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 MsonVariable = string | number;
|
||||||
|
|
||||||
|
export type Mirror3 = [boolean, boolean, boolean];
|
||||||
export type Vec3 = [number, number, number];
|
export type Vec3 = [number, number, number];
|
||||||
export type Vec2 = [number, number];
|
export type Vec2 = [number, number];
|
||||||
export type MsonVec3 = Vec3 | [MsonVariable, MsonVariable, MsonVariable];
|
export type MsonVec3 = Vec3 | [MsonVariable, MsonVariable, MsonVariable];
|
||||||
@ -92,7 +93,7 @@ export interface MsonCompound extends MsonBaseComponent {
|
|||||||
* Whether to flip this part's textures.
|
* Whether to flip this part's textures.
|
||||||
* @default false
|
* @default false
|
||||||
*/
|
*/
|
||||||
mirror?: boolean | [boolean, boolean, boolean];
|
mirror?: boolean | Mirror3;
|
||||||
/**
|
/**
|
||||||
* default type for components (if omitted): mson:box
|
* default type for components (if omitted): mson:box
|
||||||
* allowed types: <mson:box|mson:cone|mson:link|mson:quads|mson:plane|mson:slot>
|
* allowed types: <mson:box|mson:cone|mson:link|mson:quads|mson:plane|mson:slot>
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
Vector3,
|
Vector3,
|
||||||
} from 'three';
|
} from 'three';
|
||||||
import {
|
import {
|
||||||
|
Mirror3,
|
||||||
MsonBaseComponent,
|
MsonBaseComponent,
|
||||||
MsonBox,
|
MsonBox,
|
||||||
MsonComponent,
|
MsonComponent,
|
||||||
@ -28,6 +29,7 @@ import {
|
|||||||
} from '../mson';
|
} from '../mson';
|
||||||
import { isArrayOfArrays } from '../util/array-of-array';
|
import { isArrayOfArrays } from '../util/array-of-array';
|
||||||
import { UVMapper } from './uv-mapper';
|
import { UVMapper } from './uv-mapper';
|
||||||
|
import { MirrorHelper } from './mirror-helper';
|
||||||
|
|
||||||
export class ThreeBuilder {
|
export class ThreeBuilder {
|
||||||
/**
|
/**
|
||||||
@ -195,6 +197,13 @@ export class ThreeBuilder {
|
|||||||
texture?: MsonTexture,
|
texture?: MsonTexture,
|
||||||
) {
|
) {
|
||||||
const size = new Vector3().fromArray(component.size as Vec3);
|
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();
|
const dilate = new Vector3();
|
||||||
if (component.dilate) {
|
if (component.dilate) {
|
||||||
@ -207,8 +216,19 @@ export class ThreeBuilder {
|
|||||||
);
|
);
|
||||||
const halfSize = size.clone().divideScalar(2);
|
const halfSize = size.clone().divideScalar(2);
|
||||||
|
|
||||||
|
// Invert Y axis in the offset
|
||||||
offset.setY(offset.y * -1);
|
offset.setY(offset.y * -1);
|
||||||
|
|
||||||
const adjustedTranslate = halfSize.clone().add(offset);
|
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(
|
const geometry = new BoxGeometry(
|
||||||
size.x + dilate.x,
|
size.x + dilate.x,
|
||||||
@ -220,8 +240,8 @@ export class ThreeBuilder {
|
|||||||
);
|
);
|
||||||
|
|
||||||
geometry.translate(
|
geometry.translate(
|
||||||
-adjustedTranslate.x,
|
adjustedTranslate.x,
|
||||||
adjustedTranslate.y - size.y,
|
adjustedTranslate.y,
|
||||||
adjustedTranslate.z,
|
adjustedTranslate.z,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -230,12 +250,11 @@ export class ThreeBuilder {
|
|||||||
(geometry as any).type = 'BufferGeometry';
|
(geometry as any).type = 'BufferGeometry';
|
||||||
delete (geometry as any).parameters;
|
delete (geometry as any).parameters;
|
||||||
|
|
||||||
UVMapper.mapBoxUVs(
|
// Map UVs to box
|
||||||
size,
|
UVMapper.mapBoxUVs(size, geometry, texture);
|
||||||
geometry,
|
|
||||||
texture,
|
// Mirror geometry, if applicable
|
||||||
(parentComponent as MsonCompound)?.mirror,
|
MirrorHelper.mirrorGeometry(effectiveMirroring, geometry);
|
||||||
);
|
|
||||||
|
|
||||||
const mesh = new Mesh(geometry, this.material);
|
const mesh = new Mesh(geometry, this.material);
|
||||||
mesh.name = `${name}__mesh`;
|
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,
|
size: Vector3,
|
||||||
geometry: BoxGeometry,
|
geometry: BoxGeometry,
|
||||||
texture?: MsonTexture,
|
texture?: MsonTexture,
|
||||||
mirror?: boolean | [boolean, boolean, boolean],
|
|
||||||
) {
|
) {
|
||||||
const uvAttribute = geometry.getAttribute('uv') as BufferAttribute;
|
const uvAttribute = geometry.getAttribute('uv') as BufferAttribute;
|
||||||
const index = geometry.getIndex() as BufferAttribute;
|
const index = geometry.getIndex() as BufferAttribute;
|
||||||
@ -161,22 +160,6 @@ export class UVMapper {
|
|||||||
let textureOffsetU = texture?.u ?? 0;
|
let textureOffsetU = texture?.u ?? 0;
|
||||||
let textureOffsetV = texture?.v ?? 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
|
// px nx py ny pz nz
|
||||||
// clockwise count
|
// clockwise count
|
||||||
for (let i = 0; i < index!.count; i += 3) {
|
for (let i = 0; i < index!.count; i += 3) {
|
||||||
@ -195,8 +178,8 @@ export class UVMapper {
|
|||||||
textureHeight,
|
textureHeight,
|
||||||
finalU,
|
finalU,
|
||||||
finalV,
|
finalV,
|
||||||
invU.includes(faceName),
|
faceName === 'up' || faceName === 'down',
|
||||||
invV.includes(faceName),
|
faceName === 'up',
|
||||||
);
|
);
|
||||||
|
|
||||||
for (let attrib = 0; attrib < 3; attrib++) {
|
for (let attrib = 0; attrib < 3; attrib++) {
|
||||||
|
Loading…
Reference in New Issue
Block a user