use of org.terasology.math.geom.Quat4f in project Terasology by MovingBlocks.
the class Bone method getLocalRotation.
public Quat4f getLocalRotation() {
Quat4f rot = new Quat4f(rotation);
if (parent != null) {
Quat4f inverseParentRot = new Quat4f();
inverseParentRot.inverse(parent.getObjectRotation());
rot.mul(inverseParentRot, rot);
}
return rot;
}
use of org.terasology.math.geom.Quat4f in project Terasology by MovingBlocks.
the class SkeletalMeshData method toMD5.
/**
* Outputs the skeletal mesh as md5mesh file
*/
public String toMD5(String shader) {
StringBuilder sb = new StringBuilder();
sb.append("MD5Version 10\n" + "commandline \"Exported from Terasology MD5SkeletonLoader\"\n" + "\n");
sb.append("numJoints ").append(bones.size()).append("\n");
sb.append("numMeshes 1\n\n");
sb.append("joints {\n");
for (Bone bone : bones) {
sb.append("\t\"").append(bone.getName()).append("\" ").append(bone.getParentIndex()).append(" ( ");
sb.append(bone.getObjectPosition().x).append(" ");
sb.append(bone.getObjectPosition().y).append(" ");
sb.append(bone.getObjectPosition().z).append(" ) ( ");
Quat4f rot = new Quat4f(bone.getObjectRotation());
rot.normalize();
if (rot.w > 0) {
rot.x = -rot.x;
rot.y = -rot.y;
rot.z = -rot.z;
}
sb.append(rot.x).append(" ");
sb.append(rot.y).append(" ");
sb.append(rot.z).append(" )\n");
}
sb.append("}\n\n");
sb.append("mesh {\n");
sb.append("\tshader \"" + shader + "\"\n");
sb.append("\tnumverts ").append(uvs.size()).append("\n");
for (int i = 0; i < uvs.size(); i++) {
sb.append("\tvert ").append(i).append(" (").append(uvs.get(i).x).append(" ").append(uvs.get(i).y).append(") ");
sb.append(vertexStartWeights.get(i)).append(" ").append(vertexWeightCounts.get(i)).append("\n");
}
sb.append("\n");
sb.append("\tnumtris ").append(indices.size() / 3).append("\n");
for (int i = 0; i < indices.size() / 3; i++) {
int i1 = indices.get(i * 3);
int i2 = indices.get(i * 3 + 1);
int i3 = indices.get(i * 3 + 2);
sb.append("\ttri ").append(i).append(" ").append(i1).append(" ").append(i2).append(" ").append(i3).append("\n");
}
sb.append("\n");
sb.append("\tnumweights ").append(weights.size()).append("\n");
int meshId = 0;
for (BoneWeight weight : weights) {
sb.append("\tweight ").append(meshId).append(" ").append(weight.getBoneIndex()).append(" ");
sb.append(weight.getBias()).append(" ( ");
sb.append(weight.getPosition().x).append(" ").append(weight.getPosition().y).append(" ").append(weight.getPosition().z).append(")\n");
meshId++;
}
sb.append("}\n");
return sb.toString();
}
use of org.terasology.math.geom.Quat4f in project Terasology by MovingBlocks.
the class SkeletalMeshData method calculateNormals.
private void calculateNormals() {
// TODO: Better algorithm (take into account triangle size and angles
List<Vector3f> vertices = getBindPoseVertexPositions();
List<Vector3f> normals = Lists.newArrayListWithCapacity(vertices.size());
for (int i = 0; i < vertices.size(); ++i) {
normals.add(new Vector3f());
}
Vector3f v1 = new Vector3f();
Vector3f v2 = new Vector3f();
Vector3f norm = new Vector3f();
for (int i = 0; i < indices.size() / 3; ++i) {
Vector3f baseVert = vertices.get(indices.get(i * 3));
v1.sub(vertices.get(indices.get(i * 3 + 1)), baseVert);
v2.sub(vertices.get(indices.get(i * 3 + 2)), baseVert);
v1.normalize();
v2.normalize();
norm.cross(v1, v2);
normals.get(indices.get(i * 3)).add(norm);
normals.get(indices.get(i * 3 + 1)).add(norm);
normals.get(indices.get(i * 3 + 2)).add(norm);
}
normals.forEach(Vector3f::normalize);
Quat4f inverseRot = new Quat4f();
for (int vertIndex = 0; vertIndex < vertices.size(); ++vertIndex) {
Vector3f normal = normals.get(vertIndex);
for (int weightIndex = 0; weightIndex < vertexWeightCounts.get(vertIndex); ++weightIndex) {
BoneWeight weight = weights.get(weightIndex + vertexStartWeights.get(vertIndex));
inverseRot.inverse(bones.get(weight.getBoneIndex()).getObjectRotation());
inverseRot.rotate(normal, norm);
weight.setNormal(norm);
}
}
}
use of org.terasology.math.geom.Quat4f in project Terasology by MovingBlocks.
the class ColladaLoader method quad4fArrayFromFloat16ArrayData.
private Quat4f[] quad4fArrayFromFloat16ArrayData(float[] inverseBindMatrixArray) {
Quat4f[] rotationArray = new Quat4f[inverseBindMatrixArray.length / 16];
for (int i = 0; i < inverseBindMatrixArray.length / 16; ++i) {
int offset = i * 16;
Matrix4f matrix4f = new Matrix4f(Arrays.copyOfRange(inverseBindMatrixArray, offset, offset + 16));
Quat4f rotation = new Quat4f();
rotation.set(matrix4f);
rotationArray[i] = rotation;
}
return rotationArray;
}
use of org.terasology.math.geom.Quat4f in project Terasology by MovingBlocks.
the class ColladaLoader method createMD5Joint.
private MD5Joint createMD5Joint(Element jointNodeElement) throws ColladaParseException {
MD5Joint md5Joint = new MD5Joint();
ElementSet matrixSet = jointNodeElement.find("matrix");
if (1 == matrixSet.size()) {
Element matrix = matrixSet.first();
String floatStringArray = matrix.text();
String[] floatStrings = getItemsInString(floatStringArray);
if (floatStrings.length != 16) {
throw new ColladaParseException("Found float list of " + floatStrings.length + " instead of 16 for joint matrix sets for element " + jointNodeElement.id());
}
float[] matrixDataArray = new float[16];
for (int i = 0; i < floatStrings.length; i++) {
String floatString = floatStrings[i];
matrixDataArray[i] = Float.parseFloat(floatString);
}
Quat4f[] jointMatrix = quad4fArrayFromFloat16ArrayData(matrixDataArray);
Vector3f[] positionVectorArray = positionFromFloat16ArrayData(matrixDataArray);
md5Joint.position = positionVectorArray[0];
md5Joint.orientation = jointMatrix[0];
} else if (1 < matrixSet.size()) {
throw new ColladaParseException("Found " + matrixSet.size() + " joint matrix sets for element " + jointNodeElement.id());
// } else {
// TODO: Might be translation, rotation pairs instead of a matrix
// Or might be an unused joint node
// throw new ColladaParseException("Found " + matrixSet.size() + " joint matrix sets for element " + jointNodeElement.id());
}
// boolean isJointNode;
// String jointType = jointNodeElement.attr("type");
// if ("JOINT".equals(jointType)) {
// isJointNode = true;
// } else if ("NODE".equals(jointType)) {
// isJointNode = false;
// } else {
// throw new ColladaParseException("Found unknown node type of " + jointType + " for joint matrix sets" + errorLocation);
// }
md5Joint.element = jointNodeElement;
md5Joint.name = jointNodeElement.id();
md5Joint.childList = new ArrayList<>();
return md5Joint;
}
Aggregations