From c9f2f3c3e3c4141ac9c516fafd77d07e7d910cc9 Mon Sep 17 00:00:00 2001 From: Tim Corbly Date: Fri, 3 Mar 2023 15:40:16 -0700 Subject: [PATCH] Add Vector4 to math and change faceUVs to only accept Vector4. --- src/SceneBinding.ts | 22 +++++++-------- src/math.ts | 50 ++++++++++++++++++++++++++++++++++- src/node-templates/index.ts | 4 +-- src/state/State/Scene/Node.ts | 4 +-- 4 files changed, 64 insertions(+), 16 deletions(-) diff --git a/src/SceneBinding.ts b/src/SceneBinding.ts index 3b56042a..cb2078f8 100644 --- a/src/SceneBinding.ts +++ b/src/SceneBinding.ts @@ -10,7 +10,7 @@ import { BoxBuilder as BabylonBoxBuilder } from '@babylonjs/core/Meshes/Builders import { SphereBuilder as BabylonSphereBuilder } from '@babylonjs/core/Meshes/Builders/sphereBuilder'; import { CylinderBuilder as BabylonCylinderBuilder } from '@babylonjs/core/Meshes/Builders/cylinderBuilder'; import { PlaneBuilder as BabylonPlaneBuilder } from '@babylonjs/core/Meshes/Builders/planeBuilder'; -import { Vector3 as BabylonVector3, Vector4 as BabylonVector4 } from '@babylonjs/core/Maths/math.vector'; +import { Vector2, Vector3 as BabylonVector3, Vector4 as BabylonVector4 } from '@babylonjs/core/Maths/math.vector'; import { Texture as BabylonTexture } from '@babylonjs/core/Materials/Textures/texture'; import { Material as BabylonMaterial } from '@babylonjs/core/Materials/material'; import { StandardMaterial as BabylonStandardMaterial } from '@babylonjs/core/Materials/standardMaterial'; @@ -35,7 +35,7 @@ import '@babylonjs/core/Engines/Extensions/engine.views'; import '@babylonjs/core/Lights/Shadows/shadowGeneratorSceneComponent'; import Dict from "./Dict"; -import { Quaternion, Vector2 as RawVector2, Vector3 as RawVector3 } from "./math"; +import { Quaternion, Vector2 as RawVector2, Vector3 as RawVector3, Vector4 as RawVector4 } from "./math"; import Scene from "./state/State/Scene"; import Camera from "./state/State/Scene/Camera"; import Geometry from "./state/State/Scene/Geometry"; @@ -163,7 +163,7 @@ class SceneBinding { } }; - private buildGeometry_ = async (name: string, geometry: Geometry, faceUvs?: RawVector2[]): Promise => { + private buildGeometry_ = async (name: string, geometry: Geometry, faceUvs?: RawVector4[]): Promise => { let ret: FrameLike; switch (geometry.type) { case 'box': { @@ -171,12 +171,12 @@ class SceneBinding { width: Distance.toCentimetersValue(geometry.size.x), height: Distance.toCentimetersValue(geometry.size.y), depth: Distance.toCentimetersValue(geometry.size.z), - faceUV: this.buildGeometryFaceUvs_(faceUvs, 12), + faceUV: this.buildGeometryFaceUvs_(faceUvs, 6), }, this.bScene_); break; } case 'sphere': { - const bFaceUvs = this.buildGeometryFaceUvs_(faceUvs, 2)?.[0]; + const bFaceUvs = this.buildGeometryFaceUvs_(faceUvs, 1)?.[0]; ret = BabylonSphereBuilder.CreateSphere(name, { // Why?? Why is a sphere defined by its diameter? diameter: Distance.toCentimetersValue(geometry.radius) * 2, @@ -190,7 +190,7 @@ class SceneBinding { height: Distance.toCentimetersValue(geometry.height), diameterTop: Distance.toCentimetersValue(geometry.radius) * 2, diameterBottom: Distance.toCentimetersValue(geometry.radius) * 2, - faceUV: this.buildGeometryFaceUvs_(faceUvs, 6), + faceUV: this.buildGeometryFaceUvs_(faceUvs, 3), }, this.bScene_); break; } @@ -199,7 +199,7 @@ class SceneBinding { diameterTop: 0, height: Distance.toCentimetersValue(geometry.height), diameterBottom: Distance.toCentimetersValue(geometry.radius) * 2, - faceUV: this.buildGeometryFaceUvs_(faceUvs, 6), + faceUV: this.buildGeometryFaceUvs_(faceUvs, 3), }, this.bScene_); break; } @@ -207,7 +207,7 @@ class SceneBinding { ret = BabylonPlaneBuilder.CreatePlane(name, { width: Distance.toCentimetersValue(geometry.size.x), height: Distance.toCentimetersValue(geometry.size.y), - frontUVs: this.buildGeometryFaceUvs_(faceUvs, 2)?.[0], + frontUVs: this.buildGeometryFaceUvs_(faceUvs, 1)?.[0], }, this.bScene_); break; } @@ -244,14 +244,14 @@ class SceneBinding { return ret; }; - private buildGeometryFaceUvs_ = (faceUvs: RawVector2[] | undefined, expectedUvs: number): BabylonVector4[] => { + private buildGeometryFaceUvs_ = (faceUvs: RawVector4[] | undefined, expectedUvs: number): BabylonVector4[] => { if (faceUvs?.length !== expectedUvs) { return undefined; } const ret: BabylonVector4[] = []; - for (let i = 0; i + 1 < faceUvs.length; i += 2) { - ret.push(new BabylonVector4(faceUvs[i].x, faceUvs[i].y, faceUvs[i + 1].x, faceUvs[i + 1].y)); + for (let i = 0; i < expectedUvs; i++) { + ret.push(RawVector4.toBabylon(faceUvs[i])); } return ret; diff --git a/src/math.ts b/src/math.ts index 2d0c31c5..7b7fd407 100644 --- a/src/math.ts +++ b/src/math.ts @@ -1,4 +1,4 @@ -import { Vector3 as BabylonVector3, Quaternion as BabylonQuaternion } from '@babylonjs/core/Maths/math.vector'; +import { Vector3 as BabylonVector3, Vector4 as BabylonVector4, Quaternion as BabylonQuaternion } from '@babylonjs/core/Maths/math.vector'; import { TransformNode as BabylonTransformNode } from '@babylonjs/core/Meshes/transformNode'; import { AbstractMesh as BabylonAbstractMesh } from '@babylonjs/core/Meshes/abstractMesh'; @@ -169,6 +169,54 @@ export namespace Vector3 { } +export interface Vector4 { + x: number; + y: number; + z: number; + w: number; +} + +export namespace Vector4 { + export const ZERO: Vector4 = { x: 0, y: 0, z: 0, w: 0 }; + export const ONE: Vector4 = { x: 1, y: 1, z: 1, w: 1 }; + + export const X: Vector4 = { x: 1, y: 0, z: 0, w: 0 }; + export const Y: Vector4 = { x: 0, y: 1, z: 0, w: 0 }; + export const Z: Vector4 = { x: 0, y: 0, z: 1, w: 0 }; + export const W: Vector4 = { x: 0, y: 0, z: 0, w: 1 }; + export const NEG_X: Vector4 = { x: -1, y: 0, z: 0, w: 0 }; + export const NEG_Y: Vector4 = { x: 0, y: -1, z: 0, w: 0 }; + export const NEG_Z: Vector4 = { x: 0, y: 0, z: -1, w: 0 }; + export const NEG_W: Vector4 = { x: 0, y: 0, z: 0, w: -1 }; + + + export const create = (x: number, y: number, z: number, w: number): Vector4 => ({ x, y, z, w }); + export const x = (vec: Vector4) => (vec ? vec.x : 0); + export const y = (vec: Vector4) => (vec ? vec.y : 0); + export const z = (vec: Vector4) => (vec ? vec.z : 0); + export const w = (vec: Vector4) => (vec ? vec.w : 0); + export const eq = (lhs: Vector4, rhs: Vector4): boolean => lhs.x === rhs.x && lhs.y === rhs.y && lhs.z === rhs.z && lhs.w === rhs.w; + export const neq = (lhs: Vector4, rhs: Vector4): boolean => lhs.x !== rhs.x || lhs.y !== rhs.y || lhs.z !== rhs.z || lhs.w !== rhs.w; + + export const add = (lhs: Vector4, rhs: Vector4): Vector4 => ({ + x: lhs.x + rhs.x, + y: lhs.y + rhs.y, + z: lhs.z + rhs.z, + w: lhs.w + rhs.w + }); + + export const subtract = (lhs: Vector4, rhs: Vector4): Vector4 => ({ + x: lhs.x - rhs.x, + y: lhs.y - rhs.y, + z: lhs.z - rhs.z, + w: lhs.w - rhs.w + }); + + export const dot = (lhs: Vector4, rhs: Vector4): number => lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z + lhs.w * rhs.w; + + export const fromBabylon = (vec: BabylonVector4): Vector4 => ({ x: vec.x, y: vec.y, z: vec.z, w: vec.w }); + export const toBabylon = (vec: Vector4): BabylonVector4 => new BabylonVector4(vec.x, vec.y, vec.z, vec.w); +} export interface Euler { x: number; y: number; diff --git a/src/node-templates/index.ts b/src/node-templates/index.ts index 0b98211b..02e40cce 100644 --- a/src/node-templates/index.ts +++ b/src/node-templates/index.ts @@ -1,5 +1,5 @@ import Dict from "../Dict"; -import { Vector2 } from "../math"; +import { Vector4 } from "../math"; import { Color } from "../state/State/Scene/Color"; import Geometry from "../state/State/Scene/Geometry"; import Node from "../state/State/Scene/Node"; @@ -23,7 +23,7 @@ const canTemplate: Node.TemplatedNode = { uri: '/static/Can Texture.png' }, }, - faceUvs: [Vector2.ZERO, Vector2.ZERO, Vector2.create(1, 0), Vector2.create(0, 1), Vector2.ZERO, Vector2.ZERO], + faceUvs: [Vector4.ZERO, Vector4.create(0, 0, 1, 1), Vector4.ZERO], }; const reamTemplate: Node.TemplatedNode = { diff --git a/src/state/State/Scene/Node.ts b/src/state/State/Scene/Node.ts index acdbc807..e5217635 100644 --- a/src/state/State/Scene/Node.ts +++ b/src/state/State/Scene/Node.ts @@ -1,6 +1,6 @@ import AbstractRobot from '../../../AbstractRobot'; import deepNeq from '../../../deepNeq'; -import { Vector2, Vector3 } from '../../../math'; +import { Vector2, Vector3, Vector4 } from '../../../math'; import { ReferenceFrame } from '../../../unit-math'; import { DistributiveOmit } from '../../../util/types'; import { Angle, Mass } from '../../../util/Value'; @@ -107,7 +107,7 @@ namespace Node { geometryId: string; physics?: Physics; material?: Material; - faceUvs?: Vector2[]; + faceUvs?: Vector4[]; } export namespace Obj {