Sfoglia il codice sorgente

Updated examples builds

Mr.doob 4 anni fa
parent
commit
55f98ce493
2 ha cambiato i file con 232 aggiunte e 52 eliminazioni
  1. 63 52
      examples/js/exporters/USDZExporter.js
  2. 169 0
      examples/js/physics/OimoPhysics.js

+ 63 - 52
examples/js/exporters/USDZExporter.js

@@ -38,15 +38,12 @@
 
 					}
 
-					const referencedMesh = `prepend references = @./${geometryFileName}@</Geometry>`;
-					const referencedMaterial = `rel material:binding = </Materials/Material_${material.id}>`;
-					output += buildXform( object, referencedMesh, referencedMaterial );
+					output += buildXform( object, geometry, material );
 
 				}
 
 			} );
 			output += buildMaterials( materials );
-			output += buildTextures( textures );
 			files[ modelFileName ] = fflate.strToU8( output );
 			output = null;
 
@@ -136,19 +133,18 @@
 	} // Xform
 
 
-	function buildXform( object, referencedMesh, referencedMaterial ) {
+	function buildXform( object, geometry, material ) {
 
 		const name = 'Object_' + object.id;
 		const transform = buildMatrix( object.matrixWorld );
-		return `def Xform "${name}"
-(
-	${referencedMesh}
+		return `def Xform "${name}" (
+    prepend references = @./geometries/Geometry_${geometry.id}.usd@</Geometry>
 )
 {
     matrix4d xformOp:transform = ${transform}
     uniform token[] xformOpOrder = ["xformOp:transform"]
 
-    ${referencedMaterial}
+    rel material:binding = </Materials/Material_${material.id}>
 }
 
 `;
@@ -175,7 +171,7 @@
 		return `
 def "Geometry"
 {
-	${mesh}
+  ${mesh}
 }
 `;
 
@@ -194,7 +190,7 @@ def "Geometry"
 		}
 
 		return `
-	def Mesh "${name}"
+    def Mesh "${name}"
     {
         int[] faceVertexCounts = [${buildMeshVertexCount( geometry )}]
         int[] faceVertexIndices = [${buildMeshVertexIndices( geometry )}]
@@ -309,10 +305,40 @@ ${array.join( '' )}
 		// https://graphics.pixar.com/usd/docs/UsdPreviewSurface-Proposal.html
 		const pad = '            ';
 		const parameters = [];
+		const textures = [];
+
+		function buildTexture( texture, mapType ) {
+
+			return `
+        def Shader "Transform2d_${mapType}" (
+            sdrMetadata = {
+                string role = "math"
+            }
+        )
+        {
+            uniform token info:id = "UsdTransform2d"
+            float2 inputs:in.connect = </Materials/Material_${material.id}/uvReader_st.outputs:result>
+            float2 inputs:scale = ${buildVector2( texture.repeat )}
+            float2 inputs:translation = ${buildVector2( texture.offset )}
+            float2 outputs:result
+        }
+
+        def Shader "Texture_${texture.id}"
+        {
+            uniform token info:id = "UsdUVTexture"
+            asset inputs:file = @textures/Texture_${texture.id}.jpg@
+            float2 inputs:st.connect = </Materials/Material_${material.id}/Transform2d_${mapType}.outputs:result>
+            token inputs:wrapS = "repeat"
+            token inputs:wrapT = "repeat"
+            float3 outputs:rgb
+        }`;
+
+		}
 
 		if ( material.map !== null ) {
 
-			parameters.push( `${pad}color3f inputs:diffuseColor.connect = </Textures/Texture_${material.map.id}.outputs:rgb>` );
+			parameters.push( `${pad}color3f inputs:diffuseColor.connect = </Materials/Material_${material.id}/Texture_${material.map.id}.outputs:rgb>` );
+			textures.push( buildTexture( material.map, 'diffuse' ) );
 
 		} else {
 
@@ -322,7 +348,8 @@ ${array.join( '' )}
 
 		if ( material.emissiveMap !== null ) {
 
-			parameters.push( `${pad}color3f inputs:emissiveColor.connect = </Textures/Texture_${material.emissiveMap.id}.outputs:rgb>` );
+			parameters.push( `${pad}color3f inputs:emissiveColor.connect = </Materials/Material_${material.id}/Texture_${material.emissiveMap.id}.outputs:rgb>` );
+			textures.push( buildTexture( material.emissiveMap, 'emissive' ) );
 
 		} else if ( material.emissive.getHex() > 0 ) {
 
@@ -332,19 +359,22 @@ ${array.join( '' )}
 
 		if ( material.normalMap !== null ) {
 
-			parameters.push( `${pad}normal3f inputs:normal.connect = </Textures/Texture_${material.normalMap.id}.outputs:rgb>` );
+			parameters.push( `${pad}normal3f inputs:normal.connect = </Materials/Material_${material.id}/Texture_${material.normalMap.id}.outputs:rgb>` );
+			textures.push( buildTexture( material.normalMap, 'normal' ) );
 
 		}
 
 		if ( material.aoMap !== null ) {
 
-			parameters.push( `${pad}float inputs:occlusion.connect = </Textures/Texture_${material.aoMap.id}.outputs:r>` );
+			parameters.push( `${pad}float inputs:occlusion.connect = </Materials/Material_${material.id}/Texture_${material.aoMap.id}.outputs:r>` );
+			textures.push( buildTexture( material.aoMap, 'occlusion' ) );
 
 		}
 
 		if ( material.roughnessMap !== null ) {
 
-			parameters.push( `${pad}float inputs:roughness.connect = </Textures/Texture_${material.roughnessMap.id}.outputs:g>` );
+			parameters.push( `${pad}float inputs:roughness.connect = </Materials/Material_${material.id}/Texture_${material.roughnessMap.id}_roughness.outputs:g>` );
+			textures.push( buildTexture( material.roughnessMap, 'roughness' ) );
 
 		} else {
 
@@ -354,7 +384,8 @@ ${array.join( '' )}
 
 		if ( material.metalnessMap !== null ) {
 
-			parameters.push( `${pad}float inputs:metallic.connect = </Textures/Texture_${material.metalnessMap.id}.outputs:b>` );
+			parameters.push( `${pad}float inputs:metallic.connect = </Materials/Material_${material.id}/Texture_${material.metalnessMap.id}_metalness.outputs:b>` );
+			textures.push( buildTexture( material.metalnessMap, 'metallic' ) );
 
 		} else {
 
@@ -366,8 +397,6 @@ ${array.join( '' )}
 		return `
     def Material "Material_${material.id}"
     {
-        token outputs:surface.connect = </Materials/Material_${material.id}/PreviewSurface.outputs:surface>
-
         def Shader "PreviewSurface"
         {
             uniform token info:id = "UsdPreviewSurface"
@@ -375,52 +404,34 @@ ${parameters.join( '\n' )}
             int inputs:useSpecularWorkflow = 0
             token outputs:surface
         }
-    }
-`;
-
-	}
-
-	function buildTextures( textures ) {
-
-		const array = [];
-
-		for ( const uuid in textures ) {
 
-			const texture = textures[ uuid ];
-			array.push( buildTexture( texture ) );
+        token outputs:surface.connect = </Materials/Material_${material.id}/PreviewSurface.outputs:surface>
+        token inputs:frame:stPrimvarName = "st"
 
-		}
+        def Shader "uvReader_st"
+        {
+            uniform token info:id = "UsdPrimvarReader_float2"
+            token inputs:varname.connect = </Materials/Material_${material.id}.inputs:frame:stPrimvarName>
+            float2 inputs:fallback = (0.0, 0.0)
+            float2 outputs:result
+        }
 
-		return `def "Textures"
-{
-${array.join( '' )}
-}
+${textures.join( '\n' )}
 
+    }
 `;
 
 	}
 
-	function buildTexture( texture ) {
+	function buildColor( color ) {
 
-		return `
-    def Shader "Texture_${texture.id}"
-    {
-        uniform token info:id = "UsdUVTexture"
-        asset inputs:file = @textures/Texture_${texture.id}.jpg@
-        token inputs:wrapS = "repeat"
-        token inputs:wrapT = "repeat"
-        float outputs:r
-        float outputs:g
-        float outputs:b
-        float3 outputs:rgb
-    }
-`;
+		return `(${color.r}, ${color.g}, ${color.b})`;
 
 	}
 
-	function buildColor( color ) {
+	function buildVector2( vector ) {
 
-		return `(${color.r}, ${color.g}, ${color.b})`;
+		return `(${vector.x}, ${vector.y})`;
 
 	}
 

+ 169 - 0
examples/js/physics/OimoPhysics.js

@@ -0,0 +1,169 @@
+( function () {
+import { World, Vec3, OBoxGeometry, OSphereGeometry, ShapeConfig, RigidBodyConfig, RigidBodyType, RigidBody, Shape } from '../libs/OimoPhysics/index.js';
+
+async function OimoPhysics() {
+  const frameRate = 60;
+  const world = new World(2, new Vec3(0, -9.8, 0)); //
+
+  function getShape(geometry) {
+    const parameters = geometry.parameters; // TODO change type to is*
+
+    if (geometry.type === 'BoxGeometry') {
+      const sx = parameters.width !== undefined ? parameters.width / 2 : 0.5;
+      const sy = parameters.height !== undefined ? parameters.height / 2 : 0.5;
+      const sz = parameters.depth !== undefined ? parameters.depth / 2 : 0.5;
+      return new OBoxGeometry(new Vec3(sx, sy, sz));
+    } else if (geometry.type === 'SphereGeometry' || geometry.type === 'IcosahedronGeometry') {
+      const radius = parameters.radius !== undefined ? parameters.radius : 1;
+      return new OSphereGeometry(radius);
+    }
+
+    return null;
+  }
+
+  const meshes = [];
+  const meshMap = new WeakMap();
+
+  function addMesh(mesh, mass = 0) {
+    const shape = getShape(mesh.geometry);
+
+    if (shape !== null) {
+      if (mesh.isInstancedMesh) {
+        handleInstancedMesh(mesh, mass, shape);
+      } else if (mesh.isMesh) {
+        handleMesh(mesh, mass, shape);
+      }
+    }
+  }
+
+  function handleMesh(mesh, mass, shape) {
+    const shapeConfig = new ShapeConfig();
+    shapeConfig.geometry = shape;
+    const bodyConfig = new RigidBodyConfig();
+    bodyConfig.type = mass === 0 ? RigidBodyType.STATIC : RigidBodyType.DYNAMIC;
+    bodyConfig.position = new Vec3(mesh.position.x, mesh.position.y, mesh.position.z);
+    const body = new RigidBody(bodyConfig);
+    body.addShape(new Shape(shapeConfig));
+    world.addRigidBody(body);
+
+    if (mass > 0) {
+      meshes.push(mesh);
+      meshMap.set(mesh, body);
+    }
+  }
+
+  function handleInstancedMesh(mesh, mass, shape) {
+    const array = mesh.instanceMatrix.array;
+    const bodies = [];
+
+    for (let i = 0; i < mesh.count; i++) {
+      const index = i * 16;
+      const shapeConfig = new ShapeConfig();
+      shapeConfig.geometry = shape;
+      const bodyConfig = new RigidBodyConfig();
+      bodyConfig.type = mass === 0 ? RigidBodyType.STATIC : RigidBodyType.DYNAMIC;
+      bodyConfig.position = new Vec3(array[index + 12], array[index + 13], array[index + 14]);
+      const body = new RigidBody(bodyConfig);
+      body.addShape(new Shape(shapeConfig));
+      world.addRigidBody(body);
+      bodies.push(body);
+    }
+
+    if (mass > 0) {
+      meshes.push(mesh);
+      meshMap.set(mesh, bodies);
+    }
+  } //
+
+
+  function setMeshPosition(mesh, position, index = 0) {
+    if (mesh.isInstancedMesh) {
+      const bodies = meshMap.get(mesh);
+      const body = bodies[index];
+      body.setPosition(new Vec3(position.x, position.y, position.z));
+    } else if (mesh.isMesh) {
+      const body = meshMap.get(mesh);
+      body.setPosition(new Vec3(position.x, position.y, position.z));
+    }
+  } //
+
+
+  let lastTime = 0;
+
+  function step() {
+    const time = performance.now();
+
+    if (lastTime > 0) {
+      // console.time( 'world.step' );
+      world.step(1 / frameRate); // console.timeEnd( 'world.step' );
+    }
+
+    lastTime = time; //
+
+    for (let i = 0, l = meshes.length; i < l; i++) {
+      const mesh = meshes[i];
+
+      if (mesh.isInstancedMesh) {
+        const array = mesh.instanceMatrix.array;
+        const bodies = meshMap.get(mesh);
+
+        for (let j = 0; j < bodies.length; j++) {
+          const body = bodies[j];
+          compose(body.getPosition(), body.getOrientation(), array, j * 16);
+        }
+
+        mesh.instanceMatrix.needsUpdate = true;
+      } else if (mesh.isMesh) {
+        const body = meshMap.get(mesh);
+        mesh.position.copy(body.getPosition());
+        mesh.quaternion.copy(body.getOrientation());
+      }
+    }
+  } // animate
+
+
+  setInterval(step, 1000 / frameRate);
+  return {
+    addMesh: addMesh,
+    setMeshPosition: setMeshPosition // addCompoundMesh
+
+  };
+}
+
+function compose(position, quaternion, array, index) {
+  const x = quaternion.x,
+        y = quaternion.y,
+        z = quaternion.z,
+        w = quaternion.w;
+  const x2 = x + x,
+        y2 = y + y,
+        z2 = z + z;
+  const xx = x * x2,
+        xy = x * y2,
+        xz = x * z2;
+  const yy = y * y2,
+        yz = y * z2,
+        zz = z * z2;
+  const wx = w * x2,
+        wy = w * y2,
+        wz = w * z2;
+  array[index + 0] = 1 - (yy + zz);
+  array[index + 1] = xy + wz;
+  array[index + 2] = xz - wy;
+  array[index + 3] = 0;
+  array[index + 4] = xy - wz;
+  array[index + 5] = 1 - (xx + zz);
+  array[index + 6] = yz + wx;
+  array[index + 7] = 0;
+  array[index + 8] = xz + wy;
+  array[index + 9] = yz - wx;
+  array[index + 10] = 1 - (xx + yy);
+  array[index + 11] = 0;
+  array[index + 12] = position.x;
+  array[index + 13] = position.y;
+  array[index + 14] = position.z;
+  array[index + 15] = 1;
+}
+
+THREE.OimoPhysics = OimoPhysics;
+} )();