source: OniSplit/Totoro/BodyDaeReader.cs

Last change on this file was 1114, checked in by iritscen, 5 years ago

Adding OniSplit source code (v0.9.99.0). Many thanks to Neo for all his work over the years.

File size: 3.3 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.IO;
4
5namespace Oni.Totoro
6{
7 internal class BodyDaeReader
8 {
9 private Body body;
10 private float shellOffset = 0.07f;
11 private bool generateNormals;
12 private bool flatNormals;
13
14 private BodyDaeReader()
15 {
16 }
17
18 public static Body Read(Dae.Scene scene)
19 {
20 var reader = new BodyDaeReader
21 {
22 body = new Body()
23 };
24
25 reader.ReadBodyParts(scene);
26 return reader.body;
27 }
28
29 public static Body Read(Dae.Scene scene, bool generateNormals, bool flatNormals, float shellOffset)
30 {
31 var reader = new BodyDaeReader
32 {
33 body = new Body(),
34 flatNormals = flatNormals,
35 generateNormals = generateNormals,
36 shellOffset = shellOffset
37 };
38
39 reader.ReadBodyParts(scene);
40 return reader.body;
41 }
42
43 private void ReadBodyParts(Dae.Scene scene)
44 {
45 var rootBodyNode = FindRootNode(scene);
46
47 if (rootBodyNode == null)
48 throw new InvalidDataException("The scene does not contain any geometry nodes.");
49
50 //
51 // Make sure the pelvis is not translated from origin.
52 //
53
54 rootBodyNode.Translation = Vector3.Zero;
55
56 if (body.Nodes.Count != 19)
57 Console.Error.WriteLine("Non standard bone count: {0}", body.Nodes.Count);
58 }
59
60 private BodyNode FindRootNode(Dae.Node daeNode)
61 {
62 if (daeNode.GeometryInstances.Any())
63 return ReadNode(daeNode, null);
64
65 foreach (var childDaeNode in daeNode.Nodes)
66 {
67 var bodyNode = FindRootNode(childDaeNode);
68
69 if (bodyNode != null)
70 return bodyNode;
71 }
72
73 return null;
74 }
75
76 private BodyNode ReadNode(Dae.Node daeNode, BodyNode parentNode)
77 {
78 var bodyNode = new BodyNode
79 {
80 DaeNode = daeNode,
81 Parent = parentNode,
82 Index = body.Nodes.Count
83 };
84
85 body.Nodes.Add(bodyNode);
86
87 //
88 // Find and read the geometry for this node
89 //
90
91 foreach (var geometryInstance in daeNode.GeometryInstances.Where(n => n.Target != null))
92 {
93 var daeGeometry = geometryInstance.Target;
94
95 if (bodyNode.Geometry != null)
96 Console.Error.WriteLine("The node {0} contains more than one geometry. Only the first geometry will be used.", daeGeometry.Name);
97
98 bodyNode.Geometry = Motoko.GeometryDaeReader.Read(daeGeometry, generateNormals, flatNormals, shellOffset);
99 }
100
101 //
102 // Extract the translation part of this node's transform
103 //
104
105 bodyNode.Translation = daeNode.Transforms.ToMatrix().Translation;
106
107 //
108 // Read child nodes
109 //
110
111 foreach (var daeChildNode in daeNode.Nodes)
112 bodyNode.Nodes.Add(ReadNode(daeChildNode, parentNode));
113
114 return bodyNode;
115 }
116 }
117}
Note: See TracBrowser for help on using the repository browser.