use of net.drewke.tdme.utils.Key in project tdme by andreasdr.
the class ContactCache method add.
/**
*
* @param rb1
* @param rb2
* @param collision
* @param lamdaValues
*/
protected void add(RigidBody rb1, RigidBody rb2, CollisionResponse collision, float[] lamdaValues) {
// construct contact cache
ContactCacheInfo contactCacheInfo = contactCacheInfoPool[contactCacheInfoPoolIdx++];
contactCacheInfo.rb1 = rb1;
contactCacheInfo.rb2 = rb2;
contactCacheInfo.hitPointCount = collision.getHitPointsCount();
for (int i = 0; i < contactCacheInfo.hitPointCount; i++) {
contactCacheInfo.hitPoints[i].set(collision.getHitPointAt(i));
contactCacheInfo.lamdas[i] = lamdaValues[i];
}
// generate key
Key key = keyPool[keyPoolIdx++];
key.reset();
key.append(rb1.id);
key.append(",");
key.append(rb2.id);
// construct
ContactCacheInfo oldContactCacheInfo = contactCache.put(key, contactCacheInfo);
}
use of net.drewke.tdme.utils.Key in project tdme by andreasdr.
the class PartitionQuadTree method createPartition.
/**
* Creates a partition
* @param parent
* @param x
* @param z
* @param partition size
* @return partition tree node
*/
public PartitionTreeNode createPartition(PartitionTreeNode parent, int x, int y, int z, float partitionSize) {
PartitionTreeNode node;
node = new PartitionTreeNode();
node.partitionSize = partitionSize;
node.x = x;
node.y = y;
node.z = z;
node.parent = parent;
node.bv = new BoundingBox(new Vector3(x * partitionSize, y * partitionSize, z * partitionSize), new Vector3(x * partitionSize + partitionSize, y * partitionSize + partitionSize, z * partitionSize + partitionSize));
node.subNodes = null;
node.subNodesByCoordinate = null;
node.partitionRidigBodies = null;
// register in parent sub nodes
if (parent.subNodes == null) {
parent.subNodes = new ArrayList<PartitionTreeNode>();
}
parent.subNodes.add(node);
// register in parent sub nodes by coordinate
if (parent.subNodesByCoordinate == null) {
parent.subNodesByCoordinate = new HashMap<Key, PartitionTreeNode>();
}
Key key = new Key();
key.reset();
key.append(node.x);
key.append(",");
key.append(node.y);
key.append(",");
key.append(node.z);
parent.subNodesByCoordinate.put(key, node);
// create sub nodes
if (partitionSize > PARTITION_SIZE_MIN) {
for (int _y = 0; _y < 2; _y++) for (int _x = 0; _x < 2; _x++) for (int _z = 0; _z < 2; _z++) {
createPartition(node, (int) ((x * partitionSize) / (partitionSize / 2f)) + _x, (int) ((y * partitionSize) / (partitionSize / 2f)) + _y, (int) ((z * partitionSize) / (partitionSize / 2f)) + _z, partitionSize / 2f);
}
} else {
node.partitionRidigBodies = new ArrayList<RigidBody>();
}
//
return node;
}
use of net.drewke.tdme.utils.Key in project tdme by andreasdr.
the class Object3DVBORenderer method prepareTransparentFaces.
/**
* Renders transparent faces
* TODO: guess this should be optimized regarding GL commands
* skinned mesh is not supported when using GPU
* @param transparent render faces
*/
protected void prepareTransparentFaces(ArrayList<TransparentRenderFace> transparentRenderFaces) {
// all those faces should share the object and object 3d group, ...
Object3DGroup object3DGroup = transparentRenderFaces.get(0).object3DGroup;
Object3D object3D = (Object3D) object3DGroup.object;
// model view matrix to be used with given transparent render faces
modelViewMatrix = (object3DGroup.mesh.skinning == true ? modelViewMatrix.identity() : modelViewMatrix.set(object3DGroup.groupTransformationsMatrix)).multiply(object3D.transformationsMatrix).multiply(renderer.getModelViewMatrix());
//
Model model = ((Object3D) object3DGroup.object).getModel();
FacesEntity[] facesEntities = object3DGroup.group.getFacesEntities();
FacesEntity facesEntity = null;
// attributes we collect for a transparent render face group
boolean depthBuffer = false;
Color4 effectColorAdd = ((Object3D) object3D).getEffectColorAdd();
Color4 effectColorMul = ((Object3D) object3D).getEffectColorMul();
Material material = null;
boolean textureCoordinates = false;
// render transparent faces
Key transparentRenderFacesGroupKey = keyPool.allocate();
for (int i = 0; i < transparentRenderFaces.size(); i++) {
TransparentRenderFace transparentRenderFace = transparentRenderFaces.get(i);
int facesEntityIdx = transparentRenderFace.facesEntityIdx;
// check if to use depth buffer
depthBuffer = ((Object3D) transparentRenderFace.object3DGroup.object).isPickable();
// determine if faces entity and so material did switch between last face and current face
if (facesEntity != facesEntities[facesEntityIdx]) {
facesEntity = facesEntities[facesEntityIdx];
material = facesEntity.getMaterial();
}
textureCoordinates = facesEntity.isTextureCoordinatesAvailable();
// create group key
TransparentRenderFacesGroup.createKey(transparentRenderFacesGroupKey, model, object3DGroup, facesEntityIdx, effectColorAdd, effectColorMul, depthBuffer, material, textureCoordinates);
// get group
TransparentRenderFacesGroup trfGroup = transparentRenderFacesGroups.get(transparentRenderFacesGroupKey);
if (trfGroup == null) {
// we do not have the group, create group
trfGroup = transparentRenderFacesGroupPool.allocate();
trfGroup.set(this, model, object3DGroup, facesEntityIdx, effectColorAdd, effectColorMul, depthBuffer, material, textureCoordinates);
Key hashtableKey = keyPool.allocate();
transparentRenderFacesGroupKey.cloneInto(hashtableKey);
if (transparentRenderFacesGroups.put(hashtableKey, trfGroup) != null) {
System.out.println("Object3DVBORenderer::prepareTransparentFaces::key already exists");
System.out.println("-->" + transparentRenderFacesGroupKey);
System.out.println("-->" + hashtableKey);
}
}
// add face vertices
for (int vertexIdx = 0; vertexIdx < 3; vertexIdx++) {
short arrayIdx = transparentRenderFace.object3DGroup.mesh.indices[transparentRenderFace.faceIdx * 3 + vertexIdx];
trfGroup.addVertex(modelViewMatrix.multiply(transparentRenderFace.object3DGroup.mesh.transformedVertices[arrayIdx], transformedVertex), modelViewMatrix.multiplyNoTranslation(transparentRenderFace.object3DGroup.mesh.transformedNormals[arrayIdx], transformedNormal), transparentRenderFace.object3DGroup.mesh.textureCoordinates != null ? transparentRenderFace.object3DGroup.mesh.textureCoordinates[arrayIdx] : null);
}
}
keyPool.release(transparentRenderFacesGroupKey);
}
use of net.drewke.tdme.utils.Key in project tdme by andreasdr.
the class World method update.
/**
* Update world
* @param delta time
*/
public void update(float deltaTime) {
// lazy initiate constraints solver
if (constraintsSolver == null) {
constraintsSolver = new ConstraintsSolver(rigidBodies);
}
// apply gravity
for (int i = 0; i < rigidBodies.size(); i++) {
// update rigid body
RigidBody rigidBody = rigidBodies.get(i);
// skip on disabled, static
if (rigidBody.enabled == false) {
// System.out.println("World::update()::gravity::skipping " + rigidBody.id + "::disabled");
continue;
}
if (rigidBody.isStatic == true) {
continue;
}
// unset sleeping if velocity change occured
if (rigidBody.checkVelocityChange() == true) {
rigidBody.awake(true);
}
// skip on sleeping
if (rigidBody.isSleeping == true) {
continue;
}
// add gravity
rigidBody.addForce(worldPosForce.set(rigidBody.getPosition()).setY(10000f), gravityForce.set(0f, -rigidBody.getMass() * MathTools.g, 0f));
}
// do the collision tests,
// take every rigid body with every other rigid body into account
int collisionsTests = 0;
rigidBodyTestedCollisions.clear();
for (int i = 0; i < rigidBodies.size(); i++) {
RigidBody rigidBody1 = rigidBodies.get(i);
// skip on disabled
if (rigidBody1.enabled == false) {
// System.out.println("World::update()::collision::skipping " + rigidBody1.id + "::disabled");
continue;
}
/**
for (int j = 0; j < rigidBodies.size(); j++) {
RigidBody rigidBody2 = rigidBodies.get(j);
*/
int nearObjects = 0;
// dont test test which had been done in reverse order
for (RigidBody rigidBody2 : partition.getObjectsNearTo(rigidBody1.cbv)) {
// skip on disabled
if (rigidBody2.enabled == false) {
// System.out.println("World::update()::collision::skipping " + rigidBody2.id + "::disabled");
continue;
}
// skip if both are static
if (rigidBody1.isStatic == true && rigidBody2.isStatic == true)
continue;
// skip on same rigid body
if (rigidBody1 == rigidBody2)
continue;
// skip on rigid body 1 static, 2 non static and sleeping
if (rigidBody1.isStatic == true && rigidBody2.isStatic == false && rigidBody2.isSleeping == true) {
continue;
}
// skip on rigid body 2 static, 1 non static and sleeping
if (rigidBody2.isStatic == true && rigidBody1.isStatic == false && rigidBody1.isSleeping == true) {
continue;
}
// check if rigid body 2 want to have collision with rigid body 1
if (((rigidBody1.typeId & rigidBody2.collisionTypeIds) == rigidBody1.typeId) == false) {
continue;
}
// check if rigid body 1 want to have collision with rigid body 2
if (((rigidBody2.typeId & rigidBody1.collisionTypeIds) == rigidBody2.typeId) == false) {
continue;
}
//
nearObjects++;
// create rigidBody12 key
Key rigidBodyKey = constraintsSolver.allocateKey();
rigidBodyKey.reset();
rigidBodyKey.append(rigidBody1.idx);
rigidBodyKey.append(",");
rigidBodyKey.append(rigidBody2.idx);
// check if collision has been tested already
if (rigidBodyTestedCollisions.get(rigidBodyKey) != null) {
constraintsSolver.releaseKey();
continue;
}
/*
// create rigidbody21 key
rigidBodyKey.reset();
rigidBodyKey.append(rigidBody2.idx);
rigidBodyKey.append(",");
rigidBodyKey.append(rigidBody1.idx);
if (rigidBodyTestedCollisions.get(rigidBodyKey) != null) {
constraintsSolver.releaseKey();
continue;
}
*/
// nope, add 12 key
rigidBodyTestedCollisions.put(rigidBodyKey, rigidBodyKey);
//
collisionsTests++;
// determine collision movement
collisionMovement.set(rigidBody1.movement);
if (collisionMovement.computeLength() < MathTools.EPSILON) {
collisionMovement.set(rigidBody2.movement);
collisionMovement.scale(-1f);
}
// do collision test
if (rigidBody1.cbv.doesCollideWith(rigidBody2.cbv, collisionMovement, collision) == true && collision.hasPenetration() == true) {
// check for hit point count
if (collision.getHitPointsCount() == 0)
continue;
// we have a collision, so register it
Key rigidBodyCollisionKey = rigidBodyCollisionsKeyPoolCurrentFrame.allocate();
rigidBodyCollisionKey.reset();
rigidBodyCollisionKey.append(rigidBody1.idx);
rigidBodyCollisionKey.append(",");
rigidBodyCollisionKey.append(rigidBody2.idx);
rigidBodyCollisionsCurrentFrame.put(rigidBodyCollisionKey, rigidBodyCollisionKey);
// on collision begin
if (rigidBodyCollisionsLastFrame.get(rigidBodyCollisionKey) == null) {
rigidBody1.fireOnCollisionBegin(rigidBody2, collision);
}
// on collision
rigidBody1.fireOnCollision(rigidBody2, collision);
// unset sleeping if both non static and colliding
if (rigidBody1.isStatic == false && rigidBody2.isStatic == false) {
rigidBody1.awake(true);
rigidBody2.awake(true);
}
// add constraint entity
constraintsSolver.allocateConstraintsEntity().set(rigidBody1, rigidBody2, constraintsSolver.allocateCollision().fromResponse(collision));
}
}
// System.out.println(rigidBody1.id + ":" + nearObjects);
}
// check each collision last frame that disappeared in current frame
for (Key key : rigidBodyCollisionsLastFrame.getKeysIterator()) {
Key rigidBodyCollisionKey = rigidBodyCollisionsCurrentFrame.get(key);
if (rigidBodyCollisionKey == null) {
char[] keyData = key.getData();
int rigidBodyIdx1 = 0;
int rigidBodyIdx2 = 0;
rigidBodyIdx1 += (int) keyData[0] << 0;
rigidBodyIdx1 += (int) keyData[1] << 8;
rigidBodyIdx1 += (int) keyData[2] << 16;
rigidBodyIdx1 += (int) keyData[3] << 24;
rigidBodyIdx2 += (int) keyData[5] << 0;
rigidBodyIdx2 += (int) keyData[6] << 8;
rigidBodyIdx2 += (int) keyData[7] << 16;
rigidBodyIdx2 += (int) keyData[8] << 24;
RigidBody rigidBody1 = rigidBodies.get(rigidBodyIdx1);
RigidBody rigidBody2 = rigidBodies.get(rigidBodyIdx2);
rigidBody1.fireOnCollisionEnd(rigidBody2);
}
}
// swap rigid body collisions current and last frame
Pool<Key> rigidBodyCollisionsKeyPoolTmp = rigidBodyCollisionsKeyPoolLastFrame;
HashMap<Key, Key> rigidBodyCollisionsTmp = rigidBodyCollisionsLastFrame;
rigidBodyCollisionsLastFrame = rigidBodyCollisionsCurrentFrame;
rigidBodyCollisionsKeyPoolLastFrame = rigidBodyCollisionsKeyPoolCurrentFrame;
rigidBodyCollisionsCurrentFrame = rigidBodyCollisionsTmp;
rigidBodyCollisionsKeyPoolCurrentFrame = rigidBodyCollisionsKeyPoolTmp;
// reset current frame
rigidBodyCollisionsCurrentFrame.clear();
rigidBodyCollisionsKeyPoolCurrentFrame.reset();
// do the solving
constraintsSolver.compute(deltaTime);
constraintsSolver.updateAllBodies(deltaTime);
constraintsSolver.reset();
// update transformations for rigid body
for (int i = 0; i < rigidBodies.size(); i++) {
RigidBody rigidBody = rigidBodies.get(i);
// skip if enabled and remove partition
if (rigidBody.enabled == false) {
partition.removeRigidBody(rigidBody);
continue;
}
// skip on static
if (rigidBody.isStatic == true || rigidBody.isSleeping == true) {
continue;
}
// set up transformations, keep care that only 3 rotations exists (x, y, z axis)
Rotations rotations = rigidBody.transformations.getRotations();
while (rotations.size() > 1) {
rotations.remove(rotations.size() - 1);
}
while (rotations.size() < 1) {
rotations.add(new Rotation());
}
// set up orientation
rotations.get(0).fromQuaternion(rigidBody.orientation);
rotations.get(0).getAxix().getArray()[1] *= -1f;
// second set up position
Transformations transformations = rigidBody.transformations;
transformations.getTranslation().set(rigidBody.position);
// update
transformations.update();
// update bounding volume
rigidBody.cbv.fromBoundingVolumeWithTransformations(rigidBody.obv, transformations);
// update partition
partition.updateRigidBody(rigidBody);
}
}
use of net.drewke.tdme.utils.Key in project tdme by andreasdr.
the class Object3DVBORenderer method render.
/**
* Render batch VBO renderer points entities
* @param points batch VBO renderer points
*/
public void render(ArrayList<PointsParticleSystemEntity> visiblePses) {
if (visiblePses.size() == 0)
return;
// store model view matrix
modelViewMatrix.set(renderer.getModelViewMatrix());
//
boolean depthBuffer = false;
// set up GL state
renderer.enableBlending();
renderer.disableDepthBuffer();
renderer.disableClientState(renderer.CLIENTSTATE_NORMAL_ARRAY);
renderer.enableClientState(renderer.CLIENTSTATE_COLOR_ARRAY);
// disable texturing client state if not yet done
if (renderer.renderingTexturingClientState == false) {
renderer.enableClientState(renderer.CLIENTSTATE_TEXTURECOORD_ARRAY);
renderer.renderingTexturingClientState = true;
}
// model view matrix
renderer.getModelViewMatrix().identity();
renderer.onUpdateModelViewMatrix();
// find all keys which differentiate with effect colors and depth buffer
for (int i = 0; i < visiblePses.size(); i++) {
PointsParticleSystemEntityInternal ppse = visiblePses.get(i);
Key key = pseKeyPool.allocate();
createPseKey(key, ppse.getEffectColorAdd(), ppse.getEffectColorMul(), ppse.isPickable(), ppse.getParticleEmitter().getColorStart().equals(ppse.getParticleEmitter().getColorEnd()) == false);
if (pseKeys.contains(key) == false) {
pseKeys.add(key);
} else {
pseKeyPool.release(key);
}
}
// process each key in inner loop
Key innerPseKey = pseKeyPool.allocate();
for (int i = 0; i < pseKeys.size(); i++) {
// fetch key from available keys
Key pseKey = pseKeys.get(i);
boolean pseSort = false;
PointsParticleSystemEntityInternal currentPse = null;
// iterate all pses
for (int j = 0; j < visiblePses.size(); j++) {
PointsParticleSystemEntityInternal ppse = visiblePses.get(j);
// check if ppse belongs to current key, otherwise skip this pse
createPseKey(innerPseKey, ppse.getEffectColorAdd(), ppse.getEffectColorMul(), ppse.isPickable(), ppse.getParticleEmitter().getColorStart().equals(ppse.getParticleEmitter().getColorEnd()) == false);
if (pseKey.equals(innerPseKey) == false) {
continue;
} else {
currentPse = visiblePses.get(j);
pseSort = ppse.getParticleEmitter().getColorStart().equals(ppse.getParticleEmitter().getColorEnd()) == false;
}
// merge ppse pool
pseTransparentRenderPointsPool.merge(ppse.getRenderPointsPool());
}
// sort
if (pseSort == true)
pseTransparentRenderPointsPool.sort();
// put sorted points into batch renderer
for (TransparentRenderPoint point : pseTransparentRenderPointsPool.getTransparentRenderPointsIterator()) {
if (point.acquired == false)
break;
psePointBatchVBORenderer.addPoint(point);
}
//
renderer.setEffectColorAdd(currentPse.getEffectColorAdd().getArray());
renderer.setEffectColorMul(currentPse.getEffectColorMul().getArray());
renderer.onUpdateEffect();
depthBuffer = currentPse.isPickable();
if (depthBuffer) {
renderer.enableDepthBuffer();
} else {
renderer.disableDepthBuffer();
}
// render, clear
psePointBatchVBORenderer.render();
psePointBatchVBORenderer.clear();
// reset pool
pseTransparentRenderPointsPool.reset();
}
// release pse keys and current pse key
for (int i = 0; i < pseKeys.size(); i++) {
pseKeyPool.release(pseKeys.get(i));
}
pseKeys.clear();
pseKeyPool.release(innerPseKey);
// restore gl state
renderer.disableBlending();
if (depthBuffer == false)
renderer.enableDepthBuffer();
renderer.unbindBufferObjects();
renderer.enableClientState(renderer.CLIENTSTATE_NORMAL_ARRAY);
renderer.disableClientState(renderer.CLIENTSTATE_COLOR_ARRAY);
renderer.getModelViewMatrix().set(modelViewMatrix);
}
Aggregations