Bladeren bron

Prepare iron to c port

luboslenco 1 jaar geleden
bovenliggende
commit
5b340fc755

+ 2 - 2
armorforge/Sources/TabObjects.ts

@@ -15,7 +15,7 @@ class TabObjects {
 			ui.row([1 / 4]);
 			if (ui.button("Import")) {
 				Project.importMesh(false, () => {
-					Project.paintObjects.pop().setParent(null);
+					Project.paintObjects.pop().base.setParent(null);
 				});
 			}
 			ui.endSticky();
@@ -96,7 +96,7 @@ class TabObjects {
 								}
 
 								Data.getMaterial("Scene", "TempMaterial" + TabObjects.materialId, (md: TMaterialData) => {
-									let mo: MeshObject = currentObject as MeshObject;
+									let mo: MeshObject = currentObject.ext;
 									mo.materials = [md];
 									MakeMaterial.parseMeshPreviewMaterial(md);
 								});

+ 1 - 1
armorlab/Sources/MakeMaterial.ts

@@ -105,7 +105,7 @@ class MakeMaterial {
 	}
 
 	static getDisplaceStrength = (): f32 => {
-		let sc = Context.mainObject().transform.scale.x;
+		let sc = Context.mainObject().base.transform.scale.x;
 		return Config.raw.displace_strength * 0.02 * sc;
 	}
 

+ 1 - 1
armorlab/Sources/RenderPathPaint.ts

@@ -182,7 +182,7 @@ class RenderPathPaint {
 	}
 
 	static drawCursor = (mx: f32, my: f32, radius: f32, tintR = 1.0, tintG = 1.0, tintB = 1.0) => {
-		let plane = (Scene.getChild(".Plane") as MeshObject);
+		let plane = Scene.getChild(".Plane").ext;
 		let geom = plane.data;
 
 		let g = RenderPath.frameG;

+ 1 - 1
armorpaint/Sources/MakeMaterial.ts

@@ -482,7 +482,7 @@ class MakeMaterial {
 	}
 
 	static getDisplaceStrength = (): f32 => {
-		let sc = Context.mainObject().transform.scale.x;
+		let sc = Context.mainObject().base.transform.scale.x;
 		return Config.raw.displace_strength * 0.02 * sc;
 	}
 

+ 2 - 2
armorpaint/Sources/MakeMesh.ts

@@ -171,12 +171,12 @@ class MakeMesh {
 						NodeShader.write(frag, 'if (');
 						for (let i = 0; i < visibles.length; ++i) {
 							if (i > 0) NodeShader.write(frag, ' || ');
-							NodeShader.write(frag, `${visibles[i].uid} == uid`);
+							NodeShader.write(frag, `${visibles[i].base.uid} == uid`);
 						}
 						NodeShader.write(frag, ') {');
 					}
 					else { // Object mask
-						let uid = Project.paintObjects[SlotLayer.getObjectMask(l) - 1].uid;
+						let uid = Project.paintObjects[SlotLayer.getObjectMask(l) - 1].base.uid;
 						NodeShader.write(frag, `if (${uid} == uid) {`);
 					}
 				}

+ 35 - 35
armorpaint/Sources/RenderPathPaint.ts

@@ -121,15 +121,15 @@ class RenderPathPaint {
 					RenderPath.bindTarget("gbuffer0", "gbuffer0");
 				}
 
-				let mo: MeshObject = Scene.getChild(".ParticleEmitter") as MeshObject;
-				mo.visible = true;
+				let mo: MeshObject = Scene.getChild(".ParticleEmitter").ext;
+				mo.base.visible = true;
 				mo.render(RenderPath.currentG, "mesh", RenderPath.bindParams);
-				mo.visible = false;
+				mo.base.visible = false;
 
-				mo = Scene.getChild(".Particle")as MeshObject;
-				mo.visible = true;
+				mo = Scene.getChild(".Particle").ext;
+				mo.base.visible = true;
 				mo.render(RenderPath.currentG, "mesh", RenderPath.bindParams);
-				mo.visible = false;
+				mo.base.visible = false;
 				RenderPath.end();
 			}
 
