package rajawali.bounds; import java.nio.FloatBuffer; import rajawali.BaseObject3D; import rajawali.Camera; import rajawali.Geometry3D; import rajawali.materials.SimpleMaterial; import rajawali.math.Number3D; import rajawali.primitives.Sphere; import android.opengl.GLES20; import android.opengl.Matrix; public class BoundingSphere implements IBoundingVolume { protected Geometry3D mGeometry; protected float mRadius; protected Number3D mPosition; protected Sphere mVisualSphere; protected float[] mTmpMatrix = new float[16]; protected Number3D mTmpPos; protected float mDist, mMinDist, mScale; protected float[] mScaleValues; public BoundingSphere() { super(); mPosition = new Number3D(); mTmpPos = new Number3D(); mScaleValues = new float[3]; } public BoundingSphere(Geometry3D geometry) { this(); mGeometry = geometry; calculateBounds(mGeometry); } public BaseObject3D getVisual() { return mVisualSphere; } public void drawBoundingVolume(Camera camera, float[] projMatrix, float[] vMatrix, float[] mMatrix) { if(mVisualSphere == null) { mVisualSphere = new Sphere(1, 8, 8); mVisualSphere.setMaterial(new SimpleMaterial()); mVisualSphere.getMaterial().setUseColor(true); mVisualSphere.setColor(0xffffff00); mVisualSphere.setDrawingMode(GLES20.GL_LINE_LOOP); } Matrix.setIdentityM(mTmpMatrix, 0); mVisualSphere.setPosition(mPosition); mVisualSphere.setScale(mRadius * mScale); mVisualSphere.render(camera, projMatrix, vMatrix, mTmpMatrix, null); } public void transform(float[] matrix) { mPosition.setAll(0, 0, 0); mPosition.multiply(matrix); mTmpPos.setAll(matrix[0], matrix[1], matrix[2]); mScaleValues[0] = mTmpPos.length(); mTmpPos.setAll(matrix[4], matrix[5], matrix[6]); mScaleValues[1] = mTmpPos.length(); mTmpPos.setAll(matrix[8], matrix[9], matrix[10]); mScaleValues[2] = mTmpPos.length(); mScale = mScaleValues[0] > mScaleValues[1] ? mScaleValues[0] : mScaleValues[1]; mScale = mScale > mScaleValues[2] ? mScale : mScaleValues[2]; } public void calculateBounds(Geometry3D geometry) { float radius = 0, maxRadius = 0; Number3D vertex = new Number3D(); FloatBuffer vertices = geometry.getVertices(); vertices.rewind(); while(vertices.hasRemaining()) { vertex.x = vertices.get(); vertex.y = vertices.get(); vertex.z = vertices.get(); radius = vertex.length(); if(radius > maxRadius) maxRadius = radius; } mRadius = maxRadius; } public float getRadius() { return mRadius; } public Number3D getPosition() { return mPosition; } public float getScale() { return mScale; } public boolean intersectsWith(IBoundingVolume boundingVolume) { if(!(boundingVolume instanceof BoundingSphere)) return false; BoundingSphere boundingSphere = (BoundingSphere)boundingVolume; mTmpPos.setAllFrom(mPosition); mTmpPos.subtract(boundingSphere.getPosition()); mDist = mTmpPos.x * mTmpPos.x + mTmpPos.y * mTmpPos.y + mTmpPos.z * mTmpPos.z; mMinDist = mRadius * mScale + boundingSphere.getRadius() * boundingSphere.getScale(); return mDist < mMinDist * mMinDist; } }