/* 
 | 
 * Java port of Bullet (c) 2008 Martin Dvorak <jezek2@advel.cz> 
 | 
 * 
 | 
 * Bullet Continuous Collision Detection and Physics Library 
 | 
 * Copyright (c) 2003-2008 Erwin Coumans  http://www.bulletphysics.com/ 
 | 
 * 
 | 
 * This software is provided 'as-is', without any express or implied warranty. 
 | 
 * In no event will the authors be held liable for any damages arising from 
 | 
 * the use of this software. 
 | 
 *  
 | 
 * Permission is granted to anyone to use this software for any purpose,  
 | 
 * including commercial applications, and to alter it and redistribute it 
 | 
 * freely, subject to the following restrictions: 
 | 
 *  
 | 
 * 1. The origin of this software must not be misrepresented; you must not 
 | 
 *    claim that you wrote the original software. If you use this software 
 | 
 *    in a product, an acknowledgment in the product documentation would be 
 | 
 *    appreciated but is not required. 
 | 
 * 2. Altered source versions must be plainly marked as such, and must not be 
 | 
 *    misrepresented as being the original software. 
 | 
 * 3. This notice may not be removed or altered from any source distribution. 
 | 
 */ 
 | 
  
 | 
package com.bulletphysics.collision.shapes; 
 | 
  
 | 
import com.bulletphysics.collision.broadphase.BroadphaseNativeType; 
 | 
import com.bulletphysics.collision.dispatch.CollisionObject; 
 | 
import com.bulletphysics.linearmath.Transform; 
 | 
import cz.advel.stack.Stack; 
 | 
import javax.vecmath.Vector3f; 
 | 
  
 | 
/** 
 | 
 * CollisionShape class provides an interface for collision shapes that can be 
 | 
 * shared among {@link CollisionObject}s. 
 | 
 *  
 | 
 * @author jezek2 
 | 
 */ 
 | 
public abstract class CollisionShape  implements java.io.Serializable { 
 | 
  
 | 
    //protected final BulletStack stack = BulletStack.get(); 
 | 
  
 | 
    protected Object userPointer; 
 | 
     
 | 
    ///getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t. 
 | 
    public abstract void getAabb(Transform t, Vector3f aabbMin, Vector3f aabbMax); 
 | 
  
 | 
    public void getBoundingSphere(Vector3f center, float[] radius) { 
 | 
        Vector3f tmp = Stack.alloc(Vector3f.class); 
 | 
  
 | 
        Transform tr = Stack.alloc(Transform.class); 
 | 
        tr.setIdentity(); 
 | 
        Vector3f aabbMin = Stack.alloc(Vector3f.class), aabbMax = Stack.alloc(Vector3f.class); 
 | 
  
 | 
        getAabb(tr, aabbMin, aabbMax); 
 | 
  
 | 
        tmp.sub(aabbMax, aabbMin); 
 | 
        radius[0] = tmp.length() * 0.5f; 
 | 
  
 | 
        tmp.add(aabbMin, aabbMax); 
 | 
        center.scale(0.5f, tmp); 
 | 
    } 
 | 
  
 | 
    ///getAngularMotionDisc returns the maximus radius needed for Conservative Advancement to handle time-of-impact with rotations. 
 | 
    public float getAngularMotionDisc() { 
 | 
        Vector3f center = Stack.alloc(Vector3f.class); 
 | 
        float[] disc = new float[1]; // TODO: stack 
 | 
        getBoundingSphere(center, disc); 
 | 
        disc[0] += center.length(); 
 | 
        return disc[0]; 
 | 
    } 
 | 
  