@@ -354,7 +354,7 @@ class RenderPathPaint {
 			if (ConstData.screenAlignedVB == null) ConstData.createScreenAlignedData();
 			RenderPath.currentG.setPipeline(cc_context._pipeState);
 			Uniforms.setContextConstants(RenderPath.currentG, cc_context, RenderPath.bindParams);
-			Uniforms.setObjectConstants(RenderPath.currentG, cc_context, Project.paintObjects[0]);
+			Uniforms.setObjectConstants(RenderPath.currentG, cc_context, Project.paintObjects[0].base);
 			Uniforms.setMaterialConstants(RenderPath.currentG, cc_context, materialContexts[0]);
 			RenderPath.currentG.setVertexBuffer(ConstData.screenAlignedVB);
 			RenderPath.currentG.setIndexBuffer(ConstData.screenAlignedIB);
@@ -495,7 +495,7 @@ class RenderPathPaint {
 	}
 
 	static drawCursor = (mx: f32, my: f32, radius: f32, tintR = 1.0, tintG = 1.0, tintB = 1.0) => {
-		let plane = (Scene.getChild(".Plane") as MeshObject);
+		let plane: MeshObject = Scene.getChild(".Plane").ext;
 		let geom = plane.data;
 
 		let g = RenderPath.frameG;
@@ -534,7 +534,7 @@ class RenderPathPaint {
 	static commandsSymmetry = () => {
 		if (Context.raw.symX || Context.raw.symY || Context.raw.symZ) {
 			Context.raw.ddirty = 2;
-			let t = Context.raw.paintObject.transform;
+			let t = Context.raw.paintObject.base.transform;
 			let sx = t.scale.x;
 			let sy = t.scale.y;
 			let sz = t.scale.z;
@@ -693,11 +693,11 @@ class RenderPathPaint {
 						MakeMaterial.parsePaintMaterial();
 						let _paintObject = Context.raw.paintObject;
 						let highPoly = Project.paintObjects[Context.raw.bakeHighPoly];
-						let _visible = highPoly.visible;
-						highPoly.visible = true;
+						let _visible = highPoly.base.visible;
+						highPoly.base.visible = true;
 						Context.selectPaintObject(highPoly);
 						RenderPathPaint.commandsPaint();
-						highPoly.visible = _visible;
+						highPoly.base.visible = _visible;
 						if (RenderPathPaint.pushUndoLast) History.paint();
 						Context.selectPaintObject(_paintObject);
 
@@ -726,9 +726,9 @@ class RenderPathPaint {
 					let _layerFilter = Context.raw.layerFilter;
 					let _paintObject = Context.raw.paintObject;
 					let isMerged = Context.raw.mergedObject != null;
-					let _visible = isMerged && Context.raw.mergedObject.visible;
+					let _visible = isMerged && Context.raw.mergedObject.base.visible;
 					Context.raw.layerFilter = 1;
-					if (isMerged) Context.raw.mergedObject.visible = false;
+					if (isMerged) Context.raw.mergedObject.base.visible = false;
 
 					for (let p of Project.paintObjects) {
 						Context.selectPaintObject(p);
@@ -737,7 +737,7 @@ class RenderPathPaint {
 
 					Context.raw.layerFilter = _layerFilter;
 					Context.selectPaintObject(_paintObject);
-					if (isMerged) Context.raw.mergedObject.visible = _visible;
+					if (isMerged) Context.raw.mergedObject.base.visible = _visible;
 				}
 				///if (krom_direct3d12 || krom_vulkan || krom_metal)
 				else if (isRaytracedBake) {
@@ -785,21 +785,21 @@ class RenderPathPaint {
 		RenderPathPaint.painto = Context.raw.paintObject;
 		RenderPathPaint.visibles = [];
 		for (let p of Project.paintObjects) {
-			RenderPathPaint.visibles.push(p.visible);
-			p.visible = false;
+			RenderPathPaint.visibles.push(p.base.visible);
+			p.base.visible = false;
 		}
 		if (Context.raw.mergedObject != null) {
-			RenderPathPaint.mergedObjectVisible = Context.raw.mergedObject.visible;
-			Context.raw.mergedObject.visible = false;
+			RenderPathPaint.mergedObjectVisible = Context.raw.mergedObject.base.visible;
+			Context.raw.mergedObject.base.visible = false;
 		}
 
 		let cam = Scene.camera;
-		Context.raw.savedCamera.setFrom(cam.transform.local);
+		Context.raw.savedCamera.setFrom(cam.base.transform.local);
 		RenderPathPaint.savedFov = cam.data.fov;
 		Viewport.updateCameraType(CameraType.CameraPerspective);
 		let m = Mat4.identity();
 		m.translate(0, 0, 0.5);
-		cam.transform.setMatrix(m);
+		cam.base.transform.setMatrix(m);
 		cam.data.fov = Base.defaultFov;
 		cam.buildProjection();
 		cam.buildMatrix();
@@ -835,37 +835,37 @@ class RenderPathPaint {
 				scale_tex: 1.0
 			};
 			MeshData.create(raw, (md: TMeshData) => {
-				let materials = (Scene.getChild(".Plane") as MeshObject).materials;
+				let materials: TMaterialData[] = Scene.getChild(".Plane").ext.materials;
 				let o = Scene.addMeshObject(md, materials);
-				o.name = ".PlaneTiled";
+				o.base.name = ".PlaneTiled";
 			});
 		}
 
-		RenderPathPaint.planeo = Scene.getChild(tiled ? ".PlaneTiled" : ".Plane") as MeshObject;
-		RenderPathPaint.planeo.visible = true;
+		RenderPathPaint.planeo = Scene.getChild(tiled ? ".PlaneTiled" : ".Plane").ext;
+		RenderPathPaint.planeo.base.visible = true;
 		Context.raw.paintObject = RenderPathPaint.planeo;
 
 		let v = new Vec4();
 		let sx = v.set(m._00, m._01, m._02).length();
-		RenderPathPaint.planeo.transform.rot.fromEuler(-Math.PI / 2, 0, 0);
-		RenderPathPaint.planeo.transform.scale.set(sx, 1.0, sx);
-		RenderPathPaint.planeo.transform.scale.z *= Config.getTextureResY() / Config.getTextureResX();
-		RenderPathPaint.planeo.transform.loc.set(m._30, -m._31, 0.0);
-		RenderPathPaint.planeo.transform.buildMatrix();
+		RenderPathPaint.planeo.base.transform.rot.fromEuler(-Math.PI / 2, 0, 0);
+		RenderPathPaint.planeo.base.transform.scale.set(sx, 1.0, sx);
+		RenderPathPaint.planeo.base.transform.scale.z *= Config.getTextureResY() / Config.getTextureResX();
+		RenderPathPaint.planeo.base.transform.loc.set(m._30, -m._31, 0.0);
+		RenderPathPaint.planeo.base.transform.buildMatrix();
 	}
 
 	static restorePlaneMesh = () => {
 		Context.raw.paint2dView = false;
-		RenderPathPaint.planeo.visible = false;
-		RenderPathPaint.planeo.transform.loc.set(0.0, 0.0, 0.0);
+		RenderPathPaint.planeo.base.visible = false;
+		RenderPathPaint.planeo.base.transform.loc.set(0.0, 0.0, 0.0);
 		for (let i = 0; i < Project.paintObjects.length; ++i) {
-			Project.paintObjects[i].visible = RenderPathPaint.visibles[i];
+			Project.paintObjects[i].base.visible = RenderPathPaint.visibles[i];
 		}
 		if (Context.raw.mergedObject != null) {
-			Context.raw.mergedObject.visible = RenderPathPaint.mergedObjectVisible;
+			Context.raw.mergedObject.base.visible = RenderPathPaint.mergedObjectVisible;
 		}
 		Context.raw.paintObject = RenderPathPaint.painto;
-		Scene.camera.transform.setMatrix(Context.raw.savedCamera);
+		Scene.camera.base.transform.setMatrix(Context.raw.savedCamera);
 		Scene.camera.data.fov = RenderPathPaint.savedFov;
 		Viewport.updateCameraType(Context.raw.cameraType);
 		Scene.camera.buildProjection();

+ 4 - 4
armorpaint/Sources/TabLayers.ts

@@ -157,7 +157,7 @@ class TabLayers {
 	static comboFilter = () => {
 		let ui = UIBase.ui;
 		let ar = [tr("All")];
-		for (let p of Project.paintObjects) ar.push(p.name);
+		for (let p of Project.paintObjects) ar.push(p.base.name);
 		let atlases = Project.getUsedAtlases();
 		if (atlases != null) for (let a of atlases) ar.push(a);
 		let filterHandle = Zui.handle("tablayers_0");
@@ -165,14 +165,14 @@ class TabLayers {
 		Context.raw.layerFilter = ui.combo(filterHandle, ar, tr("Filter"), false, Align.Left);
 		if (filterHandle.changed) {
 			for (let p of Project.paintObjects) {
-				p.visible = Context.raw.layerFilter == 0 || p.name == ar[Context.raw.layerFilter] || Project.isAtlasObject(p);
+				p.base.visible = Context.raw.layerFilter == 0 || p.base.name == ar[Context.raw.layerFilter] || Project.isAtlasObject(p);
 			}
 			if (Context.raw.layerFilter == 0 && Context.raw.mergedObjectIsAtlas) { // All
 				UtilMesh.mergeMesh();
 			}
 			else if (Context.raw.layerFilter > Project.paintObjects.length) { // Atlas
 				let visibles: MeshObject[] = [];
-				for (let p of Project.paintObjects) if (p.visible) visibles.push(p);
+				for (let p of Project.paintObjects) if (p.base.visible) visibles.push(p);
 				UtilMesh.mergeMesh(visibles);
 			}
 			Base.setObjectMask();
@@ -448,7 +448,7 @@ class TabLayers {
 
 	static comboObject = (ui: Zui, l: SlotLayerRaw, label = false): Handle => {
 		let ar = [tr("Shared")];
-		for (let p of Project.paintObjects) ar.push(p.name);
+		for (let p of Project.paintObjects) ar.push(p.base.name);
 		let atlases = Project.getUsedAtlases();
 		if (atlases != null) for (let a of atlases) ar.push(a);
 		let objectHandle = Zui.handle("tablayers_2").nest(l.id);

+ 1 - 1
armorsculpt/Sources/ExportObj.ts

@@ -60,7 +60,7 @@ class ExportObj {
 				}
 			}
 
-			ExportObj.writeString(o, "o " + p.name + "\n");
+			ExportObj.writeString(o, "o " + p.base.name + "\n");
 			for (let i = 0; i < pi; ++i) {
 				ExportObj.writeString(o, "v ");
 				let vx = posa2[i * 3] * sc + "";

+ 10 - 10
armorsculpt/Sources/ImportMesh.ts

@@ -44,21 +44,21 @@ class ImportMesh {
 		if (Project.paintObjects.length > 1) {
 			// Sort by name
 			Project.paintObjects.sort((a, b): i32 => {
-				if (a.name < b.name) return -1;
-				else if (a.name > b.name) return 1;
+				if (a.base.name < b.base.name) return -1;
+				else if (a.base.name > b.base.name) return 1;
 				return 0;
 			});
 
 			// No mask by default
-			for (let p of Project.paintObjects) p.visible = true;
+			for (let p of Project.paintObjects) p.base.visible = true;
 			if (Context.raw.mergedObject == null) UtilMesh.mergeMesh();
 			Context.raw.paintObject.skip_context = "paint";
-			Context.raw.mergedObject.visible = true;
+			Context.raw.mergedObject.base.visible = true;
 		}
 
 		Viewport.scaleToBounds();
 
-		if (Context.raw.paintObject.name == "") Context.raw.paintObject.name = "Object";
+		if (Context.raw.paintObject.base.name == "") Context.raw.paintObject.base.name = "Object";
 		MakeMaterial.parsePaintMaterial();
 		MakeMaterial.parseMeshMaterial();
 
@@ -105,7 +105,7 @@ class ImportMesh {
 				}
 
 				Context.raw.paintObject.setData(md);
-				Context.raw.paintObject.name = mesh.name;
+				Context.raw.paintObject.base.name = mesh.name;
 				Project.paintObjects = [Context.raw.paintObject];
 
 				md._handle = raw.name;
@@ -149,14 +149,14 @@ class ImportMesh {
 
 			MeshData.create(raw, (md: TMeshData) => {
 
-				let object = Scene.addMeshObject(md, Context.raw.paintObject.materials, Context.raw.paintObject);
-				object.name = mesh.name;
+				let object = Scene.addMeshObject(md, Context.raw.paintObject.materials, Context.raw.paintObject.base);
+				object.base.name = mesh.base.name;
 				object.skip_context = "paint";
 
 				// Ensure unique names
 				for (let p of Project.paintObjects) {
-					if (p.name == object.name) {
-						p.name += ".001";
+					if (p.base.name == object.base.name) {
+						p.base.name += ".001";
 						p.data._handle += ".001";
 						Data.cachedMeshes.set(p.data._handle, p.data);
 					}

+ 1 - 1
armorsculpt/Sources/MakeMaterial.ts

@@ -313,7 +313,7 @@ class MakeMaterial {
 	}
 
 	static getDisplaceStrength = (): f32 => {
-		let sc = Context.mainObject().transform.scale.x;
+		let sc = Context.mainObject().base.transform.scale.x;
 		return Config.raw.displace_strength * 0.02 * sc;
 	}
 

+ 2 - 2
armorsculpt/Sources/MakeMesh.ts

@@ -141,12 +141,12 @@ class MakeMesh {
 					NodeShader.write(frag, 'if (');
 					for (let i = 0; i < visibles.length; ++i) {
 						if (i > 0) NodeShader.write(frag, ' || ');
-						NodeShader.write(frag, `${visibles[i].uid} == uid`);
+						NodeShader.write(frag, `${visibles[i].base.uid} == uid`);
 					}
 					NodeShader.write(frag, ') {');
 				}
 				else { // Object mask
-					let uid = Project.paintObjects[SlotLayer.getObjectMask(l) - 1].uid;
+					let uid = Project.paintObjects[SlotLayer.getObjectMask(l) - 1].base.uid;
 					NodeShader.write(frag, `if (${uid} == uid) {`);
 				}
 			}

+ 4 - 4
base/Sources/Base.ts

@@ -1995,17 +1995,17 @@ class Base {
 		///end
 
 		let ar = [tr("None")];
-		for (let p of Project.paintObjects) ar.push(p.name);
+		for (let p of Project.paintObjects) ar.push(p.base.name);
 
 		let mask = Context.objectMaskUsed() ? SlotLayer.getObjectMask(Context.raw.layer) : 0;
 		if (Context.layerFilterUsed()) mask = Context.raw.layerFilter;
 		if (mask > 0) {
 			if (Context.raw.mergedObject != null) {
-				Context.raw.mergedObject.visible = false;
+				Context.raw.mergedObject.base.visible = false;
 			}
 			let o = Project.paintObjects[0];
 			for (let p of Project.paintObjects) {
-				if (p.name == ar[mask]) {
+				if (p.base.name == ar[mask]) {
 					o = p;
 					break;
 				}
@@ -2020,7 +2020,7 @@ class Base {
 			}
 			Context.selectPaintObject(Context.mainObject());
 			Context.raw.paintObject.skip_context = "paint";
-			Context.raw.mergedObject.visible = true;
+			Context.raw.mergedObject.base.visible = true;
 		}
 		UtilUV.dilatemapCached = false;
 	}

+ 2 - 2
base/Sources/BoxExport.ts

@@ -302,7 +302,7 @@ class BoxExport {
 			}
 			for (let i = 0; i < Project.paintObjects.length; ++i) {
 				ui.row([1 / 2, 1 / 2]);
-				ui.text(Project.paintObjects[i].name);
+				ui.text(Project.paintObjects[i].base.name);
 				let hatlas = Zui.handle("boxexport_7").nest(i);
 				hatlas.position = Project.atlasObjects[i];
 				Project.atlasObjects[i] = ui.combo(hatlas, Project.atlasNames, tr("Atlas"));
@@ -328,7 +328,7 @@ class BoxExport {
 			Context.raw.exportMeshFormat = ui.combo(Zui.handle("boxexport_9", { position: Context.raw.exportMeshFormat }), ["obj", "arm"], tr("Format"), true);
 
 			let ar = [tr("All")];
-			for (let p of Project.paintObjects) ar.push(p.name);
+			for (let p of Project.paintObjects) ar.push(p.base.name);
 			ui.combo(BoxExport.exportMeshHandle, ar, tr("Meshes"), true);
 
 			let applyDisplacement = ui.check(Zui.handle("boxexport_10"), tr("Apply Displacement"));

+ 20 - 20
base/Sources/Camera.ts

@@ -81,17 +81,17 @@ class Camera {
 		if (controls == CameraControls.ControlsOrbit && (Operator.shortcut(Config.keymap.action_rotate, ShortcutType.ShortcutDown) || (Mouse.down("right") && !modif && defaultKeymap))) {
 			Camera.redraws = 2;
 			let dist = Camera.distance();
-			camera.transform.move(camera.lookWorld(), dist);
-			camera.transform.rotate(Vec4.zAxis(), -Mouse.movementX / 100 * Config.raw.camera_rotation_speed);
-			camera.transform.rotate(camera.rightWorld(), -Mouse.movementY / 100 * Config.raw.camera_rotation_speed);
+			camera.base.transform.move(camera.lookWorld(), dist);
+			camera.base.transform.rotate(Vec4.zAxis(), -Mouse.movementX / 100 * Config.raw.camera_rotation_speed);
+			camera.base.transform.rotate(camera.rightWorld(), -Mouse.movementY / 100 * Config.raw.camera_rotation_speed);
 			if (camera.upWorld().z < 0) {
-				camera.transform.rotate(camera.rightWorld(), Mouse.movementY / 100 * Config.raw.camera_rotation_speed);
+				camera.base.transform.rotate(camera.rightWorld(), Mouse.movementY / 100 * Config.raw.camera_rotation_speed);
 			}
-			camera.transform.move(camera.lookWorld(), -dist);
+			camera.base.transform.move(camera.lookWorld(), -dist);
 		}
 		else if (controls == CameraControls.ControlsRotate && (Operator.shortcut(Config.keymap.action_rotate, ShortcutType.ShortcutDown) || (Mouse.down("right") && !modif && defaultKeymap))) {
 			Camera.redraws = 2;
-			let t = Context.mainObject().transform;
+			let t = Context.mainObject().base.transform;
 			let up = t.up().normalize();
 			t.rotate(up, Mouse.movementX / 100 * Config.raw.camera_rotation_speed);
 			let right = camera.rightWorld().normalize();
@@ -109,14 +109,14 @@ class Camera {
 				Camera.redraws = 2;
 				let f = Camera.getZoomDelta() / 150;
 				f *= Camera.getCameraZoomSpeed();
-				camera.transform.move(camera.look(), f);
+				camera.base.transform.move(camera.look(), f);
 			}
 
 			if (Mouse.wheelDelta != 0 && !modifKey) {
 				Camera.redraws = 2;
 				let f = Mouse.wheelDelta * (-0.1);
 				f *= Camera.getCameraZoomSpeed();
-				camera.transform.move(camera.look(), f);
+				camera.base.transform.move(camera.look(), f);
 			}
 		}
 		else if (controls == CameraControls.ControlsFly && Mouse.down("right")) {
@@ -150,15 +150,15 @@ class Camera {
 
 			let d = Time.delta * fast * Camera.ease * 2.0 * ((moveForward || moveBackward) ? Config.raw.camera_zoom_speed : Config.raw.camera_pan_speed);
 			if (d > 0.0) {
-				camera.transform.move(Camera.dir, d);
+				camera.base.transform.move(Camera.dir, d);
 				if (Context.raw.cameraType == CameraType.CameraOrthographic) {
 					Viewport.updateCameraType(Context.raw.cameraType);
 				}
 			}
 
 			Camera.redraws = 2;
-			camera.transform.rotate(Vec4.zAxis(), -Mouse.movementX / 200 * Config.raw.camera_rotation_speed);
-			camera.transform.rotate(camera.right(), -Mouse.movementY / 200 * Config.raw.camera_rotation_speed);
+			camera.base.transform.rotate(Vec4.zAxis(), -Mouse.movementX / 200 * Config.raw.camera_rotation_speed);
+			camera.base.transform.rotate(camera.right(), -Mouse.movementY / 200 * Config.raw.camera_rotation_speed);
 		}
 
 		if (Operator.shortcut(Config.keymap.rotate_light, ShortcutType.ShortcutDown)) {
@@ -166,8 +166,8 @@ class Camera {
 			let light = Scene.lights[0];
 			Context.raw.lightAngle = (Context.raw.lightAngle + ((Mouse.movementX / 100) % (2 * Math.PI) + 2 * Math.PI)) % (2 * Math.PI);
 			let m = Mat4.rotationZ(Mouse.movementX / 100);
-			light.transform.local.multmat(m);
-			light.transform.decompose();
+			light.base.transform.local.multmat(m);
+			light.base.transform.decompose();
 		}
 
 		if (Operator.shortcut(Config.keymap.rotate_envmap, ShortcutType.ShortcutDown)) {
@@ -187,7 +187,7 @@ class Camera {
 
 	static distance = (): f32 => {
 		let camera = Scene.camera;
-		return Vec4.distance(Camera.origins[Camera.index()], camera.transform.loc);
+		return Vec4.distance(Camera.origins[Camera.index()], camera.base.transform.loc);
 	}
 
 	static index = (): i32 => {
@@ -205,11 +205,11 @@ class Camera {
 		let camera = Scene.camera;
 		if (viewIndex == -1) {
 			Camera.origins = [new Vec4(0, 0, 0), new Vec4(0, 0, 0)];
-			Camera.views = [camera.transform.local.clone(), camera.transform.local.clone()];
+			Camera.views = [camera.base.transform.local.clone(), camera.base.transform.local.clone()];
 		}
 		else {
 			Camera.origins[viewIndex] = new Vec4(0, 0, 0);
-			Camera.views[viewIndex] = camera.transform.local.clone();
+			Camera.views[viewIndex] = camera.base.transform.local.clone();
 		}
 	}
 
@@ -217,10 +217,10 @@ class Camera {
 		let camera = Scene.camera;
 		if (Operator.shortcut(Config.keymap.action_pan, ShortcutType.ShortcutDown) || (Mouse.down("middle") && !modif && defaultKeymap)) {
 			Camera.redraws = 2;
-			let look = camera.transform.look().normalize().mult(Mouse.movementY / 150 * Config.raw.camera_pan_speed);
-			let right = camera.transform.right().normalize().mult(-Mouse.movementX / 150 * Config.raw.camera_pan_speed);
-			camera.transform.loc.add(look);
-			camera.transform.loc.add(right);
+			let look = camera.base.transform.look().normalize().mult(Mouse.movementY / 150 * Config.raw.camera_pan_speed);
+			let right = camera.base.transform.right().normalize().mult(-Mouse.movementX / 150 * Config.raw.camera_pan_speed);
+			camera.base.transform.loc.add(look);
+			camera.base.transform.loc.add(right);
 			Camera.origins[Camera.index()].add(look);
 			Camera.origins[Camera.index()].add(right);
 			camera.buildMatrix();

+ 1 - 1
base/Sources/Context.ts

@@ -165,7 +165,7 @@ class Context {
 
 	static mainObject = (): MeshObject => {
 		///if (is_paint || is_sculpt)
-		for (let po of Project.paintObjects) if (po.children.length > 0) return po;
+		for (let po of Project.paintObjects) if (po.base.children.length > 0) return po;
 		return Project.paintObjects[0];
 		///end
 

+ 1 - 1
base/Sources/ExportArm.ts

@@ -107,7 +107,7 @@ class ExportArm {
 			swatches: Project.raw.swatches,
 			envmap: Project.raw.envmap != null ? (sameDrive ? Path.toRelative(Project.filepath, Project.raw.envmap) : Project.raw.envmap) : null,
 			envmap_strength: Scene.world.strength,
-			camera_world: Scene.camera.transform.local.toFloat32Array(),
+			camera_world: Scene.camera.base.transform.local.toFloat32Array(),
 			camera_origin: ExportArm.vec3f32(Camera.origins[0]),
 			camera_fov: Scene.camera.data.fov,
 

+ 1 - 1
base/Sources/ExportObj.ts

@@ -102,7 +102,7 @@ class ExportObj {
 				// }
 			}
 
-			ExportObj.writeString(o, "o " + p.name + "\n");
+			ExportObj.writeString(o, "o " + p.base.name + "\n");
 			for (let i = 0; i < pi; ++i) {
 				ExportObj.writeString(o, "v ");
 				ExportObj.writeString(o, posa2[i * 3] * sc + "");

+ 8 - 8
base/Sources/ExportTexture.ts

@@ -15,7 +15,7 @@ class ExportTexture {
 			let udimTiles: string[] = [];
 			for (let l of Project.layers) {
 				if (SlotLayer.getObjectMask(l) > 0) {
-					let name = Project.paintObjects[SlotLayer.getObjectMask(l) - 1].name;
+					let name = Project.paintObjects[SlotLayer.getObjectMask(l) - 1].base.name;
 					if (name.substr(name.length - 5, 2) == ".1") { // tile.1001
 						udimTiles.push(name.substr(name.length - 5));
 					}
@@ -30,7 +30,7 @@ class ExportTexture {
 			let objectNames: string[] = [];
 			for (let l of Project.layers) {
 				if (SlotLayer.getObjectMask(l) > 0) {
-					let name = Project.paintObjects[SlotLayer.getObjectMask(l) - 1].name;
+					let name = Project.paintObjects[SlotLayer.getObjectMask(l) - 1].base.name;
 					if (objectNames.indexOf(name) == -1) {
 						objectNames.push(name);
 					}
@@ -94,8 +94,8 @@ class ExportTexture {
 		Context.raw.tool = WorkspaceTool.ToolFill;
 		MakeMaterial.parsePaintMaterial();
 		let _paintObject = Context.raw.paintObject;
-		let planeo: MeshObject = Scene.getChild(".Plane") as MeshObject;
-		planeo.visible = true;
+		let planeo: MeshObject = Scene.getChild(".Plane").ext;
+		planeo.base.visible = true;
 		Context.raw.paintObject = planeo;
 		Context.raw.pdirty = 1;
 		RenderPathPaint.useLiveLayer(true);
@@ -104,7 +104,7 @@ class ExportTexture {
 		Context.raw.tool = _tool;
 		MakeMaterial.parsePaintMaterial();
 		Context.raw.pdirty = 0;
-		planeo.visible = false;
+		planeo.base.visible = false;
 		Context.raw.paintObject = _paintObject;
 
 		ExportTexture.runLayers(path, [RenderPathPaint.liveLayer], "", true);
@@ -146,7 +146,7 @@ class ExportTexture {
 		// Append object mask name
 		let exportSelected = Context.raw.layersExport == ExportMode.ExportSelected;
 		if (exportSelected && SlotLayer.getObjectMask(layers[0]) > 0) {
-			f += "_" + Project.paintObjects[SlotLayer.getObjectMask(layers[0]) - 1].name;
+			f += "_" + Project.paintObjects[SlotLayer.getObjectMask(layers[0]) - 1].base.name;
 		}
 		if (!isUdim && !exportSelected && objectName != "") {
 			f += "_" + objectName;
@@ -169,9 +169,9 @@ class ExportTexture {
 			if (!SlotLayer.isLayer(l1)) continue;
 
 			if (objectName != "" && SlotLayer.getObjectMask(l1) > 0) {
-				if (isUdim && !Project.paintObjects[SlotLayer.getObjectMask(l1) - 1].name.endsWith(objectName)) continue;
+				if (isUdim && !Project.paintObjects[SlotLayer.getObjectMask(l1) - 1].base.name.endsWith(objectName)) continue;
 				let perObject = Context.raw.layersExport == ExportMode.ExportPerObject;
-				if (perObject && Project.paintObjects[SlotLayer.getObjectMask(l1) - 1].name != objectName) continue;
+				if (perObject && Project.paintObjects[SlotLayer.getObjectMask(l1) - 1].base.name != objectName) continue;
 			}
 
 			let mask = empty;

+ 2 - 2
base/Sources/Gizmo.ts

@@ -17,7 +17,7 @@ class Gizmo {
 		gizmo.visible = (isObject || isDecal) && !hide;
 		if (!gizmo.visible) return;
 
-		let paintObject: BaseObject = Context.raw.paintObject;
+		let paintObject: BaseObject = Context.raw.paintObject.base;
 		///if is_forge
 		if (Context.raw.selectedObject != null) {
 			paintObject = Context.raw.selectedObject;
@@ -32,7 +32,7 @@ class Gizmo {
 		}
 		let cam = Scene.camera;
 		let fov = cam.data.fov;
-		let dist = Vec4.distance(cam.transform.loc, gizmo.transform.loc) / 8 * fov;
+		let dist = Vec4.distance(cam.base.transform.loc, gizmo.transform.loc) / 8 * fov;
 		gizmo.transform.scale.set(dist, dist, dist);
 		Context.raw.gizmoTranslateX.transform.scale.set(dist, dist, dist);
 		Context.raw.gizmoTranslateY.transform.scale.set(dist, dist, dist);

+ 13 - 13
base/Sources/ImportArm.ts

@@ -78,8 +78,8 @@ class ImportArm {
 				Scene.world.strength = Project.raw.envmap_strength;
 			}
 			if (Project.raw.camera_world != null) {
-				Scene.camera.transform.local = Mat4.fromFloat32Array(Project.raw.camera_world);
-				Scene.camera.transform.decompose();
+				Scene.camera.base.transform.local = Mat4.fromFloat32Array(Project.raw.camera_world);
+				Scene.camera.base.transform.decompose();
 				Scene.camera.data.fov = Project.raw.camera_fov;
 				Scene.camera.buildProjection();
 				let origin = Project.raw.camera_origin;
@@ -134,9 +134,9 @@ class ImportArm {
 			///end
 
 				Context.raw.paintObject.setData(md);
-				Context.raw.paintObject.transform.scale.set(1, 1, 1);
-				Context.raw.paintObject.transform.buildMatrix();
-				Context.raw.paintObject.name = md.name;
+				Context.raw.paintObject.base.transform.scale.set(1, 1, 1);
+				Context.raw.paintObject.base.transform.buildMatrix();
+				Context.raw.paintObject.base.name = md.name;
 				Project.paintObjects = [Context.raw.paintObject];
 			});
 
@@ -144,8 +144,8 @@ class ImportArm {
 			for (let i = 1; i < project.mesh_datas.length; ++i) {
 				let raw = project.mesh_datas[i];
 				MeshData.create(raw, (md: TMeshData) => {
-					let object = Scene.addMeshObject(md, Context.raw.paintObject.materials, Context.raw.paintObject);
-					object.name = md.name;
+					let object = Scene.addMeshObject(md, Context.raw.paintObject.materials, Context.raw.paintObject.base);
+					object.base.name = md.name;
 					object.skip_context = "paint";
 					Project.paintObjects.push(object);
 				});
@@ -169,7 +169,7 @@ class ImportArm {
 			Context.selectPaintObject(Context.mainObject());
 			Viewport.scaleToBounds();
 			Context.raw.paintObject.skip_context = "paint";
-			Context.raw.mergedObject.visible = true;
+			Context.raw.mergedObject.base.visible = true;
 
 			///if (is_paint || is_sculpt)
 			let tex = Project.layers[0].texpaint;
@@ -371,15 +371,15 @@ class ImportArm {
 					object = Context.raw.paintObject;
 				}
 				else {
-					object = Scene.addMeshObject(md, Context.raw.paintObject.materials, Context.raw.paintObject);
-					object.name = md.name;
+					object = Scene.addMeshObject(md, Context.raw.paintObject.materials, Context.raw.paintObject.base);
+					object.base.name = md.name;
 					object.skip_context = "paint";
 					md._handle = md.name;
 					Data.cachedMeshes.set(md._handle, md);
 				}
-				object.transform.scale.set(1, 1, 1);
-				object.transform.buildMatrix();
-				object.name = md.name;
+				object.base.transform.scale.set(1, 1, 1);
+				object.base.transform.buildMatrix();
+				object.base.name = md.name;
 				Project.paintObjects.push(object);
 				UtilMesh.mergeMesh();
 				Viewport.scaleToBounds();

+ 10 - 10
base/Sources/ImportMesh.ts

@@ -71,21 +71,21 @@ class ImportMesh {
 		if (Project.paintObjects.length > 1) {
 			// Sort by name
 			Project.paintObjects.sort((a, b): i32 => {
-				if (a.name < b.name) return -1;
-				else if (a.name > b.name) return 1;
+				if (a.base.name < b.base.name) return -1;
+				else if (a.base.name > b.base.name) return 1;
 				return 0;
 			});
 
 			// No mask by default
-			for (let p of Project.paintObjects) p.visible = true;
+			for (let p of Project.paintObjects) p.base.visible = true;
 			if (Context.raw.mergedObject == null) UtilMesh.mergeMesh();
 			Context.raw.paintObject.skip_context = "paint";
-			Context.raw.mergedObject.visible = true;
+			Context.raw.mergedObject.base.visible = true;
 		}
 
 		Viewport.scaleToBounds();
 
-		if (Context.raw.paintObject.name == "") Context.raw.paintObject.name = "Object";
+		if (Context.raw.paintObject.base.name == "") Context.raw.paintObject.base.name = "Object";
 		MakeMaterial.parsePaintMaterial();
 		MakeMaterial.parseMeshMaterial();
 
@@ -122,7 +122,7 @@ class ImportMesh {
 			}
 
 			Context.raw.paintObject.setData(md);
-			Context.raw.paintObject.name = mesh.name;
+			Context.raw.paintObject.base.name = mesh.name;
 			Project.paintObjects = [Context.raw.paintObject];
 
 			md._handle = raw.name;
@@ -187,14 +187,14 @@ class ImportMesh {
 
 		MeshData.create(raw, (md: TMeshData) => {
 
-			let object = Scene.addMeshObject(md, Context.raw.paintObject.materials, Context.raw.paintObject);
-			object.name = mesh.name;
+			let object = Scene.addMeshObject(md, Context.raw.paintObject.materials, Context.raw.paintObject.base);
+			object.base.name = mesh.name;
 			object.skip_context = "paint";
 
 			// Ensure unique names
 			for (let p of Project.paintObjects) {
-				if (p.name == object.name) {
-					p.name += ".001";
+				if (p.base.name == object.base.name) {
+					p.base.name += ".001";
 					p.data._handle += ".001";
 					Data.cachedMeshes.set(p.data._handle, p.data);
 				}

+ 1 - 1
base/Sources/LineDraw.ts

@@ -136,7 +136,7 @@ class LineDraw {
 		LineDraw.midLine.sub(LineDraw.midPoint);
 
 		let camera = Scene.camera;
-		LineDraw.cameraLook = camera.transform.world.getLoc();
+		LineDraw.cameraLook = camera.base.transform.world.getLoc();
 		LineDraw.cameraLook.sub(LineDraw.midPoint);
 
 		let lineWidth = LineDraw.cameraLook.cross(LineDraw.midLine);

+ 3 - 3
base/Sources/PhysicsBody.ts

@@ -354,7 +354,7 @@ class PhysicsBody {
 
 	static fillConvexHull = (pb: PhysicsBodyRaw, scale: Vec4, margin: f32): Ammo.btConvexHullShape => {
 		// Check whether shape already exists
-		let data = (pb.object as MeshObject).data;
+		let data = pb.object.ext.data;
 		let shape = PhysicsBody.convexHullCache.get(data);
 		if (shape != null) {
 			PhysicsBody.usersCache.set(data, PhysicsBody.usersCache.get(data) + 1);
@@ -386,7 +386,7 @@ class PhysicsBody {
 
 	static fillTriangleMesh = (pb: PhysicsBodyRaw, scale: Vec4): Ammo.btTriangleMesh => {
 		// Check whether shape already exists
-		let data = (pb.object as MeshObject).data;
+		let data = pb.object.ext.data;
 		let triangleMesh = PhysicsBody.triangleMeshCache.get(data);
 		if (triangleMesh != null) {
 			PhysicsBody.usersCache.set(data, PhysicsBody.usersCache.get(data) + 1);
@@ -431,7 +431,7 @@ class PhysicsBody {
 
 		// Delete shape if no other user is found
 		if (pb.shape == ShapeType.ShapeConvexHull || pb.shape == ShapeType.ShapeMesh) {
-			let data = (pb.object as MeshObject).data;
+			let data = pb.object.ext.data;
 			let i = PhysicsBody.usersCache.get(data) - 1;
 			PhysicsBody.usersCache.set(data, i);
 			if (i <= 0) {

+ 1 - 1
base/Sources/PhysicsWorld.ts

@@ -138,7 +138,7 @@ class PhysicsWorld {
 		let start = new Vec4();
 		let end = new Vec4();
 		RayCaster.getDirection(start, end, inputX, inputY, camera);
-		let hit = PhysicsWorld.rayCast(pw, camera.transform.world.getLoc(), end);
+		let hit = PhysicsWorld.rayCast(pw, camera.base.transform.world.getLoc(), end);
 		let body = (hit != null) ? hit.body : null;
 		return body;
 	}

+ 5 - 5
base/Sources/Project.ts

@@ -147,8 +147,8 @@ class Project {
 		for (let i = 0; i < len; ++i) {
 			let m = meshes[len - i - 1];
 			if (Context.raw.projectObjects.indexOf(m) == -1 &&
-				m.name != ".ParticleEmitter" &&
-				m.name != ".Particle") {
+				m.base.name != ".ParticleEmitter" &&
+				m.base.name != ".Particle") {
 				Data.deleteMesh(m.data._handle);
 				m.remove();
 			}
@@ -214,9 +214,9 @@ class Project {
 			///end
 
 			Context.raw.paintObject.setData(md);
-			Context.raw.paintObject.transform.scale.set(1, 1, 1);
-			Context.raw.paintObject.transform.buildMatrix();
-			Context.raw.paintObject.name = n;
+			Context.raw.paintObject.base.transform.scale.set(1, 1, 1);
+			Context.raw.paintObject.base.transform.buildMatrix();
+			Context.raw.paintObject.base.name = n;
 			Project.paintObjects = [Context.raw.paintObject];
 			///if (is_paint || is_sculpt)
 			while (Project.materials.length > 0) SlotMaterial.unload(Project.materials.pop());

+ 21 - 21
base/Sources/RenderPathBase.ts

@@ -58,31 +58,31 @@ class RenderPathBase {
 	static drawCompass = (currentG: Graphics4) => {
 		if (Context.raw.showCompass) {
 			let cam = Scene.camera;
-			let compass: MeshObject = Scene.getChild(".Compass") as MeshObject;
+			let compass: MeshObject = Scene.getChild(".Compass").ext;
 
-			let _visible = compass.visible;
-			let _parent = compass.parent;
-			let _loc = compass.transform.loc;
-			let _rot = compass.transform.rot;
-			let crot = cam.transform.rot;
+			let _visible = compass.base.visible;
+			let _parent = compass.base.parent;
+			let _loc = compass.base.transform.loc;
+			let _rot = compass.base.transform.rot;
+			let crot = cam.base.transform.rot;
 			let ratio = App.w() / App.h();
 			let _P = cam.P;
 			cam.P = Mat4.ortho(-8 * ratio, 8 * ratio, -8, 8, -2, 2);
-			compass.visible = true;
-			compass.parent = cam;
-			compass.transform.loc = new Vec4(7.4 * ratio, 7.0, -1);
-			compass.transform.rot = new Quat(-crot.x, -crot.y, -crot.z, crot.w);
-			compass.transform.scale.set(0.4, 0.4, 0.4);
-			compass.transform.buildMatrix();
+			compass.base.visible = true;
+			compass.base.parent = cam.base;
+			compass.base.transform.loc = new Vec4(7.4 * ratio, 7.0, -1);
+			compass.base.transform.rot = new Quat(-crot.x, -crot.y, -crot.z, crot.w);
+			compass.base.transform.scale.set(0.4, 0.4, 0.4);
+			compass.base.transform.buildMatrix();
 			compass.frustumCulling = false;
 			compass.render(currentG, "overlay", []);
 
 			cam.P = _P;
-			compass.visible = _visible;
-			compass.parent = _parent;
-			compass.transform.loc = _loc;
-			compass.transform.rot = _rot;
-			compass.transform.buildMatrix();
+			compass.base.visible = _visible;
+			compass.base.parent = _parent;
+			compass.base.transform.loc = _loc;
+			compass.base.transform.rot = _rot;
+			compass.base.transform.buildMatrix();
 		}
 	}
 
@@ -101,7 +101,7 @@ class RenderPathBase {
 			let cam = Scene.camera;
 			if (Context.raw.viewIndexLast > -1) {
 				// Save current viewport camera
-				Camera.views[Context.raw.viewIndexLast].setFrom(cam.transform.local);
+				Camera.views[Context.raw.viewIndexLast].setFrom(cam.base.transform.local);
 			}
 
 			let decal = Context.raw.tool == WorkspaceTool.ToolDecal || Context.raw.tool == WorkspaceTool.ToolText;
@@ -111,7 +111,7 @@ class RenderPathBase {
 				Context.raw.ddirty = 1;
 			}
 
-			cam.transform.setMatrix(Camera.views[Context.raw.viewIndex]);
+			cam.base.transform.setMatrix(Camera.views[Context.raw.viewIndex]);
 			cam.buildMatrix();
 			cam.buildProjection();
 		}
@@ -253,7 +253,7 @@ class RenderPathBase {
 			let cam = Scene.camera;
 
 			Context.raw.viewIndex = Context.raw.viewIndex == 0 ? 1 : 0;
-			cam.transform.setMatrix(Camera.views[Context.raw.viewIndex]);
+			cam.base.transform.setMatrix(Camera.views[Context.raw.viewIndex]);
 			cam.buildMatrix();
 			cam.buildProjection();
 
@@ -271,7 +271,7 @@ class RenderPathBase {
 			///end
 
 			Context.raw.viewIndex = Context.raw.viewIndex == 0 ? 1 : 0;
-			cam.transform.setMatrix(Camera.views[Context.raw.viewIndex]);
+			cam.base.transform.setMatrix(Camera.views[Context.raw.viewIndex]);
 			cam.buildMatrix();
 			cam.buildProjection();
 		}

+ 3 - 3
base/Sources/RenderPathRaytrace.ts

@@ -78,7 +78,7 @@ class RenderPathRaytrace {
 		}
 
 		let cam = Scene.camera;
-		let ct = cam.transform;
+		let ct = cam.base.transform;
 		RenderPathRaytrace.helpMat.setFrom(cam.V);
 		RenderPathRaytrace.helpMat.multmat(cam.P);
 		RenderPathRaytrace.helpMat.getInverse(RenderPathRaytrace.helpMat);
@@ -159,9 +159,9 @@ class RenderPathRaytrace {
 		let mo = Scene.meshes[0];
 		///end
 		let md = mo.data;
-		let mo_scale = mo.transform.scale.x; // Uniform scale only
+		let mo_scale = mo.base.transform.scale.x; // Uniform scale only
 		RenderPathRaytrace.vb_scale = md.scale_pos * mo_scale;
-		if (mo.parent != null) RenderPathRaytrace.vb_scale *= mo.parent.transform.scale.x;
+		if (mo.base.parent != null) RenderPathRaytrace.vb_scale *= mo.base.parent.transform.scale.x;
 		RenderPathRaytrace.vb = md._vertexBuffer;
 		RenderPathRaytrace.ib = md._indexBuffers[0];
 	}

+ 13 - 13
base/Sources/TabMeshes.ts

@@ -104,8 +104,8 @@ class TabMeshes {
 			for (let i = 0; i < Project.paintObjects.length; ++i) {
 				let o = Project.paintObjects[i];
 				let h = Zui.handle("tabmeshes_0");
-				h.selected = o.visible;
-				o.visible = ui.check(h, o.name);
+				h.selected = o.base.visible;
+				o.base.visible = ui.check(h, o.base.name);
 				if (ui.isHovered && ui.inputReleasedR) {
 					UIMenu.draw((ui: Zui) => {
 						if (UIMenu.menuButton(ui, tr("Export"))) {
@@ -114,15 +114,15 @@ class TabMeshes {
 						}
 						if (Project.paintObjects.length > 1 && UIMenu.menuButton(ui, tr("Delete"))) {
 							array_remove(Project.paintObjects, o);
-							while (o.children.length > 0) {
-								let child = o.children[0];
+							while (o.base.children.length > 0) {
+								let child = o.base.children[0];
 								child.setParent(null);
-								if (Project.paintObjects[0] != child) {
-									child.setParent(Project.paintObjects[0]);
+								if (Project.paintObjects[0].base != child) {
+									child.setParent(Project.paintObjects[0].base);
 								}
-								if (o.children.length == 0) {
-									Project.paintObjects[0].transform.scale.setFrom(o.transform.scale);
-									Project.paintObjects[0].transform.buildMatrix();
+								if (o.base.children.length == 0) {
+									Project.paintObjects[0].base.transform.scale.setFrom(o.base.transform.scale);
+									Project.paintObjects[0].base.transform.buildMatrix();
 								}
 							}
 							Data.deleteMesh(o.data._handle);
@@ -135,7 +135,7 @@ class TabMeshes {
 				}
 				if (h.changed) {
 					let visibles: MeshObject[] = [];
-					for (let p of Project.paintObjects) if (p.visible) visibles.push(p);
+					for (let p of Project.paintObjects) if (p.base.visible) visibles.push(p);
 					UtilMesh.mergeMesh(visibles);
 					Context.raw.ddirty = 2;
 				}
@@ -166,13 +166,13 @@ class TabMeshes {
 			MeshData.create(raw, (_md: TMeshData) => { md = _md; });
 			mo = new MeshObject(md, Context.raw.paintObject.materials);
 			array_remove(Scene.meshes, mo);
-			mo.name = "Tessellated";
+			mo.base.name = "Tessellated";
 		}
 		else {
-			mo = Scene.getChild(name) as MeshObject;
+			mo = Scene.getChild(name).ext;
 		}
 
-		mo.visible = true;
+		mo.base.visible = true;
 		Context.raw.ddirty = 2;
 		Context.raw.paintObject = mo;
 		Project.paintObjects[0] = mo;

+ 14 - 14
base/Sources/UIBase.ts

@@ -234,7 +234,7 @@ class UIBase {
 
 		if (UIBase.ui.SCALE() > 1) UIBase.setIconScale();
 
-		Context.raw.paintObject = (Scene.getChild(".Cube") as MeshObject);
+		Context.raw.paintObject = Scene.getChild(".Cube").ext;
 		Project.paintObjects = [Context.raw.paintObject];
 
 		if (Project.filepath == "") {
@@ -710,27 +710,27 @@ class UIBase {
 				}
 				History.pushUndo = true;
 				Context.raw.particleHitX = Context.raw.particleHitY = Context.raw.particleHitZ = 0;
-				Scene.spawnObject(".Sphere", null, (o: Object) => {
+				Scene.spawnObject(".Sphere", null, (o: BaseObject) => {
 					Data.getMaterial("Scene", ".Gizmo", (md: TMaterialData) => {
-						let mo: MeshObject = o as MeshObject;
-						mo.name = ".Bullet";
+						let mo: MeshObject = o.ext;
+						mo.base.name = ".Bullet";
 						mo.materials[0] = md;
-						mo.visible = true;
+						mo.base.visible = true;
 
 						let camera = Scene.camera;
-						let ct = camera.transform;
-						mo.transform.loc.set(ct.worldx(), ct.worldy(), ct.worldz());
-						mo.transform.scale.set(Context.raw.brushRadius * 0.2, Context.raw.brushRadius * 0.2, Context.raw.brushRadius * 0.2);
-						mo.transform.buildMatrix();
+						let ct = camera.base.transform;
+						mo.base.transform.loc.set(ct.worldx(), ct.worldy(), ct.worldz());
+						mo.base.transform.scale.set(Context.raw.brushRadius * 0.2, Context.raw.brushRadius * 0.2, Context.raw.brushRadius * 0.2);
+						mo.base.transform.buildMatrix();
 
 						let body = PhysicsBody.create();
 						body.shape = ShapeType.ShapeSphere;
 						body.mass = 1.0;
 						body.ccd = true;
-						mo.transform.radius /= 10; // Lower ccd radius
-						PhysicsBody.init(body, mo);
-						(mo as any).physicsBody = body;
-						mo.transform.radius *= 10;
+						mo.base.transform.radius /= 10; // Lower ccd radius
+						PhysicsBody.init(body, mo.base);
+						(mo.base as any).physicsBody = body;
+						mo.base.transform.radius *= 10;
 
 						let ray = RayCaster.getRay(Mouse.viewX, Mouse.viewY, camera);
 						PhysicsBody.applyImpulse(body, ray.direction.mult(0.15));
@@ -1019,7 +1019,7 @@ class UIBase {
 						else if (Context.raw.tool == WorkspaceTool.ToolParticle) {
 							// Reset particles
 							///if arm_particles
-							let emitter: MeshObject = Scene.getChild(".ParticleEmitter") as MeshObject;
+							let emitter: MeshObject = Scene.getChild(".ParticleEmitter").ext;
 							let psys = emitter.particleSystems[0];
 							psys.time = 0;
 							// psys.time = psys.seed * psys.animtime;

+ 1 - 1
base/Sources/UIHeader.ts

@@ -268,7 +268,7 @@ class UIHeader {
 			}
 			if (Context.raw.bakeType == BakeType.BakeNormal || Context.raw.bakeType == BakeType.BakeHeight || Context.raw.bakeType == BakeType.BakeDerivative) {
 				let ar = [];
-				for (let p of Project.paintObjects) ar.push(p.name);
+				for (let p of Project.paintObjects) ar.push(p.base.name);
 				let polyHandle = Zui.handle("uiheader_13", { position: Context.raw.bakeHighPoly });
 				Context.raw.bakeHighPoly = ui.combo(polyHandle, ar, tr("High Poly"));
 			}

+ 2 - 2
base/Sources/UIMenu.ts

@@ -166,8 +166,8 @@ class UIMenu {
 						else if (newAngle > 2 * Math.PI) newAngle -= Math.floor(newAngle / (2 * Math.PI)) * 2 * Math.PI;
 						Context.raw.lightAngle = newAngle;
 						let m = Mat4.rotationZ(ldiff);
-						light.transform.local.multmat(m);
-						light.transform.decompose();
+						light.base.transform.local.multmat(m);
+						light.base.transform.decompose();
 						Context.raw.ddirty = 2;
 					}
 

+ 4 - 4
base/Sources/UIMenubar.ts

@@ -115,7 +115,7 @@ class UIMenubar {
 
 				if (UIHeader.worktab.position == SpaceType.Space3D) {
 					if (UIMenubar._savedCamera != null) {
-						Scene.camera.transform.setMatrix(UIMenubar._savedCamera);
+						Scene.camera.base.transform.setMatrix(UIMenubar._savedCamera);
 						UIMenubar._savedCamera = null;
 					}
 					Scene.meshes = [Context.mainObject()];
@@ -138,18 +138,18 @@ class UIMenubar {
 						};
 						let md: TMeshData;
 						MeshData.create(raw, (_md: TMeshData) => { md = _md; });
-						let dotPlane: MeshObject = Scene.getChild(".Plane") as MeshObject;
+						let dotPlane: MeshObject = Scene.getChild(".Plane").ext;
 						UIMenubar._plane = new MeshObject(md, dotPlane.materials);
 						array_remove(Scene.meshes, UIMenubar._plane);
 					}
 
 					if (UIMenubar._savedCamera == null) {
-						UIMenubar._savedCamera = Scene.camera.transform.local.clone();
+						UIMenubar._savedCamera = Scene.camera.base.transform.local.clone();
 					}
 					Scene.meshes = [UIMenubar._plane];
 					let m = Mat4.identity();
 					m.translate(0, 0, 1.6);
-					Scene.camera.transform.setMatrix(m);
+					Scene.camera.base.transform.setMatrix(m);
 				}
 				///if (krom_direct3d12 || krom_vulkan || krom_metal)
 				RenderPathRaytrace.ready = false;

+ 1 - 1
base/Sources/UniformsExt.ts

@@ -102,7 +102,7 @@ class UniformsExt {
 				return val;
 			}
 			case "_objectId": {
-				return Project.paintObjects.indexOf(object as MeshObject);
+				return Project.paintObjects.indexOf(object.ext);
 			}
 			///if is_paint
 			case "_dilateRadius": {

+ 8 - 8
base/Sources/UtilMesh.ts

@@ -35,9 +35,9 @@ class UtilMesh {
 			// Translate
 			///if is_forge
 			for (let j = 0; j < Math.floor(va0.length / 4); ++j) {
-				va0[j * 4     + voff * 4] += Math.floor(paintObjects[i].transform.worldx() * 32767);
-				va0[j * 4 + 1 + voff * 4] += Math.floor(paintObjects[i].transform.worldy() * 32767);
-				va0[j * 4 + 2 + voff * 4] += Math.floor(paintObjects[i].transform.worldz() * 32767);
+				va0[j * 4     + voff * 4] += Math.floor(paintObjects[i].base.transform.worldx() * 32767);
+				va0[j * 4 + 1 + voff * 4] += Math.floor(paintObjects[i].base.transform.worldy() * 32767);
+				va0[j * 4 + 2 + voff * 4] += Math.floor(paintObjects[i].base.transform.worldz() * 32767);
 			}
 			///end
 
@@ -61,7 +61,7 @@ class UtilMesh {
 		}
 
 		let raw: TMeshData = {
-			name: Context.raw.paintObject.name,
+			name: Context.raw.paintObject.base.name,
 			vertex_arrays: [
 				{ values: va0, attrib: "pos", data: "short4norm" },
 				{ values: va1, attrib: "nor", data: "short2norm" },
@@ -78,9 +78,9 @@ class UtilMesh {
 		UtilMesh.removeMergedMesh();
 		MeshData.create(raw, (md: TMeshData) => {
 			Context.raw.mergedObject = new MeshObject(md, Context.raw.paintObject.materials);
-			Context.raw.mergedObject.name = Context.raw.paintObject.name + "_merged";
+			Context.raw.mergedObject.base.name = Context.raw.paintObject.base.name + "_merged";
 			Context.raw.mergedObject.force_context = "paint";
-			Context.raw.mergedObject.setParent(Context.mainObject());
+			Context.raw.mergedObject.base.setParent(Context.mainObject().base);
 		});
 
 		///if (krom_direct3d12 || krom_vulkan || krom_metal)
@@ -297,8 +297,8 @@ class UtilMesh {
 				if (Math.abs(va[i * 4 + 1] * sc - dy) > maxScale) maxScale = Math.abs(va[i * 4 + 1] * sc - dy);
 				if (Math.abs(va[i * 4 + 2] * sc - dz) > maxScale) maxScale = Math.abs(va[i * 4 + 2] * sc - dz);
 			}
-			o.transform.scaleWorld = o.data.scale_pos = o.data.scale_pos = maxScale;
-			o.transform.buildMatrix();
+			o.base.transform.scaleWorld = o.data.scale_pos = o.data.scale_pos = maxScale;
+			o.base.transform.buildMatrix();
 
 			for (let i = 0; i < Math.floor(va.length / 4); ++i) {
 				va[i * 4    ] = Math.floor((va[i * 4    ] * sc - dx) / maxScale * 32767);

+ 9 - 9
base/Sources/UtilParticle.ts

@@ -69,10 +69,10 @@ class UtilParticle {
 			}
 
 			Scene.spawnObject(".Sphere", null, (o: BaseObject) => {
-				let mo: MeshObject = o as MeshObject;
-				mo.name = ".ParticleEmitter";
-				mo.raw = JSON.parse(JSON.stringify(mo.raw));
-				mo.raw.particle_refs = particle_refs;
+				let mo: MeshObject = o.ext;
+				mo.base.name = ".ParticleEmitter";
+				mo.base.raw = JSON.parse(JSON.stringify(mo.base.raw));
+				mo.base.raw.particle_refs = particle_refs;
 				///if arm_particles
 				mo.setupParticleSystem("Scene", particle_refs[0]);
 				///end
@@ -99,14 +99,14 @@ class UtilParticle {
 
 		let po = Context.raw.mergedObject != null ? Context.raw.mergedObject : Context.raw.paintObject;
 
-		po.transform.scale.x = po.parent.transform.scale.x;
-		po.transform.scale.y = po.parent.transform.scale.y;
-		po.transform.scale.z = po.parent.transform.scale.z;
+		po.base.transform.scale.x = po.base.parent.transform.scale.x;
+		po.base.transform.scale.y = po.base.parent.transform.scale.y;
+		po.base.transform.scale.z = po.base.parent.transform.scale.z;
 
 		Context.raw.paintBody = PhysicsBody.create();
 		Context.raw.paintBody.shape = ShapeType.ShapeMesh;
-		PhysicsBody.init(Context.raw.paintBody, po);
-		(po as any).physicsBody = Context.raw.paintBody;
+		PhysicsBody.init(Context.raw.paintBody, po.base);
+		(po.base as any).physicsBody = Context.raw.paintBody;
 	}
 
 	///end

+ 39 - 39
base/Sources/UtilRender.ts

@@ -12,8 +12,8 @@ class UtilRender {
 	static makeMaterialPreview = () => {
 		Context.raw.materialPreview = true;
 
-		let sphere: MeshObject = Scene.getChild(".Sphere") as MeshObject;
-		sphere.visible = true;
+		let sphere: MeshObject = Scene.getChild(".Sphere").ext;
+		sphere.base.visible = true;
 		let meshes = Scene.meshes;
 		Scene.meshes = [sphere];
 		let painto = Context.raw.paintObject;
@@ -22,9 +22,9 @@ class UtilRender {
 		sphere.materials[0] = Project.materials[0].data;
 		Context.raw.material.previewReady = true;
 
-		Context.raw.savedCamera.setFrom(Scene.camera.transform.local);
+		Context.raw.savedCamera.setFrom(Scene.camera.base.transform.local);
 		let m = new Mat4(0.9146286343879498, -0.0032648027153306235, 0.404281837254303, 0.4659988049397712, 0.404295023959927, 0.007367569133732468, -0.9145989516155143, -1.0687517188018691, 0.000007410128652369705, 0.9999675337275382, 0.008058532943908717, 0.015935682577325486, 0, 0, 0, 1);
-		Scene.camera.transform.setMatrix(m);
+		Scene.camera.base.transform.setMatrix(m);
 		let savedFov = Scene.camera.data.fov;
 		Scene.camera.data.fov = 0.92;
 		Viewport.updateCameraType(CameraType.CameraPerspective);
@@ -59,11 +59,11 @@ class UtilRender {
 		RenderPath.lastH = App.h();
 
 		// Restore
-		sphere.visible = false;
+		sphere.base.visible = false;
 		Scene.meshes = meshes;
 		Context.raw.paintObject = painto;
 
-		Scene.camera.transform.setMatrix(Context.raw.savedCamera);
+		Scene.camera.base.transform.setMatrix(Context.raw.savedCamera);
 		Viewport.updateCameraType(Context.raw.cameraType);
 		Scene.camera.data.fov = savedFov;
 		Scene.camera.buildProjection();
@@ -87,25 +87,25 @@ class UtilRender {
 		}
 		Context.raw.decalPreview = true;
 
-		let plane: MeshObject = Scene.getChild(".Plane") as MeshObject;
-		plane.transform.scale.set(1, 1, 1);
-		plane.transform.rot.fromEuler(-Math.PI / 2, 0, 0);
-		plane.transform.buildMatrix();
-		plane.visible = true;
+		let plane: MeshObject = Scene.getChild(".Plane").ext;
+		plane.base.transform.scale.set(1, 1, 1);
+		plane.base.transform.rot.fromEuler(-Math.PI / 2, 0, 0);
+		plane.base.transform.buildMatrix();
+		plane.base.visible = true;
 		let meshes = Scene.meshes;
 		Scene.meshes = [plane];
 		let painto = Context.raw.paintObject;
 		Context.raw.paintObject = plane;
 
-		Context.raw.savedCamera.setFrom(Scene.camera.transform.local);
+		Context.raw.savedCamera.setFrom(Scene.camera.base.transform.local);
 		let m = Mat4.identity();
 		m.translate(0, 0, 1);
-		Scene.camera.transform.setMatrix(m);
+		Scene.camera.base.transform.setMatrix(m);
 		let savedFov = Scene.camera.data.fov;
 		Scene.camera.data.fov = 0.92;
 		Viewport.updateCameraType(CameraType.CameraPerspective);
 		let light = Scene.lights[0];
-		light.visible = false;
+		light.base.visible = false;
 		Scene.world._envmap = Context.raw.previewEnvmap;
 
 		// No resize
@@ -125,17 +125,17 @@ class UtilRender {
 		RenderPath.lastH = App.h();
 
 		// Restore
-		plane.visible = false;
+		plane.base.visible = false;
 		Scene.meshes = meshes;
 		Context.raw.paintObject = painto;
 
-		Scene.camera.transform.setMatrix(Context.raw.savedCamera);
+		Scene.camera.base.transform.setMatrix(Context.raw.savedCamera);
 		Scene.camera.data.fov = savedFov;
 		Viewport.updateCameraType(Context.raw.cameraType);
 		Scene.camera.buildProjection();
 		Scene.camera.buildMatrix();
 		light = Scene.lights[0];
-		light.visible = true;
+		light.base.visible = true;
 		Scene.world._envmap = Context.raw.showEnvmap ? Context.raw.savedEnvmap : Context.raw.emptyEnvmap;
 
 		MakeMaterial.parseMeshMaterial();
@@ -244,37 +244,37 @@ class UtilRender {
 		let painto = Context.raw.paintObject;
 		let visibles: bool[] = [];
 		for (let p of Project.paintObjects) {
-			visibles.push(p.visible);
-			p.visible = false;
+			visibles.push(p.base.visible);
+			p.base.visible = false;
 		}
 		let mergedObjectVisible = false;
 		if (Context.raw.mergedObject != null) {
-			mergedObjectVisible = Context.raw.mergedObject.visible;
-			Context.raw.mergedObject.visible = false;
+			mergedObjectVisible = Context.raw.mergedObject.base.visible;
+			Context.raw.mergedObject.base.visible = false;
 		}
 
 		let cam = Scene.camera;
-		Context.raw.savedCamera.setFrom(cam.transform.local);
+		Context.raw.savedCamera.setFrom(cam.base.transform.local);
 		let savedFov = cam.data.fov;
 		Viewport.updateCameraType(CameraType.CameraPerspective);
 		let m = Mat4.identity();
 		m.translate(0, 0, 0.5);
-		cam.transform.setMatrix(m);
+		cam.base.transform.setMatrix(m);
 		cam.data.fov = 0.92;
 		cam.buildProjection();
 		cam.buildMatrix();
 		m.getInverse(Scene.camera.VP);
 
-		let planeo: MeshObject = Scene.getChild(".Plane") as MeshObject;
-		planeo.visible = true;
+		let planeo: MeshObject = Scene.getChild(".Plane").ext;
+		planeo.base.visible = true;
 		Context.raw.paintObject = planeo;
 
 		let v = new Vec4();
 		let sx = v.set(m._00, m._01, m._02).length();
-		planeo.transform.rot.fromEuler(-Math.PI / 2, 0, 0);
-		planeo.transform.scale.set(sx, 1.0, sx);
-		planeo.transform.loc.set(m._30, -m._31, 0.0);
-		planeo.transform.buildMatrix();
+		planeo.base.transform.rot.fromEuler(-Math.PI / 2, 0, 0);
+		planeo.base.transform.scale.set(sx, 1.0, sx);
+		planeo.base.transform.loc.set(m._30, -m._31, 0.0);
+		planeo.base.transform.buildMatrix();
 
 		RenderPathPaint.liveLayerDrawn = 0;
 		RenderPathBase.drawGbuffer();
@@ -325,15 +325,15 @@ class UtilRender {
 
 		// Restore paint mesh
 		Context.raw.materialPreview = false;
-		planeo.visible = false;
+		planeo.base.visible = false;
 		for (let i = 0; i < Project.paintObjects.length; ++i) {
-			Project.paintObjects[i].visible = visibles[i];
+			Project.paintObjects[i].base.visible = visibles[i];
 		}
 		if (Context.raw.mergedObject != null) {
-			Context.raw.mergedObject.visible = mergedObjectVisible;
+			Context.raw.mergedObject.base.visible = mergedObjectVisible;
 		}
 		Context.raw.paintObject = painto;
-		Scene.camera.transform.setMatrix(Context.raw.savedCamera);
+		Scene.camera.base.transform.setMatrix(Context.raw.savedCamera);
 		Scene.camera.data.fov = savedFov;
 		Viewport.updateCameraType(Context.raw.cameraType);
 		Scene.camera.buildProjection();
@@ -371,22 +371,22 @@ class UtilRender {
 			UtilRender.createScreenAlignedFullData();
 		}
 
-		let _scaleWorld = Context.raw.paintObject.transform.scaleWorld;
-		Context.raw.paintObject.transform.scaleWorld = 3.0;
-		Context.raw.paintObject.transform.buildMatrix();
+		let _scaleWorld = Context.raw.paintObject.base.transform.scaleWorld;
+		Context.raw.paintObject.base.transform.scaleWorld = 3.0;
+		Context.raw.paintObject.base.transform.buildMatrix();
 
 		g4.begin();
 		g4.setPipeline(res.scon._pipeState);
 		Uniforms.setContextConstants(g4, res.scon, [""]);
-		Uniforms.setObjectConstants(g4, res.scon, Context.raw.paintObject);
+		Uniforms.setObjectConstants(g4, res.scon, Context.raw.paintObject.base);
 		Uniforms.setMaterialConstants(g4, res.scon, res.mcon);
 		g4.setVertexBuffer(UtilRender.screenAlignedFullVB);
 		g4.setIndexBuffer(UtilRender.screenAlignedFullIB);
 		g4.drawIndexedVertices();
 		g4.end();
 
-		Context.raw.paintObject.transform.scaleWorld = _scaleWorld;
-		Context.raw.paintObject.transform.buildMatrix();
+		Context.raw.paintObject.base.transform.scaleWorld = _scaleWorld;
+		Context.raw.paintObject.base.transform.buildMatrix();
 	}
 
 	static pickPosNorTex = () => {

+ 24 - 24
base/Sources/Viewport.ts

@@ -7,13 +7,13 @@ class Viewport {
 		let aabb = MeshData.calculateAABB(md);
 		let r = Math.sqrt(aabb.x * aabb.x + aabb.y * aabb.y + aabb.z * aabb.z);
 		po = Context.mainObject();
-		po.transform.dim.x = aabb.x;
-		po.transform.dim.y = aabb.y;
-		po.transform.dim.z = aabb.z;
-		po.transform.scale.set(2 / r, 2 / r, 2 / r);
-		po.transform.loc.set(0, 0, 0);
-		po.transform.buildMatrix();
-		for (let c of po.children) {
+		po.base.transform.dim.x = aabb.x;
+		po.base.transform.dim.y = aabb.y;
+		po.base.transform.dim.z = aabb.z;
+		po.base.transform.scale.set(2 / r, 2 / r, 2 / r);
+		po.base.transform.loc.set(0, 0, 0);
+		po.base.transform.buildMatrix();
+		for (let c of po.base.children) {
 			c.transform.loc.set(0, 0, 0);
 			c.transform.buildMatrix();
 		}
@@ -23,28 +23,28 @@ class Viewport {
 		let cam = Scene.camera;
 		for (let o of Scene.raw.objects) {
 			if (o.type == "camera_object") {
-				cam.transform.local.setF32(o.transform.values);
-				cam.transform.decompose();
+				cam.base.transform.local.setF32(o.transform.values);
+				cam.base.transform.decompose();
 				if (Context.raw.fovHandle != null) Context.raw.fovHandle.value = cam.data.fov = Base.defaultFov;
 				Context.raw.camHandle.position = 0;
 				cam.data.ortho = null;
 				cam.buildProjection();
 				Context.raw.ddirty = 2;
 				Camera.reset();
-				Context.mainObject().transform.reset();
+				Context.mainObject().base.transform.reset();
 				break;
 			}
 		}
 	}
 
 	static setView = (x: f32, y: f32, z: f32, rx: f32, ry: f32, rz: f32) => {
-		Context.raw.paintObject.transform.rot.set(0, 0, 0, 1);
-		Context.raw.paintObject.transform.dirty = true;
+		Context.raw.paintObject.base.transform.rot.set(0, 0, 0, 1);
+		Context.raw.paintObject.base.transform.dirty = true;
 		let cam = Scene.camera;
-		let dist = cam.transform.loc.length();
-		cam.transform.loc.set(x * dist, y * dist, z * dist);
-		cam.transform.rot.fromEuler(rx, ry, rz);
-		cam.transform.buildMatrix();
+		let dist = cam.base.transform.loc.length();
+		cam.base.transform.loc.set(x * dist, y * dist, z * dist);
+		cam.base.transform.rot.fromEuler(rx, ry, rz);
+		cam.base.transform.buildMatrix();
 		cam.buildProjection();
 		Context.raw.ddirty = 2;
 		Camera.reset(Context.raw.viewIndexLast);
@@ -53,10 +53,10 @@ class Viewport {
 	static orbit = (x: f32, y: f32) => {
 		let cam = Scene.camera;
 		let dist = Camera.distance();
-		cam.transform.move(cam.lookWorld(), dist);
-		cam.transform.rotate(new Vec4(0, 0, 1), x);
-		cam.transform.rotate(cam.rightWorld(), y);
-		cam.transform.move(cam.lookWorld(), -dist);
+		cam.base.transform.move(cam.lookWorld(), dist);
+		cam.base.transform.rotate(new Vec4(0, 0, 1), x);
+		cam.base.transform.rotate(cam.rightWorld(), y);
+		cam.base.transform.move(cam.lookWorld(), -dist);
 		Context.raw.ddirty = 2;
 	}
 
@@ -68,7 +68,7 @@ class Viewport {
 
 	static zoom = (f: f32) => {
 		let cam = Scene.camera;
-		cam.transform.move(cam.look(), f);
+		cam.base.transform.move(cam.look(), f);
 		Context.raw.ddirty = 2;
 	}
 
@@ -77,17 +77,17 @@ class Viewport {
 		let light = Scene.lights[0];
 		if (cameraType == CameraType.CameraPerspective) {
 			cam.data.ortho = null;
-			light.visible = true;
+			light.base.visible = true;
 		}
 		else {
 			let f32a = new Float32Array(4);
-			let f = cam.data.fov * cam.transform.world.getLoc().length() / 2.5;
+			let f = cam.data.fov * cam.base.transform.world.getLoc().length() / 2.5;
 			f32a[0] = -2 * f;
 			f32a[1] =  2 * f;
 			f32a[2] = -2 * f * (App.h() / App.w());
 			f32a[3] =  2 * f * (App.h() / App.w());
 			cam.data.ortho = f32a;
-			light.visible = false;
+			light.base.visible = false;
 		}
 		cam.buildProjection();
 		Context.raw.ddirty = 2;