use of org.terasology.math.AABB in project Terasology by MovingBlocks.
the class MeshRenderer method renderEntitiesByMaterial.
private void renderEntitiesByMaterial(SetMultimap<Material, EntityRef> meshByMaterial) {
Vector3f cameraPosition = worldRenderer.getActiveCamera().getPosition();
Quat4f worldRot = new Quat4f();
Vector3f worldPos = new Vector3f();
FloatBuffer tempMatrixBuffer44 = BufferUtils.createFloatBuffer(16);
FloatBuffer tempMatrixBuffer33 = BufferUtils.createFloatBuffer(12);
for (Material material : meshByMaterial.keySet()) {
if (material.isRenderable()) {
OpenGLMesh lastMesh = null;
material.enable();
material.setFloat("sunlight", 1.0f, true);
material.setFloat("blockLight", 1.0f, true);
material.setMatrix4("projectionMatrix", worldRenderer.getActiveCamera().getProjectionMatrix(), true);
material.bindTextures();
Set<EntityRef> entities = meshByMaterial.get(material);
lastRendered = entities.size();
for (EntityRef entity : entities) {
MeshComponent meshComp = entity.getComponent(MeshComponent.class);
LocationComponent location = entity.getComponent(LocationComponent.class);
if (isHidden(entity, meshComp) || location == null || meshComp.mesh == null || !isRelevant(entity, location.getWorldPosition())) {
continue;
}
if (meshComp.mesh.isDisposed()) {
logger.error("Attempted to render disposed mesh");
continue;
}
location.getWorldRotation(worldRot);
location.getWorldPosition(worldPos);
float worldScale = location.getWorldScale();
Transform toWorldSpace = new Transform(worldPos, worldRot, worldScale);
Vector3f offsetFromCamera = new Vector3f();
offsetFromCamera.sub(worldPos, cameraPosition);
Matrix4f matrixCameraSpace = new Matrix4f(worldRot, offsetFromCamera, worldScale);
AABB aabb = meshComp.mesh.getAABB().transform(toWorldSpace);
if (worldRenderer.getActiveCamera().hasInSight(aabb)) {
if (meshComp.mesh != lastMesh) {
if (lastMesh != null) {
lastMesh.postRender();
}
lastMesh = (OpenGLMesh) meshComp.mesh;
lastMesh.preRender();
}
Matrix4f modelViewMatrix = MatrixUtils.calcModelViewMatrix(worldRenderer.getActiveCamera().getViewMatrix(), matrixCameraSpace);
MatrixUtils.matrixToFloatBuffer(modelViewMatrix, tempMatrixBuffer44);
MatrixUtils.matrixToFloatBuffer(MatrixUtils.calcNormalMatrix(modelViewMatrix), tempMatrixBuffer33);
material.setMatrix4("projectionMatrix", worldRenderer.getActiveCamera().getProjectionMatrix(), true);
material.setMatrix4("worldViewMatrix", tempMatrixBuffer44, true);
material.setMatrix3("normalMatrix", tempMatrixBuffer33, true);
material.setFloat3("colorOffset", meshComp.color.rf(), meshComp.color.gf(), meshComp.color.bf(), true);
material.setFloat("sunlight", worldRenderer.getMainLightIntensityAt(worldPos), true);
material.setFloat("blockLight", Math.max(worldRenderer.getBlockLightIntensityAt(worldPos), meshComp.selfLuminance), true);
lastMesh.doRender();
}
}
if (lastMesh != null) {
lastMesh.postRender();
}
}
}
}
use of org.terasology.math.AABB in project Terasology by MovingBlocks.
the class PlayerFactory method getHeightOf.
private float getHeightOf(ComponentContainer prefab) {
BoxShapeComponent box = prefab.getComponent(BoxShapeComponent.class);
if (box != null) {
return box.extents.getY();
}
CylinderShapeComponent cylinder = prefab.getComponent(CylinderShapeComponent.class);
if (cylinder != null) {
return cylinder.height;
}
CapsuleShapeComponent capsule = prefab.getComponent(CapsuleShapeComponent.class);
if (capsule != null) {
return capsule.height;
}
SphereShapeComponent sphere = prefab.getComponent(SphereShapeComponent.class);
if (sphere != null) {
return sphere.radius * 2.0f;
}
HullShapeComponent hull = prefab.getComponent(HullShapeComponent.class);
if (hull != null) {
AABB aabb = hull.sourceMesh.getAABB();
return aabb.maxY() - aabb.minY();
}
logger.warn("entity {} does not have any known extent specification - using default", prefab);
return 1.0f;
}
use of org.terasology.math.AABB in project Terasology by MovingBlocks.
the class SkeletalMeshDataBuilder method build.
public SkeletalMeshData build() {
int rootBones = 0;
for (Bone bone : bones) {
if (bone.getParent() == null) {
rootBones++;
}
}
if (rootBones == 0) {
throw new IllegalStateException("Cannot create a skeleton with no root bones");
} else if (rootBones > 1) {
throw new IllegalStateException("Cannot create a skeleton with multiple root bones");
}
AABB staticAabb;
if (minOfAABB != null && maxOfAABB != null) {
staticAabb = AABB.createMinMax(minOfAABB, maxOfAABB);
} else {
staticAabb = AABB.createEmpty();
}
return new SkeletalMeshData(bones, weights, uvs, vertexStartWeights, vertexWeightCounts, indices, staticAabb);
}
use of org.terasology.math.AABB in project Terasology by MovingBlocks.
the class AbstractStorageManager method getEntitiesOfChunk.
protected Collection<EntityRef> getEntitiesOfChunk(Chunk chunk) {
List<EntityRef> entitiesToStore = Lists.newArrayList();
AABB aabb = chunk.getAABB();
for (EntityRef entity : getEntityManager().getEntitiesWith(LocationComponent.class)) {
if (!entity.getOwner().exists() && !entity.isAlwaysRelevant() && !entity.hasComponent(ClientComponent.class)) {
LocationComponent loc = entity.getComponent(LocationComponent.class);
if (loc != null) {
if (aabb.contains(loc.getWorldPosition())) {
entitiesToStore.add(entity);
}
}
}
}
return entitiesToStore;
}
use of org.terasology.math.AABB in project Terasology by MovingBlocks.
the class BlockItemSystem method canPlaceBlock.
private boolean canPlaceBlock(Block block, Vector3i targetBlock, Vector3i blockPos) {
if (block == null) {
return false;
}
Block centerBlock = worldProvider.getBlock(targetBlock.x, targetBlock.y, targetBlock.z);
if (!centerBlock.isAttachmentAllowed()) {
return false;
}
Block adjBlock = worldProvider.getBlock(blockPos.x, blockPos.y, blockPos.z);
if (!adjBlock.isReplacementAllowed() || adjBlock.isTargetable()) {
return false;
}
if (block.getBlockFamily().equals(adjBlock.getBlockFamily())) {
return false;
}
// Prevent players from placing blocks inside their bounding boxes
if (!block.isPenetrable()) {
Physics physics = CoreRegistry.get(Physics.class);
AABB blockBounds = block.getBounds(blockPos);
Vector3f min = new Vector3f(blockBounds.getMin());
Vector3f max = new Vector3f(blockBounds.getMax());
/**
* Characters can enter other solid objects/blocks for certain amount. This is does to detect collsion
* start and end without noise. So if the user walked as close to a block as possible it is only natural
* to let it place a block exactly above it even if that technically would mean a collision start.
*/
min.x += KinematicCharacterMover.HORIZONTAL_PENETRATION;
max.x -= KinematicCharacterMover.HORIZONTAL_PENETRATION;
min.y += KinematicCharacterMover.VERTICAL_PENETRATION;
max.y -= KinematicCharacterMover.VERTICAL_PENETRATION;
min.z += KinematicCharacterMover.HORIZONTAL_PENETRATION;
max.z -= KinematicCharacterMover.HORIZONTAL_PENETRATION;
/*
* Calculations aren't exact and in the corner cases it is better to let the user place the block.
*/
// ignore small rounding mistakes
float additionalAllowedPenetration = 0.04f;
min.add(ADDITIONAL_ALLOWED_PENETRATION, ADDITIONAL_ALLOWED_PENETRATION, ADDITIONAL_ALLOWED_PENETRATION);
max.sub(ADDITIONAL_ALLOWED_PENETRATION, ADDITIONAL_ALLOWED_PENETRATION, ADDITIONAL_ALLOWED_PENETRATION);
AABB newBounds = AABB.createMinMax(min, max);
return physics.scanArea(newBounds, StandardCollisionGroup.DEFAULT, StandardCollisionGroup.CHARACTER).isEmpty();
}
return true;
}
Aggregations