Fix some more mesher issues
This commit is contained in:
parent
0a06d7970d
commit
573c3e8f67
@ -17,6 +17,7 @@ export type MsonOperand =
|
||||
|
||||
export type MsonVariable = string | number;
|
||||
|
||||
export type Mirror3 = [boolean, boolean, boolean];
|
||||
export type Vec3 = [number, number, number];
|
||||
export type Vec2 = [number, number];
|
||||
export type MsonVec3 = Vec3 | [MsonVariable, MsonVariable, MsonVariable];
|
||||
@ -92,7 +93,7 @@ export interface MsonCompound extends MsonBaseComponent {
|
||||
* Whether to flip this part's textures.
|
||||
* @default false
|
||||
*/
|
||||
mirror?: boolean | [boolean, boolean, boolean];
|
||||
mirror?: boolean | Mirror3;
|
||||
/**
|
||||
* default type for components (if omitted): mson:box
|
||||
* allowed types: <mson:box|mson:cone|mson:link|mson:quads|mson:plane|mson:slot>
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
Vector3,
|
||||
} from 'three';
|
||||
import {
|
||||
Mirror3,
|
||||
MsonBaseComponent,
|
||||
MsonBox,
|
||||
MsonComponent,
|
||||
@ -28,6 +29,7 @@ import {
|
||||
} from '../mson';
|
||||
import { isArrayOfArrays } from '../util/array-of-array';
|
||||
import { UVMapper } from './uv-mapper';
|
||||
import { MirrorHelper } from './mirror-helper';
|
||||
|
||||
export class ThreeBuilder {
|
||||
/**
|
||||
@ -195,6 +197,13 @@ export class ThreeBuilder {
|
||||
texture?: MsonTexture,
|
||||
) {
|
||||
const size = new Vector3().fromArray(component.size as Vec3);
|
||||
const mirror = (parentComponent as MsonCompound)?.mirror;
|
||||
const effectiveMirroring: Mirror3 =
|
||||
mirror !== undefined
|
||||
? Array.isArray(mirror)
|
||||
? mirror
|
||||
: [mirror, mirror, mirror]
|
||||
: [false, false, false];
|
||||
|
||||
const dilate = new Vector3();
|
||||
if (component.dilate) {
|
||||
@ -207,8 +216,19 @@ export class ThreeBuilder {
|
||||
);
|
||||
const halfSize = size.clone().divideScalar(2);
|
||||
|
||||
// Invert Y axis in the offset
|
||||
offset.setY(offset.y * -1);
|
||||
|
||||
const adjustedTranslate = halfSize.clone().add(offset);
|
||||
// Y axis is reversed in the mesh format.
|
||||
adjustedTranslate.setY(adjustedTranslate.y - size.y);
|
||||
// Apply mirrored translations, if applicable
|
||||
// X axis is reversed as well.
|
||||
adjustedTranslate.set(
|
||||
adjustedTranslate.x * (effectiveMirroring[0] ? 1 : -1),
|
||||
adjustedTranslate.y * (effectiveMirroring[1] ? -1 : 1),
|
||||
adjustedTranslate.z * (effectiveMirroring[2] ? -1 : 1),
|
||||
);
|
||||
|
||||
const geometry = new BoxGeometry(
|
||||
size.x + dilate.x,
|
||||
@ -220,8 +240,8 @@ export class ThreeBuilder {
|
||||
);
|
||||
|
||||
geometry.translate(
|
||||
-adjustedTranslate.x,
|
||||
adjustedTranslate.y - size.y,
|
||||
adjustedTranslate.x,
|
||||
adjustedTranslate.y,
|
||||
adjustedTranslate.z,
|
||||
);
|
||||
|
||||
@ -230,12 +250,11 @@ export class ThreeBuilder {
|
||||
(geometry as any).type = 'BufferGeometry';
|
||||
delete (geometry as any).parameters;
|
||||
|
||||
UVMapper.mapBoxUVs(
|
||||
size,
|
||||
geometry,
|
||||
texture,
|
||||
(parentComponent as MsonCompound)?.mirror,
|
||||
);
|
||||
// Map UVs to box
|
||||
UVMapper.mapBoxUVs(size, geometry, texture);
|
||||
|
||||
// Mirror geometry, if applicable
|
||||
MirrorHelper.mirrorGeometry(effectiveMirroring, geometry);
|
||||
|
||||
const mesh = new Mesh(geometry, this.material);
|
||||
mesh.name = `${name}__mesh`;
|
||||
|
38
src/three/mirror-helper.ts
Normal file
38
src/three/mirror-helper.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import { BufferGeometry, Matrix4 } from 'three';
|
||||
import { Mirror3 } from '../mson/mson.type';
|
||||
|
||||
/**
|
||||
* Utilities to mirror a THREE BufferGeometry in set axes.
|
||||
*/
|
||||
export class MirrorHelper {
|
||||
static mirrorGeometry(axes: Mirror3, geometry: BufferGeometry) {
|
||||
// No axes are mirrored, ignore
|
||||
if (!axes.some((entry) => !!entry)) return;
|
||||
|
||||
// Invert geometry
|
||||
const inversionMatrix = new Matrix4().makeScale(
|
||||
axes[0] ? -1 : 1,
|
||||
axes[1] ? -1 : 1,
|
||||
axes[2] ? -1 : 1,
|
||||
);
|
||||
geometry.applyMatrix4(inversionMatrix);
|
||||
|
||||
// Reverse faces winding direction
|
||||
MirrorHelper.reverseIndexBuffer(geometry);
|
||||
|
||||
// Recalculate normals to face correctly
|
||||
geometry.computeVertexNormals();
|
||||
}
|
||||
|
||||
static reverseIndexBuffer(geometry: BufferGeometry) {
|
||||
if (!geometry.index) return;
|
||||
|
||||
const index = geometry.index.array;
|
||||
for (let i = 0, il = index.length / 3; i < il; i++) {
|
||||
let x = index[i * 3];
|
||||
index[i * 3] = index[i * 3 + 2];
|
||||
index[i * 3 + 2] = x;
|
||||
}
|
||||
geometry.index.needsUpdate = true;
|
||||
}
|
||||
}
|
@ -148,7 +148,6 @@ export class UVMapper {
|
||||
size: Vector3,
|
||||
geometry: BoxGeometry,
|
||||
texture?: MsonTexture,
|
||||
mirror?: boolean | [boolean, boolean, boolean],
|
||||
) {
|
||||
const uvAttribute = geometry.getAttribute('uv') as BufferAttribute;
|
||||
const index = geometry.getIndex() as BufferAttribute;
|
||||
@ -161,22 +160,6 @@ export class UVMapper {
|
||||
let textureOffsetU = texture?.u ?? 0;
|
||||
let textureOffsetV = texture?.v ?? 0;
|
||||
|
||||
const invU: string[] = ['up'];
|
||||
const invV: string[] = ['up'];
|
||||
|
||||
const mirroring =
|
||||
mirror !== undefined
|
||||
? Array.isArray(mirror)
|
||||
? mirror
|
||||
: [mirror, mirror, mirror]
|
||||
: [false, false, false];
|
||||
|
||||
// TODO: figure out what rest of the components mirror
|
||||
const [flipX, flipY, flipZ] = mirroring;
|
||||
if (flipX) {
|
||||
invU.push('south', 'north');
|
||||
}
|
||||
|
||||
// px nx py ny pz nz
|
||||
// clockwise count
|
||||
for (let i = 0; i < index!.count; i += 3) {
|
||||
@ -195,8 +178,8 @@ export class UVMapper {
|
||||
textureHeight,
|
||||
finalU,
|
||||
finalV,
|
||||
invU.includes(faceName),
|
||||
invV.includes(faceName),
|
||||
faceName === 'up' || faceName === 'down',
|
||||
faceName === 'up',
|
||||
);
|
||||
|
||||
for (let attrib = 0; attrib < 3; attrib++) {
|
||||
|
Loading…
Reference in New Issue
Block a user