use of net.drewke.tdme.engine.primitives.BoundingBox in project tdme by andreasdr.
the class World method determineHeight.
/**
* Determine height on x,y,u while respecting step up max
* @param type ids
* @param step up max
* @param point on which height should be calculated
* @param point where height has been determined
* @return rigid body from which height was determined or null
*/
public RigidBody determineHeight(int typeIds, float stepUpMax, Vector3 point, Vector3 dest) {
dest.set(point);
float[] pointXYZ = point.getArray();
// height bounding box to determine partition bounding volumes
heightBoundingBox.getMin().set(pointXYZ[0], -10000f, pointXYZ[2]);
heightBoundingBox.getMax().set(pointXYZ[0], +10000f, pointXYZ[2]);
heightBoundingBox.update();
// determine height of point on x, z
heightOnPointCandidate.set(pointXYZ[0], 10000f, pointXYZ[2]);
float height = -10000f;
RigidBody heightRigidBody = null;
for (RigidBody rigidBody : partition.getObjectsNearTo(heightBoundingBox)) {
if (((rigidBody.typeId & typeIds) == rigidBody.typeId) == false)
continue;
BoundingVolume cbv = rigidBody.cbv;
if (cbv instanceof BoundingBox) {
if (heightOnPointLineSegment.doesBoundingBoxCollideWithLineSegment((BoundingBox) cbv, heightBoundingBox.getMin(), heightBoundingBox.getMax(), heightOnPointA, heightOnPointB) == true) {
Vector3 heightOnPoint = higher(heightOnPointA, heightOnPointB);
if (heightOnPoint.getY() >= height && heightOnPoint.getY() < pointXYZ[1] + Math.max(0.1f, stepUpMax)) {
//
height = heightOnPoint.getY();
heightRigidBody = rigidBody;
}
}
} else if (cbv instanceof OrientedBoundingBox) {
if (heightOnPointLineSegment.doesOrientedBoundingBoxCollideWithLineSegment((OrientedBoundingBox) cbv, heightBoundingBox.getMin(), heightBoundingBox.getMax(), heightOnPointA, heightOnPointB) == true) {
Vector3 heightOnPoint = higher(heightOnPointA, heightOnPointB);
if (heightOnPoint.getY() >= height && heightOnPoint.getY() < pointXYZ[1] + Math.max(0.1f, stepUpMax)) {
//
height = heightOnPoint.getY();
heightRigidBody = rigidBody;
}
}
} else {
// compute closest point on height candidate
cbv.computeClosestPointOnBoundingVolume(heightOnPointCandidate, heightOnPointA);
// check new height, take only result into account which is near to candidate
if (Math.abs(heightOnPointCandidate.getX() - heightOnPointA.getX()) < 0.1f && Math.abs(heightOnPointCandidate.getZ() - heightOnPointA.getZ()) < 0.1f && heightOnPointA.getY() >= height && heightOnPointA.getY() < pointXYZ[1] + Math.max(0.1f, stepUpMax)) {
//
height = heightOnPointA.getY();
heightRigidBody = rigidBody;
}
}
}
// check if we have a ground
if (heightRigidBody == null) {
return null;
}
// nope, no collision
dest.setY(height);
return heightRigidBody;
}
use of net.drewke.tdme.engine.primitives.BoundingBox in project tdme by andreasdr.
the class ModelUtilitiesInternal method createBoundingBox.
/**
* Creates a bounding box from given object3d model
* @param model
* @return axis aligned bounding box
*/
public static BoundingBox createBoundingBox(Object3DModelInternal object3DModelInternal) {
Model model = object3DModelInternal.getModel();
AnimationSetup defaultAnimation = model.getAnimationSetup(Model.ANIMATIONSETUP_DEFAULT);
//
float minX = 0f, minY = 0f, minZ = 0f;
float maxX = 0f, maxY = 0f, maxZ = 0f;
boolean firstVertex = true;
// create bounding box for whole animation at 60fps
AnimationState animationState = new AnimationState();
animationState.setup = defaultAnimation;
animationState.lastAtTime = Timing.UNDEFINED;
animationState.currentAtTime = 0L;
animationState.time = 0.0f;
animationState.finished = false;
for (float t = 0.0f; t <= (defaultAnimation != null ? defaultAnimation.getFrames() : 0.0f) / model.getFPS(); t += 1f / model.getFPS()) {
//
// calculate transformations matrices without world transformations
object3DModelInternal.computeTransformationsMatrices(model.getSubGroups(), object3DModelInternal.getModel().getImportTransformationsMatrix().clone().multiply(object3DModelInternal.getTransformationsMatrix()), animationState, 0);
Object3DGroup.computeTransformations(object3DModelInternal.object3dGroups, object3DModelInternal.transformationsMatrices);
// parse through object groups to determine min, max
for (Object3DGroup object3DGroup : object3DModelInternal.object3dGroups) {
for (Vector3 vertex : object3DGroup.mesh.transformedVertices) {
// vertex xyz array
float[] vertexXYZ = vertex.getArray();
// determine min, max
if (firstVertex == true) {
minX = vertexXYZ[0];
minY = vertexXYZ[1];
minZ = vertexXYZ[2];
maxX = vertexXYZ[0];
maxY = vertexXYZ[1];
maxZ = vertexXYZ[2];
firstVertex = false;
} else {
if (vertexXYZ[0] < minX)
minX = vertexXYZ[0];
if (vertexXYZ[1] < minY)
minY = vertexXYZ[1];
if (vertexXYZ[2] < minZ)
minZ = vertexXYZ[2];
if (vertexXYZ[0] > maxX)
maxX = vertexXYZ[0];
if (vertexXYZ[1] > maxY)
maxY = vertexXYZ[1];
if (vertexXYZ[2] > maxZ)
maxZ = vertexXYZ[2];
}
}
}
animationState.currentAtTime = (long) (t * 1000f);
animationState.lastAtTime = (long) (t * 1000f);
}
// skip on models without meshes to be rendered
if (firstVertex == true)
return null;
// otherwise go with bounding box
return new BoundingBox(new Vector3(minX, minY, minZ), new Vector3(maxX, maxY, maxZ));
}
use of net.drewke.tdme.engine.primitives.BoundingBox in project tdme by andreasdr.
the class LevelEditorEntityBoundingVolume method setupAabb.
/**
* Setup bounding volume bounding box
* @param min
* @param max
*/
public void setupAabb(Vector3 min, Vector3 max) {
boundingVolume = new BoundingBox(min, max);
model = PrimitiveModel.createModel(boundingVolume, (levelEditorEntity.getModel() != null ? levelEditorEntity.getModel().getId() : levelEditorEntity.getId()) + "_model_bv." + id + "." + (staticIdx++));
modelMeshFile = null;
updateLevelEditorEntity();
}
use of net.drewke.tdme.engine.primitives.BoundingBox in project tdme by andreasdr.
the class LevelEditorEntityLibrary method addTrigger.
/**
* Add a trigger
* @param name
* @param description
* @param width
* @param height
* @param depth
* @return level editor entity
* @throws Exception
*/
public LevelEditorEntity addTrigger(int id, String name, String description, float width, float height, float depth) throws Exception {
String cacheId = "leveleditor.trigger." + width + "mx" + height + "mx" + depth + "m";
LevelEditorEntity levelEditorEntity = null;
BoundingBox boundingBox = new BoundingBox(new Vector3(-width / 2f, 0f, -depth / 2f), new Vector3(+width / 2f, height, +depth / 2f));
Model model = PrimitiveModel.createModel(boundingBox, cacheId + "_bv");
levelEditorEntity = new LevelEditorEntity(id == ID_ALLOCATE ? allocateEntityId() : id, EntityType.TRIGGER, name, description, null, cacheId, model.getId().replace("\\", "_").replace("/", "_").replace(":", "_") + ".png", model, new Vector3());
levelEditorEntity.addBoundingVolume(0, new LevelEditorEntityBoundingVolume(0, levelEditorEntity));
levelEditorEntity.getBoundingVolumeAt(0).setupAabb(boundingBox.getMin(), boundingBox.getMax());
id = levelEditorEntity.getId();
// add trigger
addEntity(levelEditorEntity);
//
return levelEditorEntity;
}
use of net.drewke.tdme.engine.primitives.BoundingBox in project tdme by andreasdr.
the class Tools method setupEntity.
/**
* Set up entity in given engine with look from rotations and scale
* @param entity
* @param engine
* @param look from rotations
* @param scale
*/
public static void setupEntity(LevelEditorEntity entity, Engine engine, Transformations lookFromRotations, float scale) {
if (entity == null)
return;
// entity bounding box
BoundingBox entityBoundingBox = null;
// add model to engine
if (entity.getType() == EntityType.PARTICLESYSTEM) {
entityBoundingBox = new BoundingBox(new Vector3(-0.5f, 0f, -0.5f), new Vector3(0.5f, 3f, 0.5f));
Entity particleSystemObject = Level.createParticleSystem(entity.getParticleSystem(), "model", true);
if (particleSystemObject != null) {
engine.addEntity(particleSystemObject);
}
} else {
entityBoundingBox = entity.getModel().getBoundingBox();
Object3D modelObject = new Object3D("model", entity.getModel());
modelObject.setDynamicShadowingEnabled(true);
engine.addEntity(modelObject);
}
// create ground object
Model ground = createGroundModel((entityBoundingBox.getMax().getX() - entityBoundingBox.getMin().getX()) * 1f, (entityBoundingBox.getMax().getZ() - entityBoundingBox.getMin().getZ()) * 1f, entityBoundingBox.getMin().getY() - MathTools.EPSILON);
// add ground to engine
Object3D groundObject = new Object3D("ground", ground);
groundObject.setEnabled(false);
engine.addEntity(groundObject);
// add bounding volume if we have any
for (int i = 0; i < entity.getBoundingVolumeCount(); i++) {
LevelEditorEntityBoundingVolume boundingVolume = entity.getBoundingVolumeAt(i);
if (boundingVolume.getModel() == null)
continue;
Object3D modelBoundingVolumeObject = new Object3D("model_bv." + i, boundingVolume.getModel());
modelBoundingVolumeObject.setEnabled(false);
engine.addEntity(modelBoundingVolumeObject);
}
// set up lights
for (Light light : engine.getLights()) light.setEnabled(false);
Light light0 = engine.getLightAt(0);
light0.getAmbient().set(1.0f, 1.0f, 1.0f, 1.0f);
light0.getDiffuse().set(0.5f, 0.5f, 0.5f, 1f);
light0.getSpecular().set(1f, 1f, 1f, 1f);
light0.getPosition().set(entityBoundingBox.getMin().getX() + ((entityBoundingBox.getMax().getX() - entityBoundingBox.getMin().getX()) / 2f), //modelBoundingBox.getMax().getY(),
entityBoundingBox.getMin().getY() + ((entityBoundingBox.getMax().getY() - entityBoundingBox.getMin().getY()) / 2f), -entityBoundingBox.getMin().getZ() * 4f, 1f);
light0.getSpotDirection().set(0f, 0f, 0f).sub(new Vector3(light0.getPosition().getArray()));
light0.setConstantAttenuation(0.5f);
light0.setLinearAttenuation(0f);
light0.setQuadraticAttenuation(0f);
light0.setSpotExponent(0f);
light0.setSpotCutOff(180f);
light0.setEnabled(true);
// model dimension
Vector3 dimension = entityBoundingBox.getMax().clone().sub(entityBoundingBox.getMin());
// determine max dimension on each axis
float maxAxisDimension = computeMaxAxisDimension(entityBoundingBox);
// set up cam
Camera cam = engine.getCamera();
cam.setZNear(maxAxisDimension / 5000f);
cam.setZFar(maxAxisDimension);
// look at
Vector3 lookAt = entityBoundingBox.getMin().clone().add(dimension.clone().scale(0.5f));
cam.getLookAt().set(lookAt);
// look at -> look to vector
Vector3 lookAtToFromVector = new Vector3(0f, 0f, +(maxAxisDimension * 1.2f));
// apply look from rotations
Vector3 lookAtToFromVectorTransformed = new Vector3();
Vector3 lookAtToFromVectorScaled = new Vector3();
Vector3 upVector = new Vector3();
lookFromRotations.getTransformationsMatrix().multiply(lookAtToFromVector, lookAtToFromVectorTransformed);
lookAtToFromVectorScaled.set(lookAtToFromVectorTransformed).scale(scale);
lookFromRotations.getRotations().get(2).getQuaternion().multiply(new Vector3(0f, 1f, 0f), upVector);
// look from with rotations
Vector3 lookFrom = lookAt.clone().add(lookAtToFromVectorScaled);
cam.getLookFrom().set(lookFrom);
// up vector
cam.getUpVector().set(upVector);
}
Aggregations