Search in sources :

Example 1 with Key

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);
}
Also used : Key(net.drewke.tdme.utils.Key)

Example 2 with Key

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;
}
Also used : BoundingBox(net.drewke.tdme.engine.primitives.BoundingBox) Vector3(net.drewke.tdme.math.Vector3) Key(net.drewke.tdme.utils.Key)

Example 3 with Key

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);
}
Also used : FacesEntity(net.drewke.tdme.engine.model.FacesEntity) Material(net.drewke.tdme.engine.model.Material) Object3D(net.drewke.tdme.engine.Object3D) Color4(net.drewke.tdme.engine.model.Color4) Model(net.drewke.tdme.engine.model.Model) Key(net.drewke.tdme.utils.Key)

Example 4 with Key

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);
    }
}
Also used : Transformations(net.drewke.tdme.engine.Transformations) Rotation(net.drewke.tdme.engine.Rotation) Key(net.drewke.tdme.utils.Key) Rotations(net.drewke.tdme.engine.Rotations)

Example 5 with Key

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);
}
Also used : Key(net.drewke.tdme.utils.Key) PointsParticleSystemEntityInternal(net.drewke.tdme.engine.subsystems.particlesystem.PointsParticleSystemEntityInternal)

Aggregations

Key (net.drewke.tdme.utils.Key)6 BoundingBox (net.drewke.tdme.engine.primitives.BoundingBox)2 Vector3 (net.drewke.tdme.math.Vector3)2 Object3D (net.drewke.tdme.engine.Object3D)1 Rotation (net.drewke.tdme.engine.Rotation)1 Rotations (net.drewke.tdme.engine.Rotations)1 Transformations (net.drewke.tdme.engine.Transformations)1 Color4 (net.drewke.tdme.engine.model.Color4)1 FacesEntity (net.drewke.tdme.engine.model.FacesEntity)1 Material (net.drewke.tdme.engine.model.Material)1 Model (net.drewke.tdme.engine.model.Model)1 PointsParticleSystemEntityInternal (net.drewke.tdme.engine.subsystems.particlesystem.PointsParticleSystemEntityInternal)1