mirror of
https://github.com/LucasDower/ObjToSchematic.git
synced 2024-12-27 03:18:59 +08:00
Refactor mesh
This commit is contained in:
parent
3ca4c3511e
commit
1dd7a5089d
@ -299,10 +299,11 @@ export class DebugGeometryTemplates {
|
|||||||
{ name: 'colour', numComponents: 3 },
|
{ name: 'colour', numComponents: 3 },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
for (const tri of mesh.tris) {
|
let v0: Vector3 = new Vector3(0, 0, 0);
|
||||||
const v0 = mesh.vertices[tri.positionIndices.x];
|
let v1: Vector3 = new Vector3(0, 0, 0);
|
||||||
const v1 = mesh.vertices[tri.positionIndices.y];
|
let v2: Vector3 = new Vector3(0, 0, 0);
|
||||||
const v2 = mesh.vertices[tri.positionIndices.z];
|
for (let triIndex = 0; triIndex < mesh.getTriangleCount(); ++triIndex) {
|
||||||
|
({ v0, v1, v2 } = mesh.getVertices(triIndex));
|
||||||
buffer.add(DebugGeometryTemplates.line(
|
buffer.add(DebugGeometryTemplates.line(
|
||||||
v0, v1, colour,
|
v0, v1, colour,
|
||||||
));
|
));
|
||||||
|
162
src/mesh.ts
162
src/mesh.ts
@ -28,26 +28,26 @@ export interface TexturedMaterial { path: string; type: MaterialType.textured }
|
|||||||
export type MaterialMap = {[key: string]: (SolidMaterial | TexturedMaterial)};
|
export type MaterialMap = {[key: string]: (SolidMaterial | TexturedMaterial)};
|
||||||
|
|
||||||
export class Mesh extends Warnable {
|
export class Mesh extends Warnable {
|
||||||
public vertices: Vector3[];
|
|
||||||
public normals!: Vector3[];
|
|
||||||
public uvs!: UV[];
|
|
||||||
public tris!: Tri[];
|
|
||||||
public materials!: MaterialMap;
|
|
||||||
public readonly id: string;
|
public readonly id: string;
|
||||||
|
|
||||||
|
private _vertices: Vector3[];
|
||||||
|
private _normals!: Vector3[];
|
||||||
|
private _uvs!: UV[];
|
||||||
|
private _tris!: Tri[];
|
||||||
|
private _materials!: MaterialMap;
|
||||||
private _loadedTextures: { [materialName: string]: Texture };
|
private _loadedTextures: { [materialName: string]: Texture };
|
||||||
public static desiredHeight = 8.0;
|
public static desiredHeight = 8.0;
|
||||||
|
|
||||||
constructor(vertices: Vector3[], normals: Vector3[], uvs: UV[], tris: Tri[], materials: MaterialMap) {
|
constructor(vertices: Vector3[], normals: Vector3[], uvs: UV[], tris: Tri[], materials: MaterialMap) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.vertices = vertices;
|
|
||||||
this.normals = normals;
|
|
||||||
this.uvs = uvs;
|
|
||||||
this.tris = tris;
|
|
||||||
this.materials = materials;
|
|
||||||
this._loadedTextures = {};
|
|
||||||
this.id = getRandomID();
|
this.id = getRandomID();
|
||||||
|
|
||||||
|
this._vertices = vertices;
|
||||||
|
this._normals = normals;
|
||||||
|
this._uvs = uvs;
|
||||||
|
this._tris = tris;
|
||||||
|
this._materials = materials;
|
||||||
|
this._loadedTextures = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
public processMesh() {
|
public processMesh() {
|
||||||
@ -55,58 +55,58 @@ export class Mesh extends Warnable {
|
|||||||
this._checkMaterials();
|
this._checkMaterials();
|
||||||
|
|
||||||
this._centreMesh();
|
this._centreMesh();
|
||||||
this._scaleMesh();
|
this._normaliseMesh();
|
||||||
|
|
||||||
this._loadTextures();
|
this._loadTextures();
|
||||||
}
|
}
|
||||||
|
|
||||||
public getBounds() {
|
public getBounds() {
|
||||||
const bounds = Bounds.getInfiniteBounds();
|
const bounds = Bounds.getInfiniteBounds();
|
||||||
for (const vertex of this.vertices) {
|
for (const vertex of this._vertices) {
|
||||||
bounds.extendByPoint(vertex);
|
bounds.extendByPoint(vertex);
|
||||||
}
|
}
|
||||||
return bounds;
|
return bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public translateMesh(offset: Vector3) {
|
||||||
|
this._vertices.forEach((vertex) => {
|
||||||
|
vertex.add(offset);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public scaleMesh(scaleFactor: number) {
|
||||||
|
this._vertices.forEach((vertex) => {
|
||||||
|
vertex.mulScalar(scaleFactor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private _checkMesh() {
|
private _checkMesh() {
|
||||||
// TODO: Check indices exist
|
// TODO: Check indices exist
|
||||||
|
|
||||||
if (this.vertices.length === 0) {
|
if (this._vertices.length === 0) {
|
||||||
throw new CustomError('Loaded mesh has no vertices');
|
throw new CustomError('No verticies were loaded');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.tris.length === 0) {
|
if (this._tris.length === 0) {
|
||||||
throw new CustomError('Loaded mesh has no triangles');
|
throw new CustomError('No triangles were loaded');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check UVs are inside [0, 1]
|
|
||||||
/*
|
|
||||||
for (const uv of this.uvs) {
|
|
||||||
if (uv.u < 0.0 || uv.u > 1.0) {
|
|
||||||
uv.u = Math.abs(uv.u % 1);
|
|
||||||
}
|
|
||||||
if (uv.v < 0.0 || uv.v > 1.0) {
|
|
||||||
uv.v = Math.abs(uv.v % 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _checkMaterials() {
|
private _checkMaterials() {
|
||||||
if (Object.keys(this.materials).length === 0) {
|
if (Object.keys(this._materials).length === 0) {
|
||||||
throw new CustomError('Loaded mesh has no materials');
|
throw new CustomError('Loaded mesh has no materials');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check used materials exist
|
// Check used materials exist
|
||||||
let wasRemapped = false;
|
let wasRemapped = false;
|
||||||
let debugName = (Math.random() + 1).toString(36).substring(7);
|
let debugName = (Math.random() + 1).toString(36).substring(7);
|
||||||
while (debugName in this.materials) {
|
while (debugName in this._materials) {
|
||||||
debugName = (Math.random() + 1).toString(36).substring(7);
|
debugName = (Math.random() + 1).toString(36).substring(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
const missingMaterials = new Set<string>();
|
const missingMaterials = new Set<string>();
|
||||||
for (const tri of this.tris) {
|
for (const tri of this._tris) {
|
||||||
if (!(tri.material in this.materials)) {
|
if (!(tri.material in this._materials)) {
|
||||||
missingMaterials.add(tri.material);
|
missingMaterials.add(tri.material);
|
||||||
wasRemapped = true;
|
wasRemapped = true;
|
||||||
tri.material = debugName;
|
tri.material = debugName;
|
||||||
@ -115,21 +115,21 @@ export class Mesh extends Warnable {
|
|||||||
if (wasRemapped) {
|
if (wasRemapped) {
|
||||||
LOG_WARN('Triangles use these materials but they were not found', missingMaterials);
|
LOG_WARN('Triangles use these materials but they were not found', missingMaterials);
|
||||||
this.addWarning('Some materials were not loaded correctly');
|
this.addWarning('Some materials were not loaded correctly');
|
||||||
this.materials[debugName] = {
|
this._materials[debugName] = {
|
||||||
type: MaterialType.solid,
|
type: MaterialType.solid,
|
||||||
colour: RGB.white,
|
colour: RGB.white,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check texture paths are absolute and exist
|
// Check texture paths are absolute and exist
|
||||||
for (const materialName in this.materials) {
|
for (const materialName in this._materials) {
|
||||||
const material = this.materials[materialName];
|
const material = this._materials[materialName];
|
||||||
if (material.type === MaterialType.textured) {
|
if (material.type === MaterialType.textured) {
|
||||||
ASSERT(path.isAbsolute(material.path), 'Material texture path not absolute');
|
ASSERT(path.isAbsolute(material.path), 'Material texture path not absolute');
|
||||||
if (!fs.existsSync(material.path)) {
|
if (!fs.existsSync(material.path)) {
|
||||||
this.addWarning(`Could not find ${material.path}`);
|
this.addWarning(`Could not find ${material.path}`);
|
||||||
LOG_WARN(`Could not find ${material.path} for material ${materialName}, changing to solid-white material`);
|
LOG_WARN(`Could not find ${material.path} for material ${materialName}, changing to solid-white material`);
|
||||||
this.materials[materialName] = {
|
this._materials[materialName] = {
|
||||||
type: MaterialType.solid,
|
type: MaterialType.solid,
|
||||||
colour: RGB.white,
|
colour: RGB.white,
|
||||||
};
|
};
|
||||||
@ -162,12 +162,10 @@ export class Mesh extends Warnable {
|
|||||||
LOG('Centre', centre);
|
LOG('Centre', centre);
|
||||||
|
|
||||||
// Translate each triangle
|
// Translate each triangle
|
||||||
this.vertices.forEach((vertex) => {
|
this.translateMesh(centre.negate());
|
||||||
vertex.sub(centre);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _scaleMesh() {
|
private _normaliseMesh() {
|
||||||
const bounds = this.getBounds();
|
const bounds = this.getBounds();
|
||||||
const size = Vector3.sub(bounds.max, bounds.min);
|
const size = Vector3.sub(bounds.max, bounds.min);
|
||||||
const scaleFactor = Mesh.desiredHeight / size.y;
|
const scaleFactor = Mesh.desiredHeight / size.y;
|
||||||
@ -175,16 +173,14 @@ export class Mesh extends Warnable {
|
|||||||
if (isNaN(scaleFactor) || !isFinite(scaleFactor)) {
|
if (isNaN(scaleFactor) || !isFinite(scaleFactor)) {
|
||||||
throw new CustomError('<b>Could not scale mesh correctly</b>: Mesh is likely 2D, rotate it so that it has a non-zero height');
|
throw new CustomError('<b>Could not scale mesh correctly</b>: Mesh is likely 2D, rotate it so that it has a non-zero height');
|
||||||
} else {
|
} else {
|
||||||
this.vertices.forEach((vertex) => {
|
this.scaleMesh(scaleFactor);
|
||||||
vertex.mulScalar(scaleFactor);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _loadTextures() {
|
private _loadTextures() {
|
||||||
this._loadedTextures = {};
|
this._loadedTextures = {};
|
||||||
for (const tri of this.tris) {
|
for (const tri of this._tris) {
|
||||||
const material = this.materials[tri.material];
|
const material = this._materials[tri.material];
|
||||||
if (material.type == MaterialType.textured) {
|
if (material.type == MaterialType.textured) {
|
||||||
if (!(tri.material in this._loadedTextures)) {
|
if (!(tri.material in this._loadedTextures)) {
|
||||||
this._loadedTextures[tri.material] = new Texture(material.path);
|
this._loadedTextures[tri.material] = new Texture(material.path);
|
||||||
@ -194,21 +190,21 @@ export class Mesh extends Warnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getVertices(triIndex: number) {
|
public getVertices(triIndex: number) {
|
||||||
const tri = this.tris[triIndex];
|
const tri = this._tris[triIndex];
|
||||||
return {
|
return {
|
||||||
v0: this.vertices[tri.positionIndices.x],
|
v0: this._vertices[tri.positionIndices.x],
|
||||||
v1: this.vertices[tri.positionIndices.y],
|
v1: this._vertices[tri.positionIndices.y],
|
||||||
v2: this.vertices[tri.positionIndices.z],
|
v2: this._vertices[tri.positionIndices.z],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public getUVs(triIndex: number) {
|
public getUVs(triIndex: number) {
|
||||||
const tri = this.tris[triIndex];
|
const tri = this._tris[triIndex];
|
||||||
if (tri.texcoordIndices) {
|
if (tri.texcoordIndices) {
|
||||||
return {
|
return {
|
||||||
uv0: this.uvs[tri.texcoordIndices.x] || new UV(0.0, 0.0),
|
uv0: this._uvs[tri.texcoordIndices.x] || new UV(0.0, 0.0),
|
||||||
uv1: this.uvs[tri.texcoordIndices.y] || new UV(0.0, 0.0),
|
uv1: this._uvs[tri.texcoordIndices.y] || new UV(0.0, 0.0),
|
||||||
uv2: this.uvs[tri.texcoordIndices.z] || new UV(0.0, 0.0),
|
uv2: this._uvs[tri.texcoordIndices.z] || new UV(0.0, 0.0),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
@ -221,12 +217,12 @@ export class Mesh extends Warnable {
|
|||||||
public getNormals(triIndex: number) {
|
public getNormals(triIndex: number) {
|
||||||
const vertexData = this.getVertices(triIndex);
|
const vertexData = this.getVertices(triIndex);
|
||||||
const faceNormal = new Triangle(vertexData.v0, vertexData.v1, vertexData.v2).getNormal();
|
const faceNormal = new Triangle(vertexData.v0, vertexData.v1, vertexData.v2).getNormal();
|
||||||
const tri = this.tris[triIndex];
|
const tri = this._tris[triIndex];
|
||||||
if (tri.normalIndices) {
|
if (tri.normalIndices) {
|
||||||
return {
|
return {
|
||||||
v0: this.normals[tri.normalIndices.x] || faceNormal,
|
v0: this._normals[tri.normalIndices.x] || faceNormal,
|
||||||
v1: this.normals[tri.normalIndices.y] || faceNormal,
|
v1: this._normals[tri.normalIndices.y] || faceNormal,
|
||||||
v2: this.normals[tri.normalIndices.z] || faceNormal,
|
v2: this._normals[tri.normalIndices.z] || faceNormal,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
@ -249,9 +245,21 @@ export class Mesh extends Warnable {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getMaterialByTriangle(triIndex: number) {
|
||||||
|
return this._tris[triIndex].material;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getMaterialByName(materialName: string) {
|
||||||
|
return this._materials[materialName];
|
||||||
|
}
|
||||||
|
|
||||||
|
public getMaterials() {
|
||||||
|
return this._materials;
|
||||||
|
}
|
||||||
|
|
||||||
public sampleMaterial(materialName: string, uv: UV, textureFiltering: TextureFiltering) {
|
public sampleMaterial(materialName: string, uv: UV, textureFiltering: TextureFiltering) {
|
||||||
ASSERT(materialName in this.materials, 'Sampling material that does not exist');
|
ASSERT(materialName in this._materials, 'Sampling material that does not exist');
|
||||||
const material = this.materials[materialName];
|
const material = this._materials[materialName];
|
||||||
if (material.type === MaterialType.solid) {
|
if (material.type === MaterialType.solid) {
|
||||||
return material.colour;
|
return material.colour;
|
||||||
} else {
|
} else {
|
||||||
@ -296,30 +304,30 @@ export class Mesh extends Warnable {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public copy(): Mesh {
|
public copy(): Mesh {
|
||||||
const newVertices = new Array<Vector3>(this.vertices.length);
|
const newVertices = new Array<Vector3>(this._vertices.length);
|
||||||
for (let i = 0; i < this.vertices.length; ++i) {
|
for (let i = 0; i < this._vertices.length; ++i) {
|
||||||
newVertices[i] = this.vertices[i].copy();
|
newVertices[i] = this._vertices[i].copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
const newNormals = new Array<Vector3>(this.normals.length);
|
const newNormals = new Array<Vector3>(this._normals.length);
|
||||||
for (let i = 0; i < this.normals.length; ++i) {
|
for (let i = 0; i < this._normals.length; ++i) {
|
||||||
newNormals[i] = this.normals[i].copy();
|
newNormals[i] = this._normals[i].copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
const newUVs = new Array<UV>(this.uvs.length);
|
const newUVs = new Array<UV>(this._uvs.length);
|
||||||
for (let i = 0; i < this.uvs.length; ++i) {
|
for (let i = 0; i < this._uvs.length; ++i) {
|
||||||
newUVs[i] = this.uvs[i].copy();
|
newUVs[i] = this._uvs[i].copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
const newTris = new Array<Tri>(this.tris.length);
|
const newTris = new Array<Tri>(this._tris.length);
|
||||||
for (let i = 0; i < this.tris.length; ++i) {
|
for (let i = 0; i < this._tris.length; ++i) {
|
||||||
// FIXME: Replace
|
// FIXME: Replace
|
||||||
newTris[i] = JSON.parse(JSON.stringify(this.tris[i]));
|
newTris[i] = JSON.parse(JSON.stringify(this._tris[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
const materials: { [materialName: string]: (SolidMaterial | TexturedMaterial) } = {}; // JSON.parse(JSON.stringify(this.materials));
|
const materials: { [materialName: string]: (SolidMaterial | TexturedMaterial) } = {}; // JSON.parse(JSON.stringify(this.materials));
|
||||||
for (const materialName in this.materials) {
|
for (const materialName in this._materials) {
|
||||||
const material = this.materials[materialName];
|
const material = this._materials[materialName];
|
||||||
if (material.type === MaterialType.solid) {
|
if (material.type === MaterialType.solid) {
|
||||||
materials[materialName] = {
|
materials[materialName] = {
|
||||||
type: MaterialType.solid,
|
type: MaterialType.solid,
|
||||||
@ -337,6 +345,6 @@ export class Mesh extends Warnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getTriangleCount(): number {
|
public getTriangleCount(): number {
|
||||||
return this.tris.length;
|
return this._tris.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,24 +125,23 @@ export class Renderer {
|
|||||||
LOG('Using mesh');
|
LOG('Using mesh');
|
||||||
this._materialBuffers = [];
|
this._materialBuffers = [];
|
||||||
|
|
||||||
for (const materialName in mesh.materials) {
|
for (const materialName in mesh.getMaterials()) {
|
||||||
const materialBuffer = new RenderBuffer([
|
const materialBuffer = new RenderBuffer([
|
||||||
{ name: 'position', numComponents: 3 },
|
{ name: 'position', numComponents: 3 },
|
||||||
{ name: 'texcoord', numComponents: 2 },
|
{ name: 'texcoord', numComponents: 2 },
|
||||||
{ name: 'normal', numComponents: 3 },
|
{ name: 'normal', numComponents: 3 },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
mesh.tris.forEach((tri, triIndex) => {
|
for (let triIndex = 0; triIndex < mesh.getTriangleCount(); ++triIndex) {
|
||||||
if (tri.material === materialName) {
|
const material = mesh.getMaterialByTriangle(triIndex);
|
||||||
if (tri.material === materialName) {
|
if (material === materialName) {
|
||||||
const uvTri = mesh.getUVTriangle(triIndex);
|
const uvTri = mesh.getUVTriangle(triIndex);
|
||||||
const triGeom = GeometryTemplates.getTriangleBufferData(uvTri);
|
const triGeom = GeometryTemplates.getTriangleBufferData(uvTri);
|
||||||
materialBuffer.add(triGeom);
|
materialBuffer.add(triGeom);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
const material = mesh.materials[materialName];
|
const material = mesh.getMaterialByName(materialName);
|
||||||
if (material.type === MaterialType.solid) {
|
if (material.type === MaterialType.solid) {
|
||||||
this._materialBuffers.push({
|
this._materialBuffers.push({
|
||||||
buffer: materialBuffer,
|
buffer: materialBuffer,
|
||||||
|
@ -224,6 +224,13 @@ export class Vector3 extends Hashable {
|
|||||||
return !isNaN(this.x) && !isNaN(this.y) && !isNaN(this.z);
|
return !isNaN(this.x) && !isNaN(this.y) && !isNaN(this.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public negate() {
|
||||||
|
this.x = -this.x;
|
||||||
|
this.y = -this.y;
|
||||||
|
this.z = -this.z;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
// Begin IHashable interface
|
// Begin IHashable interface
|
||||||
override hash() {
|
override hash() {
|
||||||
const p0 = 73856093;
|
const p0 = 73856093;
|
||||||
|
@ -7,6 +7,10 @@ import { RGB, UV } from '../util';
|
|||||||
import { Vector3 } from '../vector';
|
import { Vector3 } from '../vector';
|
||||||
import { IVoxeliser } from './base-voxeliser';
|
import { IVoxeliser } from './base-voxeliser';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This voxeliser works by projecting rays onto each triangle
|
||||||
|
* on each of the principle angles and testing for intersections
|
||||||
|
*/
|
||||||
export class RayVoxeliser extends IVoxeliser {
|
export class RayVoxeliser extends IVoxeliser {
|
||||||
private _mesh?: Mesh;
|
private _mesh?: Mesh;
|
||||||
private _voxelMesh?: VoxelMesh;
|
private _voxelMesh?: VoxelMesh;
|
||||||
@ -20,14 +24,15 @@ export class RayVoxeliser extends IVoxeliser {
|
|||||||
const scale = (voxelMeshParams.desiredHeight - 1) / Mesh.desiredHeight;
|
const scale = (voxelMeshParams.desiredHeight - 1) / Mesh.desiredHeight;
|
||||||
const offset = (voxelMeshParams.desiredHeight % 2 === 0) ? new Vector3(0.0, 0.5, 0.0) : new Vector3(0.0, 0.0, 0.0);
|
const offset = (voxelMeshParams.desiredHeight % 2 === 0) ? new Vector3(0.0, 0.5, 0.0) : new Vector3(0.0, 0.0, 0.0);
|
||||||
const useMesh = mesh.copy();
|
const useMesh = mesh.copy();
|
||||||
for (let i = 0; i < useMesh.vertices.length; ++i) {
|
|
||||||
useMesh.vertices[i].mulScalar(scale).add(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
useMesh.tris.forEach((tri, index) => {
|
useMesh.scaleMesh(scale);
|
||||||
const uvTriangle = useMesh.getUVTriangle(index);
|
useMesh.translateMesh(offset);
|
||||||
this._voxeliseTri(uvTriangle, tri.material);
|
|
||||||
});
|
for (let triIndex = 0; triIndex < useMesh.getTriangleCount(); ++triIndex) {
|
||||||
|
const uvTriangle = useMesh.getUVTriangle(triIndex);
|
||||||
|
const material = useMesh.getMaterialByTriangle(triIndex);
|
||||||
|
this._voxeliseTri(uvTriangle, material);
|
||||||
|
}
|
||||||
|
|
||||||
return this._voxelMesh;
|
return this._voxelMesh;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user