use of net.drewke.tdme.engine.model.Face 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;
}
use of net.drewke.tdme.engine.model.Face in project tdme by andreasdr.
the class PrimitiveModel method createSphereModel.
/**
* Creates a model from oriented bounding box
* @param sphere
* @param id
* @param number of x segments
* @param number of y segments
* @return model
*/
public static Model createSphereModel(Sphere sphere, String id, int segmentsX, int segmentsY) {
// sphere properties
float radius = sphere.radius;
Vector3 center = sphere.center;
// 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 + 1) * segmentsX; i++) vertices.add(null);
for (int ySegment = 0; ySegment <= segmentsY; ySegment++) for (int xSegment = 0; xSegment < segmentsX; xSegment++) {
Vector3 vertex = 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))).scale(radius).add(center);
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; 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;
}
use of net.drewke.tdme.engine.model.Face in project tdme by andreasdr.
the class TMReader method readFacesEntities.
/**
* Read faces entities from input stream
* @param input stream
* @param group
* @throws IOException
* @throws ModelIOException
*/
private static void readFacesEntities(InputStream is, Group g) throws IOException, ModelFileIOException {
FacesEntity[] facesEntities = new FacesEntity[readInt(is)];
for (int i = 0; i < facesEntities.length; i++) {
facesEntities[i] = new FacesEntity(g, readString(is));
if (readBoolean(is) == true) {
facesEntities[i].setMaterial(g.getModel().getMaterials().get(readString(is)));
}
Face[] faces = new Face[readInt(is)];
for (int j = 0; j < faces.length; j++) {
int[] vertexIndices = readIndices(is);
int[] normalIndices = readIndices(is);
faces[j] = new Face(g, vertexIndices[0], vertexIndices[1], vertexIndices[2], normalIndices[0], normalIndices[1], normalIndices[2]);
int[] textureCoordinateIndices = readIndices(is);
if (textureCoordinateIndices != null && textureCoordinateIndices.length > 0) {
faces[j].setTextureCoordinateIndices(textureCoordinateIndices[0], textureCoordinateIndices[1], textureCoordinateIndices[2]);
}
int[] tangentIndices = readIndices(is);
int[] bitangentIndices = readIndices(is);
if (tangentIndices != null && tangentIndices.length > 0 && bitangentIndices != null && bitangentIndices.length > 0) {
faces[j].setTangentIndices(tangentIndices[0], tangentIndices[1], tangentIndices[2]);
faces[j].setBitangentIndices(bitangentIndices[0], bitangentIndices[1], bitangentIndices[2]);
}
}
facesEntities[i].setFaces(faces);
}
g.setFacesEntities(facesEntities);
}
use of net.drewke.tdme.engine.model.Face in project tdme by andreasdr.
the class WFObjReader method read.
/**
* Reads a wave front object file
* @param path name
* @param file name
* @return model
* @throws IOException
* @throws ModelIOException
*/
public static Model read(String pathName, String fileName) throws IOException, ModelFileIOException {
// create object
Model model = new Model(pathName + File.separator + fileName, fileName, UpVector.Y_UP, RotationOrder.XYZ, null);
ArrayList<Vector3> vertices = new ArrayList<Vector3>();
ArrayList<TextureCoordinate> textureCoordinates = new ArrayList<TextureCoordinate>();
HashMap<String, Material> materials = model.getMaterials();
HashMap<String, Group> subGroups = model.getSubGroups();
HashMap<String, Group> groups = model.getGroups();
// current group
Group group = null;
// model vertices -> group vertices mapping
HashMap<Integer, Integer> modelGroupVerticesMapping = null;
// model texture coordinates -> group texture coordinates mapping
HashMap<Integer, Integer> modelGroupTextureCoordinatesMapping = null;
// current group data
ArrayList<Face> groupFacesEntityFaces = null;
ArrayList<Vector3> groupVertices = null;
ArrayList<Vector3> groupNormals = null;
ArrayList<TextureCoordinate> groupTextureCoordinates = null;
// current group's faces entity
ArrayList<FacesEntity> groupFacesEntities = null;
FacesEntity groupFacesEntity = null;
//
DataInputStream inputStream = new DataInputStream(FileSystem.getInstance().getInputStream(pathName, fileName));
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
//
try {
//
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
// skip on comments
if (line.startsWith("#")) {
continue;
}
// determine index of first ' ' which will separate command from arguments
int commandEndIdx = line.indexOf(' ');
if (commandEndIdx == -1)
commandEndIdx = line.length();
// determine command
String command = line.substring(0, commandEndIdx).trim().toLowerCase();
// determine arguments if any exist
String arguments = command.length() + 1 > line.length() ? "" : line.substring(command.length() + 1);
// parse
if (command.equals("mtllib")) {
String materialFileName = arguments;
materials = WFObjReader.readMaterials(pathName, materialFileName);
} else if (command.equals("v")) {
StringTokenizer t = new StringTokenizer(arguments, " ");
float x = Float.parseFloat(t.nextToken());
float y = Float.parseFloat(t.nextToken());
float z = Float.parseFloat(t.nextToken());
// add vertex
vertices.add(new Vector3(x, y, z));
} else if (command.equals("vt")) {
StringTokenizer t = new StringTokenizer(arguments, " ");
float u = Float.parseFloat(t.nextToken());
float v = Float.parseFloat(t.nextToken());
textureCoordinates.add(new TextureCoordinate(u, v));
} else if (command.equals("f")) {
StringTokenizer t2;
StringTokenizer t = new StringTokenizer(arguments, " ");
int v0 = -1;
int v1 = -1;
int v2 = -1;
int vt0 = -1;
int vt1 = -1;
int vt2 = -1;
// parse vertex index 0, vertex texture index 0
t2 = new StringTokenizer(t.nextToken(), "/");
v0 = Integer.parseInt(t2.nextToken()) - 1;
if (t2.hasMoreTokens()) {
vt0 = Integer.parseInt(t2.nextToken()) - 1;
}
// parse vertex index 1, vertex texture index 1
t2 = new StringTokenizer(t.nextToken(), "/");
v1 = Integer.parseInt(t2.nextToken()) - 1;
if (t2.hasMoreTokens()) {
vt1 = Integer.parseInt(t2.nextToken()) - 1;
}
// parse vertex index 2, vertex texture index 2
t2 = new StringTokenizer(t.nextToken(), "/");
v2 = Integer.parseInt(t2.nextToken()) - 1;
if (t2.hasMoreTokens()) {
vt2 = Integer.parseInt(t2.nextToken()) - 1;
}
// check if triangulated
if (t.hasMoreTokens()) {
throw new ModelFileIOException("We only support triangulated meshes");
}
Integer mappedVertex = null;
// map v0 to group
mappedVertex = modelGroupVerticesMapping.get(v0);
if (mappedVertex == null) {
groupVertices.add(vertices.get(v0).clone());
v0 = groupVertices.size() - 1;
} else {
v0 = mappedVertex.intValue();
}
// map v1 to group
mappedVertex = modelGroupVerticesMapping.get(v1);
if (mappedVertex == null) {
groupVertices.add(vertices.get(v1).clone());
v1 = groupVertices.size() - 1;
} else {
v1 = mappedVertex.intValue();
}
// map v2 to group
mappedVertex = modelGroupVerticesMapping.get(v2);
if (mappedVertex == null) {
groupVertices.add(vertices.get(v2).clone());
v2 = groupVertices.size() - 1;
} else {
v2 = mappedVertex.intValue();
}
//
Integer mappedTextureCoordinate = null;
// map vt0 to group
mappedTextureCoordinate = modelGroupTextureCoordinatesMapping.get(vt0);
if (mappedTextureCoordinate == null) {
groupTextureCoordinates.add(textureCoordinates.get(vt0).clone());
vt0 = groupTextureCoordinates.size() - 1;
} else {
vt0 = mappedTextureCoordinate.intValue();
}
// map vt1 to group
mappedTextureCoordinate = modelGroupTextureCoordinatesMapping.get(vt1);
if (mappedTextureCoordinate == null) {
groupTextureCoordinates.add(textureCoordinates.get(vt1).clone());
vt1 = groupTextureCoordinates.size() - 1;
} else {
vt1 = mappedTextureCoordinate.intValue();
}
// map vt2 to group
mappedTextureCoordinate = modelGroupTextureCoordinatesMapping.get(vt2);
if (mappedTextureCoordinate == null) {
groupTextureCoordinates.add(textureCoordinates.get(vt2).clone());
vt2 = groupTextureCoordinates.size() - 1;
} else {
vt2 = mappedTextureCoordinate.intValue();
}
// compute vertex normal
Vector3[] faceVertexNormals = ModelHelper.computeNormals(new Vector3[] { groupVertices.get(v0), groupVertices.get(v1), groupVertices.get(v2) });
// store group normals
int n0 = groupNormals.size();
groupNormals.add(faceVertexNormals[0]);
int n1 = groupNormals.size();
groupNormals.add(faceVertexNormals[1]);
int n2 = groupNormals.size();
groupNormals.add(faceVertexNormals[2]);
// create face with vertex indices
// we only support triangulated faces
Face face = new Face(group, v0, v1, v2, n0, n1, n2);
if (vt0 != -1 && vt1 != -1 && vt2 != -1) {
// set optional texture coordinate index
face.setTextureCoordinateIndices(vt0, vt1, vt2);
}
groupFacesEntityFaces.add(face);
} else if (command.equals("g")) {
if (group != null) {
// current faces entity
if (groupFacesEntityFaces.isEmpty() == false) {
groupFacesEntity.setFaces(groupFacesEntityFaces);
groupFacesEntities.add(groupFacesEntity);
}
// group
group.setVertices(groupVertices);
group.setNormals(groupNormals);
group.setTextureCoordinates(groupTextureCoordinates);
group.setFacesEntities(groupFacesEntities);
group.determineFeatures();
}
StringTokenizer t = new StringTokenizer(arguments, " ");
String name = t.nextToken();
groupVertices = new ArrayList<Vector3>();
groupNormals = new ArrayList<Vector3>();
groupTextureCoordinates = new ArrayList<TextureCoordinate>();
groupFacesEntityFaces = new ArrayList<Face>();
group = new Group(model, null, name, name);
groupFacesEntity = new FacesEntity(group, name);
groupFacesEntities = new ArrayList<FacesEntity>();
modelGroupVerticesMapping = new HashMap<Integer, Integer>();
modelGroupTextureCoordinatesMapping = new HashMap<Integer, Integer>();
subGroups.put(name, group);
groups.put(name, group);
} else if (command.equals("usemtl")) {
if (group != null) {
// current faces entity
if (groupFacesEntityFaces.isEmpty() == false) {
groupFacesEntity.setFaces(groupFacesEntityFaces);
groupFacesEntities.add(groupFacesEntity);
}
// set up new one
groupFacesEntity = new FacesEntity(group, "#" + groupFacesEntities.size());
groupFacesEntityFaces = new ArrayList<Face>();
}
groupFacesEntity.setMaterial(materials.get(arguments));
} else {
// not supported
}
}
// finish last group
if (group != null) {
// current faces entity
if (groupFacesEntityFaces.isEmpty() == false) {
groupFacesEntity.setFaces(groupFacesEntityFaces);
groupFacesEntities.add(groupFacesEntity);
}
// group
group.setVertices(groupVertices);
group.setNormals(groupNormals);
group.setTextureCoordinates(groupTextureCoordinates);
group.setFacesEntities(groupFacesEntities);
group.determineFeatures();
}
} finally {
// close resouces
reader.close();
inputStream.close();
}
// prepare for indexed rendering
ModelHelper.prepareForIndexedRendering(model);
//
return model;
}
use of net.drewke.tdme.engine.model.Face in project tdme by andreasdr.
the class EngineTest method createWallModel.
/**
* Create wall model
* @return
*/
private Model createWallModel() {
// wall model
Model wall = new Model("wall", "wall", UpVector.Y_UP, RotationOrder.XYZ, null);
// wall material
Material wallMaterial = new Material("wall");
wall.getMaterials().put("wall", wallMaterial);
// group
Group wallGroup = new Group(wall, null, "wall", "wall");
// faces entity
// far plane
FacesEntity groupFacesEntityFarPlane = new FacesEntity(wallGroup, "wall");
wallMaterial.getAmbientColor().set(1f, 1f, 1f, 1f);
wallMaterial.getDiffuseColor().set(1f, 1f, 1f, 1f);
groupFacesEntityFarPlane.setMaterial(wallMaterial);
// faces entity
ArrayList<FacesEntity> groupFacesEntities = new ArrayList<FacesEntity>();
groupFacesEntities.add(groupFacesEntityFarPlane);
// vertices
ArrayList<Vector3> vertices = new ArrayList<Vector3>();
// left, near, far plane
vertices.add(new Vector3(-4f, 0f, +4f));
// left, far, far plane
vertices.add(new Vector3(-4f, +4f, +4f));
// right far, far plane
vertices.add(new Vector3(+4f, +4f, +4f));
// right, near, far plane
vertices.add(new Vector3(+4f, 0f, +4f));
// normals
ArrayList<Vector3> normals = new ArrayList<Vector3>();
// far plane
normals.add(new Vector3(0f, 0f, -1f));
// texture coordinates
ArrayList<TextureCoordinate> textureCoordinates = new ArrayList<TextureCoordinate>();
textureCoordinates.add(new TextureCoordinate(0f, 0f));
textureCoordinates.add(new TextureCoordinate(0f, 1f));
textureCoordinates.add(new TextureCoordinate(1f, 1f));
textureCoordinates.add(new TextureCoordinate(1f, 0f));
// faces ground far plane
ArrayList<Face> facesFarPlane = new ArrayList<Face>();
facesFarPlane.add(new Face(wallGroup, 0, 1, 2, 0, 0, 0, 0, 1, 2));
facesFarPlane.add(new Face(wallGroup, 2, 3, 0, 0, 0, 0, 2, 3, 0));
// set up faces entity
groupFacesEntityFarPlane.setFaces(facesFarPlane);
// setup ground group
wallGroup.setVertices(vertices);
wallGroup.setNormals(normals);
wallGroup.setTextureCoordinates(textureCoordinates);
wallGroup.setFacesEntities(groupFacesEntities);
// determine features
wallGroup.determineFeatures();
// register group
wall.getGroups().put("wall", wallGroup);
wall.getSubGroups().put("wall", wallGroup);
// prepare for indexed rendering
ModelHelper.prepareForIndexedRendering(wall);
//
return wall;
}
Aggregations