Changeset 184
- Timestamp:
- 05/31/10 13:28:34 (2 years ago)
- Files:
-
- trunk/src/tests/integration/main.d (modified) (3 diffs)
- trunk/src/yage/resource/collada.d (modified) (15 diffs)
- trunk/src/yage/resource/geometry.d (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/tests/integration/main.d
r183 r184 154 154 155 155 // Create a textured plane 156 Geometry geometry = Geometry.createPlane( 16, 16);156 Geometry geometry = Geometry.createPlane(4, 4); 157 157 Texture texture = Texture(ResourceManager.texture("space/rocky2.jpg")); 158 158 Texture normal = Texture(ResourceManager.texture("space/rocky2-normal.jpg")); … … 213 213 //beast.setAngularVelocity(Vec3f(0, .5, 0)); 214 214 215 // For testing sprites216 plane = scene.addChild(new ModelNode(geometry));217 plane.setPosition(Vec3f(0, -10, 0));218 plane.setRotation(Vec3f(-PI/2, 0, 0));219 plane.setScale(Vec3f(10));220 221 222 215 // Lights 223 216 auto rotater = addChild(new ModelNode()); … … 225 218 auto light1 = rotater.addChild(new LightNode()); 226 219 light1.setPosition(Vec3f(10, 0, 0)); 227 //light1.setAngularVelocity(Vec3f(0, 10, 0)); // TODO: This seems to make it gradually move?220 //light1.setAngularVelocity(Vec3f(0, 10, 0)); 228 221 light1.diffuse = "white"; 229 light1.setLightRadius( 30);222 light1.setLightRadius(80); 230 223 //light1.spotExponent = 3; 231 224 //light1.spotAngle = 80 * 3.1415/180; trunk/src/yage/resource/collada.d
r183 r184 104 104 if (mesh.hasChild("polylist")) 105 105 polyList = mesh.getChild("polylist"); 106 else if (mesh.hasChild("triangles")) 107 polyList = mesh.getChild("triangles"); 106 108 else 107 polyList = mesh.getChild(" triangles");109 polyList = mesh.getChild("polygons"); // collada 1.3? 108 110 109 111 // Inputs are the cordinates that the triangles index into. … … 121 123 { 122 124 inputs[i].name = inputNode.getAttribute("semantic"); 125 char[] offset = inputNode.hasAttribute("offset") ? inputNode.getAttribute("offset") : inputNode.getAttribute("idx"); 123 126 try { 124 inputs[i].offset = Xml.parseNumber!(int)( inputNode.getAttribute("offset"));127 inputs[i].offset = Xml.parseNumber!(int)(offset); 125 128 } catch (ConversionException e) 126 129 { throw new XmlException(e.toString()); 127 130 } 128 131 129 132 if (inputs[i].name=="VERTEX") // VERTEX type requires another level of indirection to get to proper node. 130 133 { char[] verticesId = inputNode.getAttribute("source"); … … 135 138 // Get values 136 139 char[] sourceId = inputNode.getAttribute("source"); 137 inputs[i].data = getDataFromSourceId(sourceId, inputs[i].components); 138 } 139 int[] indices = Xml.parseNumberList!(int)(polyList.getChild("p").value); 140 inputs[i].data = getDataFromSourceId(sourceId, inputs[i].components); 141 } 142 int[] indices; 143 foreach (p; polyList.getChildren("p")) 144 indices ~= Xml.parseNumberList!(int)(p.value); 140 145 int[] vcounts; 141 146 if (polyList.hasChild("vcount")) … … 172 177 float[] data = new float[indices.length*c/indicesPerVertex]; 173 178 for (int i=0; i<indices.length; i+=indicesPerVertex) 174 { int index = indices[i + input.offset]*c; // T ODO: This creates duplicate vertices on shared triangle edges179 { int index = indices[i + input.offset]*c; // This creates duplicate vertices on shared triangle edges, Geometry.optimize takes care of it later 175 180 int j = i/indicesPerVertex*c; 176 181 data[j..j+c] = input.data[index..index+c]; … … 186 191 else 187 192 assert(0); 188 193 189 194 // Flip the y texture coordinate for OpenGL. 190 195 foreach (inout texCoord; cast(Vec2f[])result.getAttribute(Geometry.TEXCOORDS0)) 191 196 texCoord.y = -texCoord.y; 197 192 198 } 199 193 200 194 201 // Build triangles … … 229 236 result.meshes = [mesh]; 230 237 231 if (!calledByGetMerged)232 { result.optimize();233 234 //If phong shading is used, generate binormals.235 if (material.getPass().autoShader == MaterialPass.AutoShader.PHONG)236 result.setAttribute(Geometry.TEXCOORDS1, result.createTangentVectors());237 }238 239 240 238 return result; 241 239 } … … 244 242 245 243 // Merge meshes into a single geometry 246 Geometry result = meshes [0];244 Geometry result = meshes.length ? meshes[0] : null; 247 245 if (meshes.length > 1) 248 result = Geometry.merge(meshes); 246 result = Geometry.merge(meshes); 247 248 if (!calledByGetMerged) 249 { result.optimize(); 250 251 //If phong shading is used, generate binormals. 252 foreach (mesh; result.meshes) 253 if (mesh.material.getPass().autoShader == MaterialPass.AutoShader.PHONG) 254 { result.setAttribute(Geometry.TEXCOORDS1, result.createTangentVectors()); 255 break; 256 } 257 } 249 258 250 259 delete meshes; // garbage from old mesh sub-data 251 geometries[id] = result; // cache for next request 260 geometries[id] = result; // cache for next request 252 261 return result; 253 262 } … … 280 289 MaterialPass pass = result.techniques[0].passes[0]; 281 290 282 Node instanceEffect = Xml.getNodeById(doc, id).getChild("instance_effect"); // TODO: instance_effect can have child nodes that specify parameters 283 Node effectNode = Xml.getNodeById(doc, instanceEffect.getAttribute("url")); 284 Node profileCommon = effectNode.getChild("profile_COMMON"); // TODO: profile_GLSL 285 Node technique = profileCommon.getChild("technique"); 291 Node technique; 292 Node materialNode = Xml.getNodeById(doc, id); 293 if (materialNode.hasChild("instance_effect")) 294 { Node instanceEffect = Xml.getNodeById(doc, id).getChild("instance_effect"); // TODO: instance_effect can have child nodes that specify parameters 295 Node effectNode = Xml.getNodeById(doc, instanceEffect.getAttribute("url")); 296 Node profileCommon = effectNode.getChild("profile_COMMON"); // TODO: profile_GLSL 297 technique = profileCommon.getChild("technique"); 298 } else // Collada 1.3 299 { technique = materialNode.getChild("shader").getChild("technique"); 300 } 286 301 287 302 Node shadingType = technique.getChild(); // in profile_COMMON, it can be newparam, image, blinn, constant, lambert, phong, or extra. … … 312 327 } } 313 328 329 if (!param.getChildren().length) 330 continue; 331 314 332 Node child = param.getChild(); 315 333 GPUTexture texture; … … 323 341 pass.setDiffuseTexture(Texture(texture)); // may be null 324 342 break; 325 case "bump": 343 case "bump": // Bump map extension used by Okino, http://www.okino.com/conv/exp_collada_extensions.htm 326 344 getColorOrTexture(child, pass.diffuse, texture); 327 345 pass.setNormalSpecularTexture(Texture(texture)); // may be null … … 350 368 default: 351 369 break; 352 // TODO: Get normal from extra tag, see: http://www.okino.com/conv/exp_collada_extensions.htm353 370 } 354 371 … … 381 398 { 382 399 Geometry[] geometries; 383 Matrix[] geometryTransforms; 400 Matrix[] geometryTransforms; // A transformation matrix for each geometry found. 384 401 385 402 // Get the up direction (unfinished) … … 391 408 392 409 // Loop through the scenes and load all the geometry nodes they reference. 393 scope Node[] visual_scenes = Node(doc.elements).getChild("library_visual_scenes").getChildren("visual_scene"); 394 395 foreach (visual_scene; visual_scenes) // loop through scenes 410 Node[] scenes; 411 Node root = Node(doc.elements); 412 if (root.hasChild("library_visual_scenes")) 413 scenes = root.getChild("library_visual_scenes").getChildren("visual_scene"); 414 else // collada 1.3 415 scenes = root.getChildren("scene"); 416 417 foreach (visual_scene; scenes) // loop through scenes 396 418 { 397 scope Node[] nodes = visual_scene.getChildren("node"); 398 foreach (node; nodes) // loop through nodes in a scene 419 void traverseSceneNodes(Node node) 399 420 { 400 if (!node.hasChild("instance_geometry")) 401 continue; 402 403 Node instance_geometry = node.getChild("instance_geometry"); 404 405 char[] geometryId = instance_geometry.getAttribute("url"); // TODO: Multiple instance geometry? 406 Geometry geometry = getGeometryById(geometryId, true); 407 408 // Get transformation matrix for this instance of the geometry. 409 Matrix matrix; 410 foreach (transform; node.getChildren()) 411 { if (transform.name=="translate") 412 matrix.setPosition(Vec3f(Xml.parseNumberList!(float)(transform.value))); 413 else if (transform.name=="rotate") 414 { float[] values = Xml.parseNumberList!(float)(transform.value); 415 assert(values.length==4); 416 Vec3f(values[3]*tango.math.Math.PI/180, values[0], values[1], values[2]); // load from axis-angle 417 } 418 else if (transform.name=="scale") 419 matrix.setScalePreservingRotation(Vec3f(Xml.parseNumberList!(float)(transform.value))); 421 Node instance_geometry; 422 if (node.hasChild("instance_geometry")) 423 instance_geometry = node.getChild("instance_geometry"); 424 else if (node.hasChild("instance")) // Collada 1.3 425 instance_geometry = node.getChild("instance"); 426 427 if (instance_geometry.node) 428 { 429 char[] geometryId = instance_geometry.getAttribute("url"); // TODO: Multiple instance geometry? 430 Geometry geometry = getGeometryById(geometryId, true); 431 if (geometry) 432 { 433 // Get transformation matrix for this instance of the geometry. 434 Matrix matrix; 435 foreach (transform; node.getChildren()) 436 { if (transform.name=="translate") 437 matrix.move(Vec3f(Xml.parseNumberList!(float)(transform.value))); 438 else if (transform.name=="rotate") 439 { float[] values = Xml.parseNumberList!(float)(transform.value); 440 assert(values.length==4); 441 matrix = matrix.rotate(Vec3f(values[3]*tango.math.Math.PI/180, values[0], values[1], values[2])); // load from axis-angle 442 } 443 else if (transform.name=="scale") 444 matrix.setScalePreservingRotation(Vec3f(Xml.parseNumberList!(float)(transform.value))); 445 else if (transform.name=="matrix") // collada 1.3 446 { matrix = Matrix(Xml.parseNumberList!(float)(transform.value)); 447 448 } 449 } 450 geometryTransforms ~= matrix * upTransform; 451 452 // TODO: Sometimes intance_geometry has xml children specifying a material (or other things as well?) 453 454 geometries~= geometry; 455 } 420 456 } 421 geometryTransforms ~= matrix * upTransform; 422 423 // TODO: Sometimes intance_geometry has xml children specifying a material (or other things as well?) 424 425 geometries~= geometry; 426 } } 457 458 foreach (child; node.getChildren("node")) // loop through nodes in a scene 459 traverseSceneNodes(child); 460 } 461 462 traverseSceneNodes(visual_scene); 463 } 427 464 428 465 // Transform geometry instances by their transformation matrix … … 446 483 delete geometries; 447 484 448 449 // Timer a = new Timer(true);450 485 //foreach (mesh; result.meshes) 486 // Log.trace(mesh.getTriangles().length); 487 //Log.trace(result.getAttribute(Geometry.VERTICES).length); 451 488 result.optimize(); 452 489 … … 510 547 // See: https://collada.org/mediawiki/index.php/Using_accessors 511 548 private float[] getDataFromSourceId(char[] id, out ushort components) 512 { Node sourceAccesor = Xml.getNodeById(doc, id).getChild("technique_common").getChild("accessor"); // TODO: Read stride, offset, etc. 513 scope Node[] params = sourceAccesor.getChildren("param"); 549 { 550 551 552 Node source = Xml.getNodeById(doc, id); 553 Node sourceAccessor; 554 if (source.hasChild("technique_common")) 555 sourceAccessor = source.getChild("technique_common").getChild("accessor"); // TODO: Read stride, offset, etc. 556 else // collada 1.3 557 sourceAccessor = source.getChild("technique").getChild("accessor"); // TODO: Read stride, offset, etc. 558 scope Node[] params = sourceAccessor.getChildren("param"); 514 559 components = params.length; 515 char[] sourceFloatArrayId = sourceAcces or.getAttribute("source");516 char[] sourceFloatArray = Xml.getNodeById(doc, sourceFloatArrayId).value;517 return Xml.parseNumberList!(float)(sourceFloatArray );560 char[] sourceFloatArrayId = sourceAccessor.getAttribute("source"); 561 Node sourceFloatArray = Xml.getNodeById(doc, sourceFloatArrayId); 562 return Xml.parseNumberList!(float)(sourceFloatArray.value); 518 563 } 519 564 trunk/src/yage/resource/geometry.d
r183 r184 8 8 9 9 import tango.math.Math; 10 import yage.core.format; 10 11 import yage.core.math.vector; 11 12 import yage.resource.manager; … … 255 256 void optimize() 256 257 { 258 debug { 259 int length = getVertexBuffer(Geometry.VERTICES).length; 260 foreach (name, attribute; attributes) 261 { assert(attribute.length == length, format("%s is only of length %s, but vertices are of length %s", name, attribute.length, length)); 262 } 263 264 } 265 257 266 // Merge duplicate vertices 258 267 VertexBuffer vb = attributes[Geometry.VERTICES]; … … 312 321 313 322 // Move data 314 foreach ( inout attribute; attributes)323 foreach (name, inout attribute; attributes) 315 324 { 316 325 int c2 = attribute.components; 317 326 float[] oldData = cast(float[])attribute.data; 318 float[] data = new float[remap.length]; 319 327 float[] data = new float[remapReverse.length*c2]; 320 328 foreach (to, from; remapReverse) // Too bad doing this in-place fails for some models 329 { //Log.trace("%s %s %s %s", data.length, to*c2+c2, oldData.length, from*c2+c2); 321 330 data[to*c2..to*c2+c2] = oldData[from*c2..from*c2+c2]; 331 } 322 332 323 333 attribute.data = data;
