use of net.drewke.tdme.math.Matrix4x4 in project tdme by andreasdr.
the class DAEReader method readVisualSceneInstanceController.
/**
* Reads a instance controller
* @param authoring tool
* @param path name
* @param model
* @param parent group
* @param xml root
* @param xml node
* @return Group
* @throws Exception
*/
private static Group readVisualSceneInstanceController(AuthoringTool authoringTool, String pathName, Model model, Group parentGroup, Element xmlRoot, Element xmlNode) throws Exception {
StringTokenizer t;
String xmlNodeId = xmlNode.getAttribute("id");
String xmlNodeName = xmlNode.getAttribute("name");
HashMap<String, String> materialSymbols = new HashMap<String, String>();
// geometry id
String xmlGeometryId = null;
// parse library controllers, find our controller
List<Element> xmlInstanceControllers = getChildrenByTagName(xmlNode, "instance_controller");
Element xmlSkin = null;
Element xmlInstanceController = xmlInstanceControllers.get(0);
// parse material symbols
for (Element xmlBindMaterial : getChildrenByTagName(xmlInstanceController, "bind_material")) for (Element xmlTechniqueCommon : getChildrenByTagName(xmlBindMaterial, "technique_common")) for (Element xmlInstanceMaterial : getChildrenByTagName(xmlTechniqueCommon, "instance_material")) {
materialSymbols.put(xmlInstanceMaterial.getAttribute("symbol"), xmlInstanceMaterial.getAttribute("target"));
}
String xmlInstanceControllerId = xmlInstanceController.getAttribute("url").substring(1);
Element xmlLibraryControllers = getChildrenByTagName(xmlRoot, "library_controllers").get(0);
for (Element xmlLibraryController : getChildrenByTagName(xmlLibraryControllers, "controller")) {
// our controller ?
if (xmlLibraryController.getAttribute("id").equals(xmlInstanceControllerId)) {
// parse skin
List<Element> xmlSkins = getChildrenByTagName(xmlLibraryController, "skin");
if (xmlSkins.isEmpty() == false) {
xmlSkin = xmlSkins.get(0);
}
}
}
// check for xml skin
if (xmlSkin == null) {
throw new ModelFileIOException("skin not found for instance controller " + xmlNodeId);
}
// get geometry id
xmlGeometryId = xmlSkin.getAttribute("source").substring(1);
// parse bind shape matrix
String xmlMatrix = getChildrenByTagName(xmlSkin, "bind_shape_matrix").get(0).getTextContent();
t = new StringTokenizer(xmlMatrix, " \n\r");
//
Matrix4x4 bindShapeMatrix = new Matrix4x4(Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken())).transpose();
// tdme model definitions
Group group = new Group(model, parentGroup, xmlNodeId, xmlNodeName);
// create skinning
Skinning skinning = group.createSkinning();
// parse geometry
readGeometry(authoringTool, pathName, model, group, xmlRoot, xmlGeometryId, materialSymbols);
// parse joints
String xmlJointsSource = null;
String xmlJointsInverseBindMatricesSource = null;
Element xmlJoints = getChildrenByTagName(xmlSkin, "joints").get(0);
for (Element xmlJointsInput : getChildrenByTagName(xmlJoints, "input")) {
if (xmlJointsInput.getAttribute("semantic").equals("JOINT")) {
xmlJointsSource = xmlJointsInput.getAttribute("source").substring(1);
} else if (xmlJointsInput.getAttribute("semantic").equals("INV_BIND_MATRIX")) {
xmlJointsInverseBindMatricesSource = xmlJointsInput.getAttribute("source").substring(1);
}
}
// check for joints sources
if (xmlJointsSource == null) {
throw new ModelFileIOException("joint source not found for instance controller " + xmlNodeId);
}
// parse joint ids
ArrayList<Joint> joints = new ArrayList<Joint>();
for (Element xmlSkinSource : getChildrenByTagName(xmlSkin, "source")) {
if (xmlSkinSource.getAttribute("id").equals(xmlJointsSource)) {
t = new StringTokenizer(getChildrenByTagName(xmlSkinSource, "Name_array").get(0).getTextContent(), " \n\r");
while (t.hasMoreTokens()) {
joints.add(new Joint(t.nextToken()));
}
}
}
skinning.setJoints(joints);
// check for inverse bind matrices source
if (xmlJointsInverseBindMatricesSource == null) {
throw new ModelFileIOException("inverse bind matrices source not found for instance controller " + xmlNodeId);
}
// Create joints bind matrices
for (Element xmlSkinSource : getChildrenByTagName(xmlSkin, "source")) {
if (xmlSkinSource.getAttribute("id").equals(xmlJointsInverseBindMatricesSource)) {
t = new StringTokenizer(getChildrenByTagName(xmlSkinSource, "float_array").get(0).getTextContent(), " \n\r");
Joint[] _joints = skinning.getJoints();
for (int i = 0; i < _joints.length; i++) {
_joints[i].getBindMatrix().multiply(bindShapeMatrix);
_joints[i].getBindMatrix().multiply(// The transformation to the local space of the joint is called the inverse bind matrix
new Matrix4x4(Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken())).transpose());
}
}
}
// read vertex influences
ArrayList<Float> weights = new ArrayList<Float>();
int xmlJointOffset = -1;
int xmlWeightOffset = -1;
String xmlWeightsSource = null;
Element xmlVertexWeights = getChildrenByTagName(xmlSkin, "vertex_weights").get(0);
List<Element> xmlVertexWeightInputs = getChildrenByTagName(xmlVertexWeights, "input");
for (Element xmlVertexWeightInput : xmlVertexWeightInputs) {
if (xmlVertexWeightInput.getAttribute("semantic").equals("JOINT")) {
if (xmlVertexWeightInput.getAttribute("source").substring(1).equals(xmlJointsSource) == false) {
throw new ModelFileIOException("joint inverse bind matrices source do not match");
}
xmlJointOffset = Integer.parseInt(xmlVertexWeightInput.getAttribute("offset"));
} else if (xmlVertexWeightInput.getAttribute("semantic").equals("WEIGHT")) {
xmlWeightOffset = Integer.parseInt(xmlVertexWeightInput.getAttribute("offset"));
xmlWeightsSource = xmlVertexWeightInput.getAttribute("source").substring(1);
}
}
// check for vertex weight parameter
if (xmlJointOffset == -1) {
throw new ModelFileIOException("xml vertex weight joint offset missing for node " + xmlNodeId);
}
if (xmlWeightOffset == -1) {
throw new ModelFileIOException("xml vertex weight weight offset missing for node " + xmlNodeId);
}
if (xmlWeightsSource == null) {
throw new ModelFileIOException("xml vertex weight weight source missing for node " + xmlNodeId);
}
// parse weights
for (Element xmlSkinSource : getChildrenByTagName(xmlSkin, "source")) {
if (xmlSkinSource.getAttribute("id").equals(xmlWeightsSource)) {
t = new StringTokenizer(getChildrenByTagName(xmlSkinSource, "float_array").get(0).getTextContent(), " \n\r");
while (t.hasMoreTokens()) {
weights.add(new Float(Float.parseFloat(t.nextToken())));
}
}
}
skinning.setWeights(weights);
// actually do parse joint influences of each vertex
int xmlVertexWeightInputCount = xmlVertexWeightInputs.size();
String vertexJointsInfluenceCountString = getChildrenByTagName(xmlVertexWeights, "vcount").get(0).getTextContent();
String vertexJointsInfluencesString = getChildrenByTagName(xmlVertexWeights, "v").get(0).getTextContent();
t = new StringTokenizer(vertexJointsInfluenceCountString, " \n\r");
StringTokenizer t2 = new StringTokenizer(vertexJointsInfluencesString, " \n\r");
int offset = 0;
ArrayList<ArrayList<JointWeight>> verticesJointsWeights = new ArrayList<ArrayList<JointWeight>>();
while (t.hasMoreTokens()) {
// read joint influences for current vertex
int vertexJointsInfluencesCount = Integer.parseInt(t.nextToken());
ArrayList<JointWeight> vertexJointsWeights = new ArrayList<JointWeight>();
for (int i = 0; i < vertexJointsInfluencesCount; i++) {
int vertexJoint = -1;
int vertexWeight = -1;
while (vertexJoint == -1 || vertexWeight == -1) {
int value = Integer.parseInt(t2.nextToken());
if (offset % xmlVertexWeightInputCount == xmlJointOffset) {
vertexJoint = value;
} else if (offset % xmlVertexWeightInputCount == xmlWeightOffset) {
vertexWeight = value;
}
offset++;
}
vertexJointsWeights.add(new JointWeight(vertexJoint, vertexWeight));
}
verticesJointsWeights.add(vertexJointsWeights);
}
skinning.setVerticesJointsWeights(verticesJointsWeights);
return group;
}
Aggregations