use of net.drewke.tdme.engine.model.Group in project tdme by andreasdr.
the class Tools method createGroundModel.
/**
* Creates a ground plate
* @param width
* @param depth
* @param float y
* @return ground model
*/
public static Model createGroundModel(float width, float depth, float y) {
// ground model
Model ground = new Model("ground", "ground", UpVector.Y_UP, RotationOrder.XYZ, null);
// material
Material groundMaterial = new Material("ground");
groundMaterial.getSpecularColor().set(0f, 0f, 0f, 1f);
ground.getMaterials().put("ground", groundMaterial);
// group
Group groundGroup = new Group(ground, null, "ground", "ground");
// faces entity
// ground
FacesEntity groupFacesEntityGround = new FacesEntity(groundGroup, "ground group faces entity ground");
groupFacesEntityGround.setMaterial(groundMaterial);
// faces entity
ArrayList<FacesEntity> groupFacesEntities = new ArrayList<FacesEntity>();
groupFacesEntities.add(groupFacesEntityGround);
// vertices
ArrayList<Vector3> groundVertices = new ArrayList<Vector3>();
// left, near, ground
groundVertices.add(new Vector3(-width, y, -depth));
// left, far, ground
groundVertices.add(new Vector3(-width, y, +depth));
// right far, ground
groundVertices.add(new Vector3(+width, y, +depth));
// right, near, ground
groundVertices.add(new Vector3(+width, y, -depth));
// normals
ArrayList<Vector3> groundNormals = new ArrayList<Vector3>();
// ground
groundNormals.add(new Vector3(0f, 1f, 0f));
// texture coordinates
ArrayList<TextureCoordinate> groundTextureCoordinates = new ArrayList<TextureCoordinate>();
groundTextureCoordinates.add(new TextureCoordinate(0f, 0f));
groundTextureCoordinates.add(new TextureCoordinate(0f, 1f));
groundTextureCoordinates.add(new TextureCoordinate(1f, 1f));
groundTextureCoordinates.add(new TextureCoordinate(1f, 0f));
// faces ground
ArrayList<Face> groundFacesGround = new ArrayList<Face>();
groundFacesGround.add(new Face(groundGroup, 0, 1, 2, 0, 0, 0, 0, 1, 2));
groundFacesGround.add(new Face(groundGroup, 2, 3, 0, 0, 0, 0, 2, 3, 0));
// set up faces entity
groupFacesEntityGround.setFaces(groundFacesGround);
// setup ground group
groundGroup.setVertices(groundVertices);
groundGroup.setNormals(groundNormals);
groundGroup.setTextureCoordinates(groundTextureCoordinates);
groundGroup.setFacesEntities(groupFacesEntities);
// register group
ground.getGroups().put("ground", groundGroup);
ground.getSubGroups().put("ground", groundGroup);
// prepare for indexed rendering
ModelHelper.prepareForIndexedRendering(ground);
//
return ground;
}
use of net.drewke.tdme.engine.model.Group in project tdme by andreasdr.
the class DAEReader method readNode.
/**
* Reads a DAE visual scene group node
* @param authoring tool
* @param path name
* @param model
* @param parent group
* @param xml node
* @param xml root
* @param frames per seconds
* @throws Exception
* @return group
*/
private static Group readNode(AuthoringTool authoringTool, String pathName, Model model, Group parentGroup, Element xmlRoot, Element xmlNode, float fps) throws Exception {
String xmlNodeId = xmlNode.getAttribute("id");
String xmlNodeName = xmlNode.getAttribute("name");
if (xmlNodeId.length() == 0)
xmlNodeId = xmlNodeName;
StringTokenizer t = null;
// default node matrix
Matrix4x4 transformationsMatrix = null;
// set up local transformations matrix
List<Element> xmlMatrixElements = getChildrenByTagName(xmlNode, "matrix");
if (xmlMatrixElements.size() == 1) {
String xmlMatrix = getChildrenByTagName(xmlNode, "matrix").get(0).getTextContent();
t = new StringTokenizer(xmlMatrix, " \n\r");
//
transformationsMatrix = 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);
//
if (transformationsMatrix != null) {
group.getTransformationsMatrix().multiply(transformationsMatrix);
}
// parse animations
List<Element> xmlAnimationsLibrary = getChildrenByTagName(xmlRoot, "library_animations");
if (xmlAnimationsLibrary.isEmpty() == false) {
List<Element> xmlAnimations = getChildrenByTagName(xmlAnimationsLibrary.get(0), "animation");
for (Element xmlAnimation : xmlAnimations) {
// older DAE has animation/animation xml nodes
List<Element> _xmlAnimation = getChildrenByTagName(xmlAnimation, "animation");
if (_xmlAnimation.isEmpty() == false) {
xmlAnimation = _xmlAnimation.get(0);
}
// find sampler source
String xmlSamplerSource = null;
Element xmlChannel = getChildrenByTagName(xmlAnimation, "channel").get(0);
if (xmlChannel.getAttribute("target").startsWith(xmlNodeId + "/")) {
xmlSamplerSource = xmlChannel.getAttribute("source").substring(1);
}
// check for sampler source
if (xmlSamplerSource == null) {
continue;
}
// parse animation output matrices
String xmlSamplerOutputSource = null;
String xmlSamplerInputSource = null;
Element xmlSampler = getChildrenByTagName(xmlAnimation, "sampler").get(0);
for (Element xmlSamplerInput : getChildrenByTagName(xmlSampler, "input")) {
if (xmlSamplerInput.getAttribute("semantic").equals("OUTPUT")) {
xmlSamplerOutputSource = xmlSamplerInput.getAttribute("source").substring(1);
} else if (xmlSamplerInput.getAttribute("semantic").equals("INPUT")) {
xmlSamplerInputSource = xmlSamplerInput.getAttribute("source").substring(1);
}
}
// check for sampler source
if (xmlSamplerOutputSource == null) {
throw new ModelFileIOException("Could not find xml sampler output source for animation for " + xmlNodeId);
}
// load animation input matrices
// TODO: check accessor "time"
float[] keyFrameTimes = null;
for (Element xmlAnimationSource : getChildrenByTagName(xmlAnimation, "source")) {
if (xmlAnimationSource.getAttribute("id").equals(xmlSamplerInputSource)) {
Element xmlFloatArray = getChildrenByTagName(xmlAnimationSource, "float_array").get(0);
int frames = Integer.parseInt(xmlFloatArray.getAttribute("count"));
String valueString = xmlFloatArray.getTextContent();
int keyFrameIdx = 0;
keyFrameTimes = new float[frames];
t = new StringTokenizer(valueString, " \n\r");
while (t.hasMoreTokens()) {
keyFrameTimes[keyFrameIdx++] = Float.parseFloat(t.nextToken());
}
}
}
// load animation output matrices
// TODO: check accessor "transform"
Matrix4x4[] keyFrameMatrices = null;
for (Element xmlAnimationSource : getChildrenByTagName(xmlAnimation, "source")) {
if (xmlAnimationSource.getAttribute("id").equals(xmlSamplerOutputSource)) {
Element xmlFloatArray = getChildrenByTagName(xmlAnimationSource, "float_array").get(0);
int keyFrames = Integer.parseInt(xmlFloatArray.getAttribute("count")) / 16;
// some models have animations without frames
if (keyFrames > 0) {
String valueString = xmlFloatArray.getTextContent();
t = new StringTokenizer(valueString, " \n\r");
// parse key frame
int keyFrameIdx = 0;
keyFrameMatrices = new Matrix4x4[keyFrames];
while (t.hasMoreTokens()) {
// set animation transformation matrix at frame
keyFrameMatrices[keyFrameIdx] = 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();
keyFrameIdx++;
}
}
}
}
// create linear animation by key frame times and key frames
if (keyFrameTimes != null && keyFrameMatrices != null) {
int frames = (int) Math.ceil(keyFrameTimes[keyFrameTimes.length - 1] * fps);
// create default animation
ModelHelper.createDefaultAnimation(model, frames);
//
Animation animation = group.createAnimation(frames);
Matrix4x4[] transformationsMatrices = animation.getTransformationsMatrices();
Matrix4x4 tansformationsMatrixLast = keyFrameMatrices[0];
int keyFrameIdx = 0;
int frameIdx = 0;
float timeStampLast = 0.0f;
for (float keyFrameTime : keyFrameTimes) {
Matrix4x4 transformationsMatrixCurrent = keyFrameMatrices[(keyFrameIdx) % keyFrameMatrices.length];
float timeStamp;
for (timeStamp = timeStampLast; timeStamp < keyFrameTime; timeStamp += 1.0f / fps) {
if (frameIdx >= frames) {
System.out.println("Warning: skipping frame: " + frameIdx);
frameIdx++;
continue;
}
Matrix4x4.interpolateLinear(tansformationsMatrixLast, transformationsMatrixCurrent, (timeStamp - timeStampLast) / (keyFrameTime - timeStampLast), transformationsMatrices[frameIdx]);
frameIdx++;
}
timeStampLast = timeStamp;
tansformationsMatrixLast = transformationsMatrixCurrent;
keyFrameIdx++;
}
}
}
}
// parse sub groups
for (Element _xmlNode : getChildrenByTagName(xmlNode, "node")) {
Group _group = readVisualSceneNode(authoringTool, pathName, model, group, xmlRoot, _xmlNode, fps);
if (_group != null) {
group.getSubGroups().put(_group.getId(), _group);
model.getGroups().put(_group.getId(), _group);
}
}
// check for geometry data
String xmlInstanceGeometryId = null;
List<Element> xmlInstanceGeometryElements = getChildrenByTagName(xmlNode, "instance_geometry");
if (xmlInstanceGeometryElements.isEmpty() == false) {
Element xmlInstanceGeometryElement = xmlInstanceGeometryElements.get(0);
// fetch instance geometry url
xmlInstanceGeometryId = xmlInstanceGeometryElement.getAttribute("url").substring(1);
// determine bound materials
HashMap<String, String> materialSymbols = new HashMap<String, String>();
for (Element xmlBindMaterial : getChildrenByTagName(xmlInstanceGeometryElement, "bind_material")) for (Element xmlTechniqueCommon : getChildrenByTagName(xmlBindMaterial, "technique_common")) for (Element xmlInstanceMaterial : getChildrenByTagName(xmlTechniqueCommon, "instance_material")) {
materialSymbols.put(xmlInstanceMaterial.getAttribute("symbol"), xmlInstanceMaterial.getAttribute("target"));
}
// parse geometry
readGeometry(authoringTool, pathName, model, group, xmlRoot, xmlInstanceGeometryId, materialSymbols);
//
return group;
}
// otherwise check for "instance_node"
String xmlInstanceNodeId = null;
for (Element xmlInstanceNodeElement : getChildrenByTagName(xmlNode, "instance_node")) {
xmlInstanceNodeId = xmlInstanceNodeElement.getAttribute("url").substring(1);
}
// do we have a instance node id?
if (xmlInstanceNodeId != null) {
for (Element xmlLibraryNodes : getChildrenByTagName(xmlRoot, "library_nodes")) for (Element xmlLibraryNode : getChildrenByTagName(xmlLibraryNodes, "node")) if (xmlLibraryNode.getAttribute("id").equals(xmlInstanceNodeId)) {
// parse sub groups
for (Element _xmlNode : getChildrenByTagName(xmlLibraryNode, "node")) {
Group _group = readVisualSceneNode(authoringTool, pathName, model, parentGroup, xmlRoot, _xmlNode, fps);
if (_group != null) {
group.getSubGroups().put(_group.getId(), _group);
model.getGroups().put(_group.getId(), _group);
}
}
// parse geometry
for (Element xmlInstanceGeometry : getChildrenByTagName(xmlLibraryNode, "instance_geometry")) {
String xmlGeometryId = xmlInstanceGeometry.getAttribute("url").substring(1);
// parse material symbols
HashMap<String, String> materialSymbols = new HashMap<String, String>();
for (Element xmlBindMaterial : getChildrenByTagName(xmlInstanceGeometry, "bind_material")) for (Element xmlTechniqueCommon : getChildrenByTagName(xmlBindMaterial, "technique_common")) for (Element xmlInstanceMaterial : getChildrenByTagName(xmlTechniqueCommon, "instance_material")) {
materialSymbols.put(xmlInstanceMaterial.getAttribute("symbol"), xmlInstanceMaterial.getAttribute("target"));
}
// parse geometry
readGeometry(authoringTool, pathName, model, group, xmlRoot, xmlGeometryId, materialSymbols);
}
}
}
//
return group;
}
use of net.drewke.tdme.engine.model.Group in project tdme by andreasdr.
the class PrimitiveModel method createBoundingBoxModel.
/**
* Creates a model from bounding box
* @param bounding box
* @param id
* @return model
*/
public static Model createBoundingBoxModel(BoundingBox boundingBox, String id) {
// 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);
// triangle vertices indexes
int[][] fvi = OrientedBoundingBox.facesVerticesIndexes;
// vertices
ArrayList<Vector3> vertices = new ArrayList<Vector3>();
for (Vector3 vertex : boundingBox.getVertices()) {
vertices.add(vertex.clone());
}
// normals
ArrayList<Vector3> normals = new ArrayList<Vector3>();
normals.add(new Vector3(-1.0f, 0.0f, 0.0f));
normals.add(new Vector3(+1.0f, 0.0f, 0.0f));
normals.add(new Vector3(0.0f, -1.0f, 0.0f));
normals.add(new Vector3(0.0f, +1.0f, 0.0f));
normals.add(new Vector3(0.0f, 0.0f, -1.0f));
normals.add(new Vector3(0.0f, 0.0f, +1.0f));
// faces
ArrayList<Face> faces = new ArrayList<Face>();
// left
faces.add(new Face(group, fvi[0][0], fvi[0][1], fvi[0][2], 0, 0, 0));
faces.add(new Face(group, fvi[1][0], fvi[1][1], fvi[1][2], 0, 0, 0));
// right
faces.add(new Face(group, fvi[2][0], fvi[2][1], fvi[2][2], 1, 1, 1));
faces.add(new Face(group, fvi[3][0], fvi[3][1], fvi[3][2], 1, 1, 1));
// top
faces.add(new Face(group, fvi[4][0], fvi[4][1], fvi[4][2], 2, 2, 2));
faces.add(new Face(group, fvi[5][0], fvi[5][1], fvi[5][2], 2, 2, 2));
// bottom
faces.add(new Face(group, fvi[6][0], fvi[6][1], fvi[6][2], 3, 3, 3));
faces.add(new Face(group, fvi[7][0], fvi[7][1], fvi[7][2], 3, 3, 3));
// near
faces.add(new Face(group, fvi[8][0], fvi[8][1], fvi[8][2], 4, 4, 4));
faces.add(new Face(group, fvi[9][0], fvi[9][1], fvi[9][2], 4, 4, 4));
// far
faces.add(new Face(group, fvi[10][0], fvi[10][1], fvi[10][2], 5, 5, 5));
faces.add(new Face(group, fvi[11][0], fvi[11][1], fvi[11][2], 5, 5, 5));
// 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.Group in project tdme by andreasdr.
the class LevelEditorView method createLevelEditorGroundPlateModel.
/**
* Creates a level editor ground plate
* @return ground
*/
private Model createLevelEditorGroundPlateModel() {
// ground selectedEntity
Model groundPlate = new Model("leveleditor.ground", "leveleditor.ground", UpVector.Y_UP, RotationOrder.XYZ, (BoundingBox) BoundingBox.createBoundingVolume(new Vector3(0f, -0.01f, 0f), new Vector3(1f, +0.01f, 1f)));
// material
Material groundPlateMaterial = new Material("ground");
groundPlateMaterial.getDiffuseColor().setAlpha(0.75f);
groundPlateMaterial.setDiffuseTexture("resources/tools/leveleditor/textures", "groundplate.png");
groundPlateMaterial.getSpecularColor().set(0f, 0f, 0f, 1f);
groundPlate.getMaterials().put("ground", groundPlateMaterial);
// group
Group groundGroup = new Group(groundPlate, null, "ground", "ground");
// faces entity
// ground
FacesEntity groupFacesEntityGround = new FacesEntity(groundGroup, "leveleditor.ground.facesentity");
groupFacesEntityGround.setMaterial(groundPlateMaterial);
// faces entity
ArrayList<FacesEntity> groupFacesEntities = new ArrayList<FacesEntity>();
groupFacesEntities.add(groupFacesEntityGround);
// vertices
ArrayList<Vector3> groundVertices = new ArrayList<Vector3>();
// left, near, ground
groundVertices.add(new Vector3(0.0f, 0.0f, 0.0f));
// left, far, ground
groundVertices.add(new Vector3(0.0f, 0.0f, +groundPlateDepth));
// right far, ground
groundVertices.add(new Vector3(+groundPlateWidth, 0.0f, +groundPlateDepth));
// right, near, ground
groundVertices.add(new Vector3(+groundPlateWidth, 0.0f, 0.0f));
// normals
ArrayList<Vector3> groundNormals = new ArrayList<Vector3>();
// ground
groundNormals.add(new Vector3(0f, 1f, 0f));
// texture coordinates
ArrayList<TextureCoordinate> groundTextureCoordinates = new ArrayList<TextureCoordinate>();
groundTextureCoordinates.add(new TextureCoordinate(0f, 1f));
groundTextureCoordinates.add(new TextureCoordinate(0f, 0f));
groundTextureCoordinates.add(new TextureCoordinate(1f, 0f));
groundTextureCoordinates.add(new TextureCoordinate(1f, 1f));
// faces ground
ArrayList<Face> groundFacesGround = new ArrayList<Face>();
groundFacesGround.add(new Face(groundGroup, 0, 1, 2, 0, 0, 0, 0, 1, 2));
groundFacesGround.add(new Face(groundGroup, 2, 3, 0, 0, 0, 0, 2, 3, 0));
// set up faces entity
groupFacesEntityGround.setFaces(groundFacesGround);
// setup ground group
groundGroup.setVertices(groundVertices);
groundGroup.setNormals(groundNormals);
groundGroup.setTextureCoordinates(groundTextureCoordinates);
groundGroup.setFacesEntities(groupFacesEntities);
// register group
groundPlate.getGroups().put(groundGroup.getId(), groundGroup);
groundPlate.getSubGroups().put(groundGroup.getId(), groundGroup);
// prepare for indexed rendering
ModelHelper.prepareForIndexedRendering(groundPlate);
//
return groundPlate;
}
use of net.drewke.tdme.engine.model.Group in project tdme by andreasdr.
the class Object3DBase method computeTransformationsMatrices.
/**
* Calculates all groups transformation matrices
* @param groups
* @param parent transformations matrix
* @param animation state
* @param depth
*/
protected void computeTransformationsMatrices(HashMap<String, Group> groups, Matrix4x4 parentTransformationsMatrix, AnimationState animationState, int depth) {
// iterate through groups
for (Group group : groups.getValuesIterator()) {
// check for overlay animation
AnimationState overlayAnimation = overlayAnimationsByJointId.get(group.getId());
if (overlayAnimation != null)
animationState = overlayAnimation;
// group transformation matrix
Matrix4x4 transformationsMatrix = null;
// compute animation matrix if animation setups exist
Animation animation = group.getAnimation();
if (animation != null && animationState.finished == false) {
Matrix4x4[] animationMatrices = animation.getTransformationsMatrices();
int frames = animationState.setup.getFrames();
float fps = model.getFPS();
// determine current and last matrix
float frameAtLast = (animationState.lastAtTime / 1000f) * fps;
float frameAtCurrent = (animationState.currentAtTime / 1000f) * fps;
// check if looping is disabled
if (animationState.setup.isLoop() == false && frameAtCurrent >= frames) {
// set frame at current to last frame
frameAtLast = frames - 1;
frameAtCurrent = frames - 1;
animationState.finished = true;
}
//
int matrixAtLast = ((int) frameAtLast % frames);
int matrixAtCurrent = ((int) frameAtCurrent % frames);
animationState.time = frames <= 1 ? 0.0f : (float) matrixAtCurrent / (float) (frames - 1);
// compute animation transformations matrix
float t = frameAtCurrent - (float) Math.floor(frameAtLast);
if (t < 1f) {
if (matrixAtLast == matrixAtCurrent) {
matrixAtCurrent = ((matrixAtCurrent + 1) % frames);
}
transformationsMatrix = Matrix4x4.interpolateLinear(animationMatrices[matrixAtLast + animationState.setup.getStartFrame()], animationMatrices[matrixAtCurrent + animationState.setup.getStartFrame()], t, tmpMatrix1);
} else {
transformationsMatrix = tmpMatrix1.set(animationMatrices[matrixAtCurrent + animationState.setup.getStartFrame()]);
}
}
// do we have no animation matrix?
if (transformationsMatrix == null) {
// no animation matrix, set up local transformation matrix up as group matrix
transformationsMatrix = tmpMatrix1.set(group.getTransformationsMatrix());
}
// apply parent transformation matrix
if (parentTransformationsMatrix != null) {
transformationsMatrix.multiply(parentTransformationsMatrix);
}
// put and associate transformation matrices with group
transformationsMatrices.get(group.getId()).set(transformationsMatrix);
// calculate for sub groups
HashMap<String, Group> subGroups = group.getSubGroups();
if (subGroups.size() > 0) {
// put to matrices stack
transformationsMatricesStack[depth].set(transformationsMatrix);
// compute sub groups transformations
computeTransformationsMatrices(subGroups, transformationsMatricesStack[depth], animationState, depth + 1);
}
}
}
Aggregations