use of net.drewke.tdme.math.Quaternion in project tdme by andreasdr.
the class PrimitiveModel method createCapsuleModel.
/**
* Creates a model from capsule
* @param sphere
* @param id
* @param number of x segments
* @param number of y segments
* @return model
*/
public static Model createCapsuleModel(Capsule capsule, String id, int segmentsX, int segmentsY) {
// capsule properties
float radius = capsule.radius;
Vector3 a = capsule.a;
Vector3 b = capsule.b;
// rotation quaternion
Quaternion rotationQuaternion = new Quaternion();
rotationQuaternion.identity();
// angle between a and b
Vector3 yAxis = new Vector3(0f, -1f, 0f);
Vector3 abNormalized = a.clone().sub(b).normalize();
float[] abNormalizedVectorXYZ = abNormalized.getArray();
Vector3 rotationAxis;
if (Math.abs(abNormalizedVectorXYZ[0]) < MathTools.EPSILON && Math.abs(abNormalizedVectorXYZ[2]) < MathTools.EPSILON) {
rotationAxis = new Vector3(abNormalizedVectorXYZ[1], 0f, 0f);
} else {
rotationAxis = Vector3.computeCrossProduct(yAxis, abNormalized).normalize();
}
float angle = Vector3.computeAngle(yAxis, abNormalized, yAxis);
rotationQuaternion.rotate(angle, rotationAxis);
// ground model
Model model = new Model(id, id, UpVector.Y_UP, RotationOrder.XYZ, null);
// material
Material material = new Material("tdme.primitive.material");
material.getAmbientColor().set(0.5f, 0.5f, 0.5f, 1.0f);
material.getDiffuseColor().set(1.0f, 0.5f, 0.5f, 0.5f);
material.getSpecularColor().set(0f, 0f, 0f, 1f);
model.getMaterials().put(material.getId(), material);
// group
Group group = new Group(model, null, "group", "group");
// faces entity
FacesEntity groupFacesEntity = new FacesEntity(group, "faces entity");
groupFacesEntity.setMaterial(material);
// faces entity
ArrayList<FacesEntity> groupFacesEntities = new ArrayList<FacesEntity>();
groupFacesEntities.add(groupFacesEntity);
// vertices
ArrayList<Vector3> vertices = new ArrayList<Vector3>();
for (int i = 0; i < (segmentsY + 2) * segmentsX; i++) vertices.add(null);
// top half sphere
for (int ySegment = segmentsY / 2; ySegment <= segmentsY; ySegment++) for (int xSegment = 0; xSegment < segmentsX; xSegment++) {
Vector3 vertex = new Vector3();
rotationQuaternion.multiply(new Vector3((float) (Math.sin(Math.PI * ySegment / segmentsY) * Math.cos(Math.PI * 2 * xSegment / segmentsX)), (float) (Math.cos(Math.PI * ySegment / segmentsY)), (float) (Math.sin(Math.PI * ySegment / segmentsY) * Math.sin(Math.PI * 2 * xSegment / segmentsX))), vertex);
vertex.scale(radius);
vertex.add(a);
vertices.set(ySegment * segmentsX + xSegment, vertex);
}
// bottom half sphere
for (int i = 0; i < (segmentsY + 1) * segmentsX; i++) vertices.add(null);
for (int ySegment = 0; ySegment <= segmentsY / 2; ySegment++) for (int xSegment = 0; xSegment < segmentsX; xSegment++) {
Vector3 vertex = new Vector3();
rotationQuaternion.multiply(new Vector3((float) (Math.sin(Math.PI * ySegment / segmentsY) * Math.cos(Math.PI * 2 * xSegment / segmentsX)), (float) (Math.cos(Math.PI * ySegment / segmentsY)), (float) (Math.sin(Math.PI * ySegment / segmentsY) * Math.sin(Math.PI * 2 * xSegment / segmentsX))), vertex);
vertex.scale(radius);
vertex.add(b);
vertices.set(ySegment * segmentsX + xSegment, vertex);
}
// normals
ArrayList<Vector3> normals = new ArrayList<Vector3>();
// faces
ArrayList<Face> faces = new ArrayList<Face>();
int vi0, vi1, vi2;
int ni;
for (int y = 0; y <= segmentsY + 1; y++) {
for (int x = 0; x < segmentsX; x++) {
vi0 = ((y + 0) % (segmentsY + 1)) * segmentsX + ((x + 0) % (segmentsX));
vi1 = ((y + 1) % (segmentsY + 1)) * segmentsX + ((x + 1) % (segmentsX));
vi2 = ((y + 1) % (segmentsY + 1)) * segmentsX + ((x + 0) % (segmentsX));
ni = normals.size();
for (Vector3 normal : ModelHelper.computeNormals(new Vector3[] { vertices.get(vi0), vertices.get(vi1), vertices.get(vi2) })) {
normals.add(normal);
}
faces.add(new Face(group, vi0, vi1, vi2, ni + 0, ni + 1, ni + 2));
vi0 = ((y + 0) % (segmentsY + 1)) * segmentsX + ((x + 0) % (segmentsX));
vi1 = ((y + 0) % (segmentsY + 1)) * segmentsX + ((x + 1) % (segmentsX));
vi2 = ((y + 1) % (segmentsY + 1)) * segmentsX + ((x + 1) % (segmentsX));
ni = normals.size();
for (Vector3 normal : ModelHelper.computeNormals(new Vector3[] { vertices.get(vi0), vertices.get(vi1), vertices.get(vi2) })) {
normals.add(normal);
}
faces.add(new Face(group, vi0, vi1, vi2, ni + 0, ni + 1, ni + 2));
}
}
// set up faces entity
groupFacesEntity.setFaces(faces);
// setup group vertex data
group.setVertices(vertices);
group.setNormals(normals);
group.setFacesEntities(groupFacesEntities);
// determine features
group.determineFeatures();
// register group
model.getGroups().put("group", group);
model.getSubGroups().put("group", group);
// prepare for indexed rendering
ModelHelper.prepareForIndexedRendering(model);
//
return model;
}
Aggregations