Package com.bulletphysics.collision.shapes

Source Code of com.bulletphysics.collision.shapes.BoxShape

/*
* 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.dynamics.RigidBody;
import com.bulletphysics.linearmath.AabbUtil2;
import com.bulletphysics.linearmath.ScalarUtil;
import com.bulletphysics.linearmath.Transform;
import com.bulletphysics.linearmath.VectorUtil;
import cz.advel.stack.Stack;
import javax.vecmath.Vector3f;
import javax.vecmath.Vector4f;

/**
* BoxShape is a box primitive around the origin, its sides axis aligned with length
* specified by half extents, in local shape coordinates. When used as part of a
* {@link CollisionObject} or {@link RigidBody} it will be an oriented box in world space.
*
* @author jezek2
*/
public class BoxShape extends PolyhedralConvexShape {

  public BoxShape(Vector3f boxHalfExtents) {
    Vector3f margin = new Vector3f(getMargin(), getMargin(), getMargin());
    VectorUtil.mul(implicitShapeDimensions, boxHalfExtents, localScaling);
    implicitShapeDimensions.sub(margin);
  }

  public Vector3f getHalfExtentsWithMargin(Vector3f out) {
    Vector3f halfExtents = getHalfExtentsWithoutMargin(out);
    Vector3f margin = Stack.alloc(Vector3f.class);
    margin.set(getMargin(), getMargin(), getMargin());
    halfExtents.add(margin);
    return out;
  }

  public Vector3f getHalfExtentsWithoutMargin(Vector3f out) {
    out.set(implicitShapeDimensions); // changed in Bullet 2.63: assume the scaling and margin are included
    return out;
  }

  @Override
  public BroadphaseNativeType getShapeType() {
    return BroadphaseNativeType.BOX_SHAPE_PROXYTYPE;
  }

  @Override
  public Vector3f localGetSupportingVertex(Vector3f vec, Vector3f out) {
    Vector3f halfExtents = getHalfExtentsWithoutMargin(out);
   
    float margin = getMargin();
    halfExtents.x += margin;
    halfExtents.y += margin;
    halfExtents.z += margin;

    out.set(
        ScalarUtil.fsel(vec.x, halfExtents.x, -halfExtents.x),
        ScalarUtil.fsel(vec.y, halfExtents.y, -halfExtents.y),
        ScalarUtil.fsel(vec.z, halfExtents.z, -halfExtents.z));
    return out;
  }

  @Override
  public Vector3f localGetSupportingVertexWithoutMargin(Vector3f vec, Vector3f out) {
    Vector3f halfExtents = getHalfExtentsWithoutMargin(out);

    out.set(
        ScalarUtil.fsel(vec.x, halfExtents.x, -halfExtents.x),
        ScalarUtil.fsel(vec.y, halfExtents.y, -halfExtents.y),
        ScalarUtil.fsel(vec.z, halfExtents.z, -halfExtents.z));
    return out;
  }

  @Override
  public void batchedUnitVectorGetSupportingVertexWithoutMargin(Vector3f[] vectors, Vector3f[] supportVerticesOut, int numVectors) {
    Vector3f halfExtents = getHalfExtentsWithoutMargin(Stack.alloc(Vector3f.class));

    for (int i = 0; i < numVectors; i++) {
      Vector3f vec = vectors[i];
      supportVerticesOut[i].set(ScalarUtil.fsel(vec.x, halfExtents.x, -halfExtents.x),
          ScalarUtil.fsel(vec.y, halfExtents.y, -halfExtents.y),
          ScalarUtil.fsel(vec.z, halfExtents.z, -halfExtents.z));
    }
  }

  @Override
  public void setMargin(float margin) {
    // correct the implicitShapeDimensions for the margin
    Vector3f oldMargin = Stack.alloc(Vector3f.class);
    oldMargin.set(getMargin(), getMargin(), getMargin());
    Vector3f implicitShapeDimensionsWithMargin = Stack.alloc(Vector3f.class);
    implicitShapeDimensionsWithMargin.add(implicitShapeDimensions, oldMargin);

    super.setMargin(margin);
    Vector3f newMargin = Stack.alloc(Vector3f.class);
    newMargin.set(getMargin(), getMargin(), getMargin());
    implicitShapeDimensions.sub(implicitShapeDimensionsWithMargin, newMargin);
  }

  @Override
  public void setLocalScaling(Vector3f scaling) {
    Vector3f oldMargin = Stack.alloc(Vector3f.class);
    oldMargin.set(getMargin(), getMargin(), getMargin());
    Vector3f implicitShapeDimensionsWithMargin = Stack.alloc(Vector3f.class);
    implicitShapeDimensionsWithMargin.add(implicitShapeDimensions, oldMargin);
    Vector3f unScaledImplicitShapeDimensionsWithMargin = Stack.alloc(Vector3f.class);
    VectorUtil.div(unScaledImplicitShapeDimensionsWithMargin, implicitShapeDimensionsWithMargin, localScaling);

    super.setLocalScaling(scaling);

    VectorUtil.mul(implicitShapeDimensions, unScaledImplicitShapeDimensionsWithMargin, localScaling);
    implicitShapeDimensions.sub(oldMargin);
  }

  @Override
  public void getAabb(Transform t, Vector3f aabbMin, Vector3f aabbMax) {
    AabbUtil2.transformAabb(getHalfExtentsWithoutMargin(Stack.alloc(Vector3f.class)), getMargin(), t, aabbMin, aabbMax);
  }

