mirror of
https://github.com/LucasDower/ObjToSchematic.git
synced 2025-12-11 20:15:30 +01:00
Optimised OtS_VoxelMesh_Converter
This commit is contained in:
parent
43962b1719
commit
0f543d809d
@ -7,8 +7,6 @@ import { Axes, Ray, rayIntersectTriangle } from './ray';
|
|||||||
import { Bounds } from './bounds';
|
import { Bounds } from './bounds';
|
||||||
import { RGBA, RGBAColours, RGBAUtil } from './colour';
|
import { RGBA, RGBAColours, RGBAUtil } from './colour';
|
||||||
import { OtS_Mesh, OtS_Triangle } from './ots_mesh';
|
import { OtS_Mesh, OtS_Triangle } from './ots_mesh';
|
||||||
import { ASSERT } from './util/error_util';
|
|
||||||
import { OtS_Texture } from './ots_texture';
|
|
||||||
import { UV } from './util';
|
import { UV } from './util';
|
||||||
|
|
||||||
export type OtS_VoxelMesh_ConverterConfig = {
|
export type OtS_VoxelMesh_ConverterConfig = {
|
||||||
@ -20,10 +18,6 @@ export type OtS_VoxelMesh_ConverterConfig = {
|
|||||||
|
|
||||||
export class OtS_VoxelMesh_Converter {
|
export class OtS_VoxelMesh_Converter {
|
||||||
private _config: OtS_VoxelMesh_ConverterConfig;
|
private _config: OtS_VoxelMesh_ConverterConfig;
|
||||||
private _rays: LinearAllocator<Ray>;
|
|
||||||
|
|
||||||
// Reused Bounds object in calculations to avoid GC
|
|
||||||
private _tmpBounds: Bounds;
|
|
||||||
|
|
||||||
public constructor() {
|
public constructor() {
|
||||||
this._config = {
|
this._config = {
|
||||||
@ -32,13 +26,6 @@ export class OtS_VoxelMesh_Converter {
|
|||||||
multisampling: true,
|
multisampling: true,
|
||||||
replaceMode: 'average',
|
replaceMode: 'average',
|
||||||
};
|
};
|
||||||
|
|
||||||
this._rays = new LinearAllocator<Ray>(() => {
|
|
||||||
const ray: Ray = { origin: new Vector3(0, 0, 0), axis: Axes.x };
|
|
||||||
return ray;
|
|
||||||
});
|
|
||||||
|
|
||||||
this._tmpBounds = Bounds.getEmptyBounds();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,40 +51,59 @@ export class OtS_VoxelMesh_Converter {
|
|||||||
normalisedMesh.translate(offset.x, offset.y, offset.z);
|
normalisedMesh.translate(offset.x, offset.y, offset.z);
|
||||||
|
|
||||||
for (const triangle of normalisedMesh.getTriangles()) {
|
for (const triangle of normalisedMesh.getTriangles()) {
|
||||||
this._voxeliseTri(mesh, voxelMesh, triangle);
|
this._handleTriangle(triangle, voxelMesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
return voxelMesh;
|
return voxelMesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _voxeliseTri(mesh: OtS_Mesh, voxelMesh: OtS_VoxelMesh, triangle: OtS_Triangle) {
|
private _handleTriangle(triangle: OtS_Triangle, voxelMesh: OtS_VoxelMesh) {
|
||||||
this._rays.reset();
|
const bounds = Triangle.CalcBounds(triangle.data.v0.position, triangle.data.v1.position, triangle.data.v2.position);
|
||||||
this._generateRays(triangle.data.v0.position, triangle.data.v1.position, triangle.data.v2.position);
|
bounds.min.floor();
|
||||||
|
bounds.max.ceil();
|
||||||
|
|
||||||
const voxelPosition = new Vector3(0, 0, 0);
|
const ray: Ray = { axis: Axes.x, origin: new Vector3(0, 0, 0) };
|
||||||
const size = this._rays.size();
|
|
||||||
for (let i = 0; i < size; ++i) {
|
|
||||||
const ray = this._rays.get(i)!;
|
|
||||||
|
|
||||||
const intersection = rayIntersectTriangle(ray, triangle.data.v0.position, triangle.data.v1.position, triangle.data.v2.position);
|
ray.origin.x = bounds.min.x - 1;
|
||||||
if (intersection) {
|
ray.axis = Axes.x;
|
||||||
switch (ray.axis) {
|
for (let y = bounds.min.y; y <= bounds.max.y; ++y) {
|
||||||
case Axes.x:
|
ray.origin.y = y;
|
||||||
voxelPosition.x = Math.round(intersection.x);
|
for (let z = bounds.min.z; z <= bounds.max.z; ++z) {
|
||||||
voxelPosition.y = intersection.y;
|
ray.origin.z = z;
|
||||||
voxelPosition.z = intersection.z;
|
this._handleRay(ray, triangle, voxelMesh);
|
||||||
break;
|
|
||||||
case Axes.y:
|
|
||||||
voxelPosition.x = intersection.x;
|
|
||||||
voxelPosition.y = Math.round(intersection.y);
|
|
||||||
voxelPosition.z = intersection.z;
|
|
||||||
break;
|
|
||||||
case Axes.z:
|
|
||||||
voxelPosition.x = intersection.x;
|
|
||||||
voxelPosition.y = intersection.y;
|
|
||||||
voxelPosition.z = Math.round(intersection.z);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ray.origin.y = bounds.min.y - 1;
|
||||||
|
ray.axis = Axes.y;
|
||||||
|
for (let z = bounds.min.z; z <= bounds.max.z; ++z) {
|
||||||
|
ray.origin.z = z;
|
||||||
|
for (let x = bounds.min.x; x <= bounds.max.x; ++x) {
|
||||||
|
ray.origin.x = x;
|
||||||
|
this._handleRay(ray, triangle, voxelMesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ray.origin.z = bounds.min.z - 1;
|
||||||
|
ray.axis = Axes.z;
|
||||||
|
for (let x = bounds.min.x; x <= bounds.max.x; ++x) {
|
||||||
|
ray.origin.x = x;
|
||||||
|
for (let y = bounds.min.y; y <= bounds.max.y; ++y) {
|
||||||
|
ray.origin.y = y;
|
||||||
|
this._handleRay(ray, triangle, voxelMesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleRay(ray: Ray, triangle: OtS_Triangle, voxelMesh: OtS_VoxelMesh) {
|
||||||
|
const intersection = rayIntersectTriangle(ray, triangle.data.v0.position, triangle.data.v1.position, triangle.data.v2.position);
|
||||||
|
|
||||||
|
if (intersection) {
|
||||||
|
const voxelPosition = new Vector3(
|
||||||
|
intersection.x,
|
||||||
|
intersection.y,
|
||||||
|
intersection.z,
|
||||||
|
).round();
|
||||||
|
|
||||||
let voxelColour: RGBA;
|
let voxelColour: RGBA;
|
||||||
if (this._config.multisampling) {
|
if (this._config.multisampling) {
|
||||||
@ -118,7 +124,6 @@ export class OtS_VoxelMesh_Converter {
|
|||||||
|
|
||||||
voxelMesh.addVoxel(voxelPosition.x, voxelPosition.y, voxelPosition.z, voxelColour, this._config.replaceMode);
|
voxelMesh.addVoxel(voxelPosition.x, voxelPosition.y, voxelPosition.z, voxelColour, this._config.replaceMode);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _getVoxelColour(triangle: OtS_Triangle, location: Vector3): RGBA {
|
private _getVoxelColour(triangle: OtS_Triangle, location: Vector3): RGBA {
|
||||||
@ -156,58 +161,6 @@ export class OtS_VoxelMesh_Converter {
|
|||||||
return triangle.texture.sample(texcoord.u, texcoord.v);
|
return triangle.texture.sample(texcoord.u, texcoord.v);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _generateRays(v0: Vector3, v1: Vector3, v2: Vector3) {
|
|
||||||
this._tmpBounds.min.x = Math.floor(Math.min(v0.x, v1.x, v2.x));
|
|
||||||
this._tmpBounds.min.y = Math.floor(Math.min(v0.y, v1.y, v2.y));
|
|
||||||
this._tmpBounds.min.z = Math.floor(Math.min(v0.z, v1.z, v2.z));
|
|
||||||
|
|
||||||
this._tmpBounds.max.x = Math.floor(Math.max(v0.x, v1.x, v2.x));
|
|
||||||
this._tmpBounds.max.y = Math.floor(Math.max(v0.y, v1.y, v2.y));
|
|
||||||
this._tmpBounds.max.z = Math.floor(Math.max(v0.z, v1.z, v2.z));
|
|
||||||
|
|
||||||
//const rayList: Array<Ray> = [];
|
|
||||||
this._traverseX(this._tmpBounds);
|
|
||||||
this._traverseY(this._tmpBounds);
|
|
||||||
this._traverseZ(this._tmpBounds);
|
|
||||||
//return rayList;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _traverseX(bounds: Bounds) {
|
|
||||||
for (let y = bounds.min.y; y <= bounds.max.y; ++y) {
|
|
||||||
for (let z = bounds.min.z; z <= bounds.max.z; ++z) {
|
|
||||||
const ray = this._rays.place();
|
|
||||||
ray.origin.x = bounds.min.x - 1;
|
|
||||||
ray.origin.y = y;
|
|
||||||
ray.origin.z = z;
|
|
||||||
ray.axis = Axes.x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _traverseY(bounds: Bounds) {
|
|
||||||
for (let x = bounds.min.x; x <= bounds.max.x; ++x) {
|
|
||||||
for (let z = bounds.min.z; z <= bounds.max.z; ++z) {
|
|
||||||
const ray = this._rays.place();
|
|
||||||
ray.origin.x = x;
|
|
||||||
ray.origin.y = bounds.min.y - 1;
|
|
||||||
ray.origin.z = z;
|
|
||||||
ray.axis = Axes.y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _traverseZ(bounds: Bounds) {
|
|
||||||
for (let x = bounds.min.x; x <= bounds.max.x; ++x) {
|
|
||||||
for (let y = bounds.min.y; y <= bounds.max.y; ++y) {
|
|
||||||
const ray = this._rays.place();
|
|
||||||
ray.origin.x = x;
|
|
||||||
ray.origin.y = y;
|
|
||||||
ray.origin.z = bounds.min.z - 1;
|
|
||||||
ray.axis = Axes.z;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _calcScaleOffset(mesh: OtS_Mesh) {
|
private _calcScaleOffset(mesh: OtS_Mesh) {
|
||||||
const dimensions = mesh.calcBounds().getDimensions();
|
const dimensions = mesh.calcBounds().getDimensions();
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user