Beispiel #1
0
void Heuristic::addCollisionBounds(const Bounds& collisionBounds) {
	class Expander {
	public:
		const Real skinThickness;

		Expander(Real skinThickness) : skinThickness(skinThickness) {
		}

		Bounds::Ptr expand(const Bounds &bounds) const {
			Bounds::Ptr pBounds;

			switch (bounds.getType()) {
			case Bounds::TYPE_PLANE:
				pBounds = expand(dynamic_cast<const BoundingPlane&>(bounds));
				break;
			case Bounds::TYPE_SPHERE:
				pBounds = expand(dynamic_cast<const BoundingSphere&>(bounds));
				break;
			case Bounds::TYPE_CYLINDER:
				pBounds = expand(dynamic_cast<const BoundingCylinder&>(bounds));
				break;
			case Bounds::TYPE_BOX:
				pBounds = expand(dynamic_cast<const BoundingBox&>(bounds));
				break;
			case Bounds::TYPE_CONVEX_MESH:
				pBounds = expand(dynamic_cast<const BoundingConvexMesh&>(bounds));
				break;
			default:
				break;
			}

			return pBounds;
		}

		Bounds::Ptr expand(const BoundingPlane &bounds) const {
			BoundingPlane::Desc desc;
			desc.normal = bounds.getNormal();
			desc.distance = bounds.getDistance();// + skinThickness;
			return desc.create();
		}

		Bounds::Ptr expand(const BoundingSphere &bounds) const {
			BoundingSphere::Desc desc;
			desc.pose = bounds.getPose();
			desc.radius = bounds.getRadius() + skinThickness;
			return desc.create();
		}

		Bounds::Ptr expand(const BoundingCylinder &bounds) const {
			BoundingCylinder::Desc desc;
			desc.pose = bounds.getPose();
			desc.length = bounds.getLength() + REAL_TWO*skinThickness;
			desc.radius = bounds.getRadius() + skinThickness;
			return desc.create();
		}

		Bounds::Ptr expand(const BoundingBox &bounds) const {
			BoundingBox::Desc desc;
			desc.pose = bounds.getPose();
			desc.dimensions.set(
				bounds.getDimensions().v1 + skinThickness,
				bounds.getDimensions().v2 + skinThickness,
				bounds.getDimensions().v3 + skinThickness
			);
			return desc.create();
		}

		Bounds::Ptr expand(const BoundingConvexMesh &bounds) const {
			BoundingConvexMesh::Desc desc;

			const U32 numOfVertices = (U32)bounds.getVertices().size();
			desc.vertices.resize(numOfVertices);

			Vec3 centroid(REAL_ZERO);
			for (U32 i = 0; i < numOfVertices; ++i)
				centroid.add(centroid, bounds.getVertices()[i]);
			centroid.multiply(REAL_ONE/numOfVertices, centroid);
			
			// expand along lines drawn from centroid to vertices
			for (U32 i = 0; i < numOfVertices; ++i) {
				Vec3 axis;
				axis.subtract(bounds.getVertices()[i], centroid);
				axis.normalise();
				desc.vertices[i].multiplyAdd(skinThickness, axis, bounds.getVertices()[i]);
			}
			
			const U32 numOfTriangles = (U32)bounds.getTriangles().size();

			if (numOfTriangles > 0) {
				desc.bCook = false;
				desc.triangles = bounds.getTriangles();
			}
			else
				desc.bCook = true;
			
			return desc.create();
		}
	};

	// Expand bounds
	Bounds::Ptr pBounds = Expander(desc.collisionDesc.skinThickness).expand(collisionBounds);
	if (pBounds == NULL)
		throw MsgHeuristicBoundsExpand(Message::LEVEL_ERROR, "Heuristic::addCollisionBounds(): unable to create %s", collisionBounds.getName());
	
	//context.debug("Heuristic::setCollisionBounds(): group #%08x, name: %s\n", pBounds->getGroup(), pBounds->getName());

	// add to the collection
	this->collisionBounds.push_back(pBounds);
}