 | 
    ///calculateTemporalAabb calculates the enclosing aabb for the moving object over interval [0..timeStep) 
 | 
    ///result is conservative 
 | 
    public void calculateTemporalAabb(Transform curTrans, Vector3f linvel, Vector3f angvel, float timeStep, Vector3f temporalAabbMin, Vector3f temporalAabbMax) { 
 | 
        //start with static aabb 
 | 
        getAabb(curTrans, temporalAabbMin, temporalAabbMax); 
 | 
  
 | 
        float temporalAabbMaxx = temporalAabbMax.x; 
 | 
        float temporalAabbMaxy = temporalAabbMax.y; 
 | 
        float temporalAabbMaxz = temporalAabbMax.z; 
 | 
        float temporalAabbMinx = temporalAabbMin.x; 
 | 
        float temporalAabbMiny = temporalAabbMin.y; 
 | 
        float temporalAabbMinz = temporalAabbMin.z; 
 | 
  
 | 
        // add linear motion 
 | 
        Vector3f linMotion = (Vector3f) Stack.alloc(linvel); 
 | 
        linMotion.scale(timeStep); 
 | 
  
 | 
        //todo: simd would have a vector max/min operation, instead of per-element access 
 | 
        if (linMotion.x > 0f) { 
 | 
            temporalAabbMaxx += linMotion.x; 
 | 
        } 
 | 
        else { 
 | 
            temporalAabbMinx += linMotion.x; 
 | 
        } 
 | 
        if (linMotion.y > 0f) { 
 | 
            temporalAabbMaxy += linMotion.y; 
 | 
        } 
 | 
        else { 
 | 
            temporalAabbMiny += linMotion.y; 
 | 
        } 
 | 
        if (linMotion.z > 0f) { 
 | 
            temporalAabbMaxz += linMotion.z; 
 | 
        } 
 | 
        else { 
 | 
            temporalAabbMinz += linMotion.z; 
 | 
        } 
 | 
  
 | 
        //add conservative angular motion 
 | 
        float angularMotion = angvel.length() * getAngularMotionDisc() * timeStep; 
 | 
        Vector3f angularMotion3d = Stack.alloc(Vector3f.class); 
 | 
        angularMotion3d.set(angularMotion, angularMotion, angularMotion); 
 | 
        temporalAabbMin.set(temporalAabbMinx, temporalAabbMiny, temporalAabbMinz); 
 | 
        temporalAabbMax.set(temporalAabbMaxx, temporalAabbMaxy, temporalAabbMaxz); 
 | 
  
 | 
        temporalAabbMin.sub(angularMotion3d); 
 | 
        temporalAabbMax.add(angularMotion3d); 
 | 
    } 
 | 
  
 | 
//#ifndef __SPU__ 
 | 
    public boolean isPolyhedral() { 
 | 
        return getShapeType().isPolyhedral(); 
 | 
    } 
 | 
  
 | 
    public boolean isConvex() { 
 | 
        return getShapeType().isConvex(); 
 | 
    } 
 | 
  
 | 
    public boolean isConcave() { 
 | 
        return getShapeType().isConcave(); 
 | 
    } 
 | 
  
 | 
    public boolean isCompound() { 
 | 
        return getShapeType().isCompound(); 
 | 
    } 
 | 
  
 | 
    ///isInfinite is used to catch simulation error (aabb check) 
 | 
    public boolean isInfinite() { 
 | 
        return getShapeType().isInfinite(); 
 | 
    } 
 | 
  
 | 
    public abstract BroadphaseNativeType getShapeType(); 
 | 
  
 | 
    public abstract void setLocalScaling(Vector3f scaling); 
 | 
     
 | 
    // TODO: returns const 
 | 
    public abstract Vector3f getLocalScaling(Vector3f out); 
 | 
  
 | 
    public abstract void calculateLocalInertia(float mass, Vector3f inertia); 
 | 
  
 | 
  
 | 
//debugging support 
 | 
    public abstract String getName(); 
 | 
//#endif //__SPU__ 
 | 
    public abstract void setMargin(float margin); 
 | 
  
 | 
    public abstract float getMargin(); 
 | 
     
 | 
    // optional user data pointer 
 | 
    public void setUserPointer(Object userPtr) { 
 | 
        userPointer = userPtr; 
 | 
    } 
 | 
  
 | 
    public Object getUserPointer() { 
 | 
        return userPointer; 
 | 
    } 
 | 
     
 | 
} 
 |