  @Override
  public void calculateLocalInertia(float mass, Vector3f inertia) {
    //btScalar margin = btScalar(0.);
    Vector3f halfExtents = getHalfExtentsWithMargin(Stack.alloc(Vector3f.class));

    float lx = 2f * halfExtents.x;
    float ly = 2f * halfExtents.y;
    float lz = 2f * halfExtents.z;

    inertia.set(mass / 12f * (ly * ly + lz * lz),
        mass / 12f * (lx * lx + lz * lz),
        mass / 12f * (lx * lx + ly * ly));
  }

  @Override
  public void getPlane(Vector3f planeNormal, Vector3f planeSupport, int i) {
    // this plane might not be aligned...
    Vector4f plane = Stack.alloc(Vector4f.class);
    getPlaneEquation(plane, i);
    planeNormal.set(plane.x, plane.y, plane.z);
    Vector3f tmp = Stack.alloc(Vector3f.class);
    tmp.negate(planeNormal);
    localGetSupportingVertex(tmp, planeSupport);
  }

  @Override
  public int getNumPlanes() {
    return 6;
  }

  @Override
  public int getNumVertices() {
    return 8;
  }

  @Override
  public int getNumEdges() {
    return 12;
  }

  @Override
  public void getVertex(int i, Vector3f vtx) {
    Vector3f halfExtents = getHalfExtentsWithoutMargin(Stack.alloc(Vector3f.class));

    vtx.set(halfExtents.x * (1 - (i & 1)) - halfExtents.x * (i & 1),
        halfExtents.y * (1 - ((i & 2) >> 1)) - halfExtents.y * ((i & 2) >> 1),
        halfExtents.z * (1 - ((i & 4) >> 2)) - halfExtents.z * ((i & 4) >> 2));
  }
 
  public void getPlaneEquation(Vector4f plane, int i) {
    Vector3f halfExtents = getHalfExtentsWithoutMargin(Stack.alloc(Vector3f.class));

    switch (i) {
      case 0:
        plane.set(1f, 0f, 0f, -halfExtents.x);
        break;
      case 1:
        plane.set(-1f, 0f, 0f, -halfExtents.x);
        break;
      case 2:
        plane.set(0f, 1f, 0f, -halfExtents.y);
        break;
      case 3:
        plane.set(0f, -1f, 0f, -halfExtents.y);
        break;
      case 4:
        plane.set(0f, 0f, 1f, -halfExtents.z);
        break;
      case 5:
        plane.set(0f, 0f, -1f, -halfExtents.z);
        break;
      default:
        assert (false);
    }
  }

  @Override
  public void getEdge(int i, Vector3f pa, Vector3f pb) {
    int edgeVert0 = 0;
    int edgeVert1 = 0;

    switch (i) {
      case 0:
        edgeVert0 = 0;
        edgeVert1 = 1;
        break;
      case 1:
        edgeVert0 = 0;
        edgeVert1 = 2;
        break;
      case 2:
        edgeVert0 = 1;
        edgeVert1 = 3;

        break;
      case 3:
        edgeVert0 = 2;
        edgeVert1 = 3;
        break;
      case 4:
        edgeVert0 = 0;
        edgeVert1 = 4;
        break;
      case 5:
        edgeVert0 = 1;
        edgeVert1 = 5;

        break;
      case 6:
        edgeVert0 = 2;
        edgeVert1 = 6;
        break;
      case 7:
        edgeVert0 = 3;
        edgeVert1 = 7;
        break;
      case 8:
        edgeVert0 = 4;
        edgeVert1 = 5;
        break;
      case 9:
        edgeVert0 = 4;
        edgeVert1 = 6;
        break;
      case 10:
        edgeVert0 = 5;
        edgeVert1 = 7;
        break;
      case 11:
        edgeVert0 = 6;
        edgeVert1 = 7;
        break;
      default:
        assert (false);
    }

    getVertex(edgeVert0, pa);
    getVertex(edgeVert1, pb);
  }

  @Override
  public boolean isInside(Vector3f pt, float tolerance) {
    Vector3f halfExtents = getHalfExtentsWithoutMargin(Stack.alloc(Vector3f.class));

    //btScalar minDist = 2*tolerance;

    boolean result =
        (pt.x <= (halfExtents.x + tolerance)) &&
        (pt.x >= (-halfExtents.x - tolerance)) &&
        (pt.y <= (halfExtents.y + tolerance)) &&
        (pt.y >= (-halfExtents.y - tolerance)) &&
        (pt.z <= (halfExtents.z + tolerance)) &&
        (pt.z >= (-halfExtents.z - tolerance));

    return result;
  }

  @Override
  public String getName() {
    return "Box";
  }

  @Override
  public int getNumPreferredPenetrationDirections() {
    return 6;
  }

  @Override
  public void getPreferredPenetrationDirection(int index, Vector3f penetrationVector) {
    switch (index) {
      case 0:
        penetrationVector.set(1f, 0f, 0f);
        break;
      case 1:
        penetrationVector.set(-1f, 0f, 0f);
        break;
      case 2:
        penetrationVector.set(0f, 1f, 0f);
        break;
      case 3:
        penetrationVector.set(0f, -1f, 0f);
        break;
      case 4:
        penetrationVector.set(0f, 0f, 1f);
        break;
      case 5:
        penetrationVector.set(0f, 0f, -1f);
        break;
      default:
        assert (false);
    }
  }

}
TOP

Related Classes of com.bulletphysics.collision.shapes.BoxShape

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.