Changeset 185
- Timestamp:
- 06/01/10 00:03:08 (2 years ago)
- Files:
-
- trunk/src/yage/resource/collada.d (modified) (10 diffs)
- trunk/src/yage/resource/model.d (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/yage/resource/collada.d
r184 r185 14 14 import tango.text.xml.DocTester; 15 15 import tango.util.Convert; 16 16 17 import yage.core.array; 17 18 import yage.core.color; … … 25 26 import yage.resource.material; 26 27 import yage.resource.manager; 28 import yage.resource.model; 27 29 import yage.resource.texture; 28 30 import yage.system.log; … … 84 86 { throw new XMLException("Could not parse xml document."); 85 87 } 88 } 89 90 Matrix getBaseTransform() 91 { char[] upAxis = Node(doc.elements).getChild("asset").getChild("up_axis").value(); 92 if (upAxis == "X_UP") // Y is already up 93 return Vec3f(0, -3.1415/2, 0).toMatrix(); 94 if (upAxis == "Z_UP") 95 return Vec3f(-3.1415/2, 0, 0).toMatrix(); 96 return Matrix.IDENTITY; 86 97 } 87 98 … … 297 308 technique = profileCommon.getChild("technique"); 298 309 } else // Collada 1.3 299 { technique = materialNode.getChild("shader").getChild("technique"); 300 } 310 technique = materialNode.getChild("shader").getChild("technique"); 301 311 302 312 Node shadingType = technique.getChild(); // in profile_COMMON, it can be newparam, image, blinn, constant, lambert, phong, or extra. … … 308 318 // else use blinn (gourard) shading from the fixed function pipeline 309 319 320 321 // Helper function for loading material data. 322 void getColorOrTexture(Node n, inout Color color, inout GPUTexture texture) 323 { char[] name = n.name(); 324 switch (name) 325 { case "param": 326 n = Xml.getNodeById(doc, n.getAttribute("ref"), "sid").getChild("float3"); 327 // deliberate fall-through 328 case "color": 329 Color temp = Color(Xml.parseNumberList!(float)(n.value)); 330 color = Color(cast(int)temp.r, cast(int)temp.g, cast(int)temp.b, ((color.a*cast(int)temp.a)/255)); 331 break; 332 case "texture": 333 texture = getTextureById(n.getAttribute("texture")); // TODO getImageByTexture 334 break; 335 default: 336 Log.error("Collada material parameter %s not supported", name); 337 } } 338 310 339 // Loop through and get each material property 311 340 scope Node[] params = shadingType.getChildren(); 312 341 foreach (Node param; params) 313 342 { 314 void getColorOrTexture(Node n, inout Color color, inout GPUTexture texture)315 { char[] name = n.name();316 switch (name)317 { case "param":318 n = Xml.getNodeById(doc, n.getAttribute("ref"), "sid").getChild("float3");319 // deliberate fall-through320 case "color":321 Color temp = Color(Xml.parseNumberList!(float)(n.value));322 color = Color(cast(int)temp.r, cast(int)temp.g, cast(int)temp.b, ((color.a*cast(int)temp.a)/255));323 break;324 case "texture":325 texture = getTextureById(n.getAttribute("texture")); // TODO getImageByTexture326 break;327 } }328 329 343 if (!param.getChildren().length) 330 344 continue; … … 369 383 break; 370 384 } 371 372 // Enable blending if there's alpha. 373 if (pass.blend==MaterialPass.Blend.NONE) 374 if (pass.diffuse.a < 1f || (pass.textures.length && pass.textures[0].texture.getImage().getChannels()==4)) 375 pass.blend = MaterialPass.Blend.AVERAGE; 376 } 377 378 // Create a tecnique that uses no shaders. 385 } 386 387 // Look to see if there's a technique/extra/technique/bump for a bump--fcollada (and maybe also Blender?) puts the bump map here. 388 if (technique.hasChild("extra")) 389 { Node extra = technique.getChild("extra"); 390 if (extra.hasChild("technique")) 391 { Node extraTechnique = extra.getChild("technique"); 392 if (extraTechnique.hasChild("bump")) 393 { GPUTexture texture; 394 getColorOrTexture(extraTechnique.getChild("bump").getChild("texture"), pass.diffuse, texture); 395 pass.setNormalSpecularTexture(Texture(texture)); // may be null 396 } } } 397 398 // Enable blending if there's alpha. 399 if (pass.blend==MaterialPass.Blend.NONE) 400 if (pass.diffuse.a < 1f || (pass.textures.length && pass.textures[0].texture.getImage().getChannels()==4)) 401 pass.blend = MaterialPass.Blend.AVERAGE; 402 403 // Create a fallback technique that uses no shaders. 379 404 if (result.getPass().autoShader == MaterialPass.AutoShader.PHONG) 380 405 { … … 401 426 402 427 // Get the up direction (unfinished) 403 Matrix upTransform; 404 char[] upAxis = Node(doc.elements).getChild("asset").getChild("up_axis").value(); 405 if (upAxis == "Z_UP") 406 upTransform = Vec3f(-3.1415/2, 0, 0).toMatrix(); 407 408 409 // Loop through the scenes and load all the geometry nodes they reference. 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 428 Matrix upTransform = getBaseTransform(); 429 430 foreach (visual_scene; getScenes()) // loop through scenes 418 431 { 419 void traverseSceneNodes(Node node) 432 // Go through the scene nodes and collect anything that can be used as a model. 433 void traverseSceneNodes(Node node, Matrix matrix) 420 434 { 421 Node instance_geometry;422 if (node.hasChild("instance_geometry")) 423 instance_geometry = node.getChild("instance_geometry");435 char[] geometryId; 436 if (node.hasChild("instance_geometry")) // Collada 1.4+ 437 geometryId = node.getChild("instance_geometry").getAttribute("url"); 424 438 else if (node.hasChild("instance")) // Collada 1.3 425 instance_geometry = node.getChild("instance"); 426 427 if (instance_geometry.node) 439 geometryId = node.getChild("instance").getAttribute("url"); 440 else if (node.hasChild("instance_controller")) // A controller for skeletal animation, which we will follow to get it's geometry 441 { Node controller = Xml.getNodeById(doc, node.getChild("instance_controller").getAttribute("url")); 442 Node skin = controller.getChild("skin"); 443 geometryId = skin.getAttribute("source"); 444 } 445 446 if (geometryId.length) 428 447 { 429 char[] geometryId = instance_geometry.getAttribute("url"); // TODO: Multiple instance geometry?430 448 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-angle442 }443 else if (transform.name=="scale")444 matrix.setScalePreservingRotation(Vec3f(Xml.parseNumberList!(float)(transform.value)));445 else if (transform.name=="matrix") // collada 1.3446 { matrix = Matrix(Xml.parseNumberList!(float)(transform.value));447 448 }449 }449 450 // Get transformation matrix for this instance of the geometry. 451 foreach (transform; node.getChildren()) 452 { if (transform.name=="translate") 453 matrix = matrix.move(Vec3f(Xml.parseNumberList!(float)(transform.value))); 454 else if (transform.name=="rotate") 455 { float[] values = Xml.parseNumberList!(float)(transform.value); 456 assert(values.length==4); 457 matrix = matrix.rotate(Vec3f(values[3]*tango.math.Math.PI/180, values[0], values[1], values[2])); // load from axis-angle 458 } 459 else if (transform.name=="scale") 460 matrix.setScalePreservingRotation(Vec3f(Xml.parseNumberList!(float)(transform.value))); 461 else if (transform.name=="matrix") // collada 1.3 462 matrix = Matrix(Xml.parseNumberList!(float)(transform.value)); 463 464 } 465 466 if (geometry) // TODO: Sometimes intance_geometry has xml children specifying a material (or other things as well?) 467 { geometries~= geometry; 450 468 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 469 } 456 470 } 457 471 458 472 foreach (child; node.getChildren("node")) // loop through nodes in a scene 459 traverseSceneNodes(child );473 traverseSceneNodes(child, matrix); 460 474 } 461 475 462 traverseSceneNodes(visual_scene );476 traverseSceneNodes(visual_scene, Matrix.IDENTITY); 463 477 } 464 478 … … 499 513 return result; 500 514 } 515 516 Node[] getScenes() 517 { 518 Node[] scenes; 519 Node root = Node(doc.elements); 520 if (root.hasChild("library_visual_scenes")) 521 scenes = root.getChild("library_visual_scenes").getChildren("visual_scene"); 522 else // collada 1.3 523 scenes = root.getChildren("scene"); 524 return scenes; 525 } 501 526 527 Joint[] getSkeletonById(char[] id) 528 { 529 // Get the up direction (unfinished) 530 Matrix upTransform = getBaseTransform(); 531 532 // Loop through the scenes and load all the geometry nodes they reference. 533 534 535 foreach (scene; getScenes()) // loop through scenes 536 { 537 538 539 } 540 return null; 541 } 542 502 543 /** 503 544 * Get a yage GPUTexture from the Collada file by its id. … … 548 589 private float[] getDataFromSourceId(char[] id, out ushort components) 549 590 { 550 551 552 591 Node source = Xml.getNodeById(doc, id); 553 592 Node sourceAccessor; … … 661 700 try { 662 701 foreach(i, piece; pieces) 663 result[i] = to!(T)(piece); 702 if (piece.length) 703 result[i] = to!(T)(piece); 664 704 } catch (ConversionException e) 665 705 { throw new XmlException(e.toString()); trunk/src/yage/resource/model.d
r175 r185 14 14 import yage.core.math.vector; 15 15 import yage.core.object2; 16 import yage.core.tree; 16 17 import yage.resource.collada; 17 18 import yage.resource.geometry; … … 20 21 import yage.system.log; 21 22 23 /* 22 24 /// 23 25 struct KeyFrame … … 39 41 KeyFrame[] rotations; 40 42 }; 41 43 */ 44 45 class Joint : Tree!(Joint) 46 { 47 Matrix relative; 48 Matrix absolute; 49 } 42 50 43 51 /** … … 51 59 private char[] source; 52 60 61 // Old: 53 62 protected float fps=24; 54 63 protected bool animated = false; 55 64 protected double animation_time=-1; 56 protected double animation_max_time=0; 57 protected Joint[] joints; // used for skeletal animation 58 protected int[] joint_indices; 65 protected double animation_max_time=0; 66 //protected int[] joint_indices; 67 68 protected Joint[] skeleton; // All of the joints that makeup the skeleton. The first Joint is the root. 59 69 60 70 /// Instantiate an empty model. … … 75 85 } 76 86 77 /* *87 /* 78 88 * Advance this Model's animation to time. 79 89 * This still has bugs somehow. 80 90 * Params: 81 91 * time = 82 */83 92 void animateTo(double time) 84 93 { … … 179 188 setAttribute(Geometry.NORMALS, normals); 180 189 } 181 182 /** 183 * Get an array of all of the Model's Joints, which are used for skeletal animation. 184 * This can be traversed as an array, or as a tree since each Joint references its parent and children. */ 185 Joint[] getJoints() 186 { return joints; 187 } 190 */ 188 191 189 192 /**
