bool Obj::GroundCheck(IN OUT D3DXVECTOR3& groundPos) const
{
	bool find = false;
	D3DXVECTOR3 rayStart(groundPos.x, 1000.0f, groundPos.z);
	D3DXVECTOR3 rayDirection(0, -1, 0);
	for (size_t i = 0; i < objGround.size(); i += 3)
	{
		float u, v, distance;
		find = D3DXIntersectTri(
			&objGround[i],
			&objGround[i + 1],
			&objGround[i + 2],
			&rayStart,
			&rayDirection,
			&u, &v,
			&distance) != 0;
		if (find == true)
		{
			groundPos.y = 1000.0f - distance;
			//groundPos = objGround[i] + ( ( objGround[i + 1] - objGround[i] ) * u ) + ( ( objGround[i + 2] - objGround[i] ) * v );
			break;
		}
	}
	return find;
}
//--------------------------------------------------------------
ofxBulletRaycastData ofxBulletWorldRigid::raycastTest( ofVec3f a_rayStart, ofVec3f a_rayEnd, short int a_filterMask) {
    ofxBulletRaycastData data;
    data.bHasHit = false;

    btVector3 rayStart( a_rayStart.x, a_rayStart.y, a_rayStart.z );
    btVector3 rayEnd( a_rayEnd.x, a_rayEnd.y, a_rayEnd.z );

    btCollisionWorld::ClosestRayResultCallback rayCallback( rayStart, rayEnd );
    rayCallback.m_collisionFilterMask = a_filterMask;
    world->rayTest( rayStart, rayEnd, rayCallback );

    if (rayCallback.hasHit()) {
        btRigidBody* body = btRigidBody::upcast( (btCollisionObject*)rayCallback.m_collisionObject );
        if (body) {
            data.bHasHit			= true;
            data.userData			= (ofxBulletUserData*)body->getUserPointer();
            data.body				= body;
            data.rayWorldPos		= a_rayEnd;
            btVector3 pickPos		= rayCallback.m_hitPointWorld;
            data.pickPosWorld		= ofVec3f(pickPos.getX(), pickPos.getY(), pickPos.getZ());
            btVector3 localPos		= body->getCenterOfMassTransform().inverse() * pickPos;
            data.localPivotPos		= ofVec3f(localPos.getX(), localPos.getY(), localPos.getZ() );
        }
    }
    return data;
}
Vector<float>* CollisionManager::getCellFloorCollision(float x, float y, CellObject* cellObject) {
	Vector<float>* collisions = NULL;

	ManagedReference<SceneObject*> rootObject = cellObject->getRootParent();

	if (rootObject == NULL)
		return NULL;

	SharedObjectTemplate* templateObject = rootObject->getObjectTemplate();

	if (templateObject == NULL)
		return NULL;

	PortalLayout* portalLayout = templateObject->getPortalLayout();

	if (portalLayout == NULL)
		return NULL;

	FloorMesh* mesh = portalLayout->getFloorMesh(cellObject->getCellNumber());

	if (mesh == NULL)
		return NULL;

	AABBTree* tree = mesh->getAABBTree();

	if (tree == NULL)
		return NULL;

	Vector3 rayStart(x, 16384.f, y);
	Vector3 rayEnd(x, -16384.f, y);

	Vector3 norm = rayEnd - rayStart;
	norm.normalize();

	Ray ray(rayStart, norm);

	SortedVector<IntersectionResult> results(3, 2);

	tree->intersects(ray, 16384 * 2, results);

	if (results.size() == 0)
		return NULL;

	collisions = new Vector<float>(results.size(), 1);

	for (int i = 0; i < results.size(); ++i) {
		float floorHeight = 16384 - results.get(i).getIntersectionDistance();

		collisions->add(floorHeight);
	}

	return collisions;
}
Example #4
0
/**
 * Picks a single scene object from the scene. If the object has a mesh collider, the picker will calculate the
 * texture coordinates and barycentric coordinates of the corresponding hit-point. Note that this will do nothing
 * if the scene object doesn't have a collider.
 */
void Picker::pickSceneObject(const SceneObject *scene_object, float ox, float oy, float oz, float dx, float dy, float dz, ColliderData &colliderData){
    Collider* collider = scene_object->collider();
    if(collider == nullptr){
        return;
    }
    else if (collider->enabled() && scene_object->enabled()) {
        glm::vec3 rayStart(ox, oy, oz);
        glm::vec3 rayDir(dx, dy, dz);

        colliderData = collider->isHit(rayStart, rayDir);
    }
}
//--------------------------------------------------------------
ofxBulletRaycastData ofxBulletWorldSoft::raycastTest( ofVec3f a_rayStart, ofVec3f a_rayEnd, short int a_filterMask) {
	ofxBulletRaycastData data;
	data.bHasHit = false;
	if(_camera == NULL) {
		ofLog( OF_LOG_ERROR, "ofxBulletWorldSoft :: raycastTest : must set the camera first!!");
		return data;
	}
	
	btVector3 rayStart( a_rayStart.x, a_rayStart.y, a_rayStart.z );
	btVector3 rayEnd( a_rayEnd.x, a_rayEnd.y, a_rayEnd.z );
	
	btCollisionWorld::ClosestRayResultCallback rayCallback( rayStart, rayEnd );
	rayCallback.m_collisionFilterMask = a_filterMask;
	world->rayTest( rayStart, rayEnd, rayCallback );
	
	if (rayCallback.hasHit()) {
		if ( rayCallback.m_collisionObject->getInternalType() & btCollisionObject::CO_SOFT_BODY ) {
			// cast a ray into the soft body to get the point exactly
			//ofLogNotice("ofxBulletWorldSoft: soft body intersection");
			btSoftBody::sRayCast result;
#warning Casting (const btSoftBody*) to (btSoftBody*) -- not necessarily safe
			btSoftBody* body = (btSoftBody*)btSoftBody::upcast( rayCallback.m_collisionObject );
			if ( body->rayTest( rayStart, rayEnd, result ) ) {
				if ( result.fraction<1.0f ) {
					//ofLogNotice("ofxBulletWorldSoft") << "    at " << result.getFeatureName() << " index " << result.index;
				}
			}
			
		}
		else {
#warning Casting (const btRigidBody*) to (btRigidBody*) -- not necessarily safe
			btRigidBody* body = (btRigidBody*)btRigidBody::upcast(rayCallback.m_collisionObject);
			if (body) {
				data.bHasHit			= true;
				data.userData			= (ofxBulletUserData*)body->getUserPointer();
				data.body				= body;
				data.rayWorldPos		= a_rayEnd;
				btVector3 pickPos		= rayCallback.m_hitPointWorld;
				data.pickPosWorld		= ofVec3f(pickPos.getX(), pickPos.getY(), pickPos.getZ());
				btVector3 localPos		= body->getCenterOfMassTransform().inverse() * pickPos;
				data.localPivotPos		= ofVec3f(localPos.getX(), localPos.getY(), localPos.getZ() );
			}
		}
	}
	return data;
}
Example #6
0
void CollisionManager::getWorldFloorCollisions(float x, float y, Zone* zone, SortedVector<IntersectionResult>* result, const Vector<QuadTreeEntry*>& inRangeObjects) {
	Vector3 rayStart(x, 16384.f, y);
	Vector3 rayEnd(x, -16384.f, y);

	for (int i = 0; i < inRangeObjects.size(); ++i) {
		SceneObject* sceno = static_cast<SceneObject*>(inRangeObjects.get(i));

		AABBTree* aabbTree = getAABBTree(sceno, 255);

		if (aabbTree == NULL)
			continue;

		Ray ray = convertToModelSpace(rayStart, rayEnd, sceno);

		aabbTree->intersects(ray, 16384 * 2, *result);
	}
}
Example #7
0
/*
 * Pick against the scene bounding box.
 * The input ray is in world coordinates.
 * To pick against the bounding box, we create a bounding box mesh
 * from the original mesh. This new mesh is in mesh coordinates
 * so we must apply the inverse of the model matrix from the scene object
 * to the ray to put it into mesh coordinates.
 */
glm::vec3 Picker::pickSceneObjectAgainstBoundingBox(const SceneObject* scene_object, float ox, float oy, float oz, float dx, float dy, float dz) {
    RenderData* rd = scene_object->render_data();

    if ((rd == NULL) || (rd->mesh() == NULL)) {
        return glm::vec3(std::numeric_limits<float>::infinity());
    }
    glm::mat4 model_inverse = glm::affineInverse(scene_object->transform()->getModelMatrix());
    const BoundingVolume& bounds = rd->mesh()->getBoundingVolume();
    glm::vec3 rayStart(ox, oy, oz);
    glm::vec3 rayDir(dx, dy, dz);

    glm::normalize(rayDir);
    Collider::transformRay(model_inverse, rayStart, rayDir);
    ColliderData data = MeshCollider::isHit(bounds, rayStart, rayDir);
    if (data.IsHit) {
        return data.HitPosition;
    }
    return glm::vec3(std::numeric_limits<float>::infinity());
}
bool HeightMap::OnTheGround(D3DXVECTOR3& pos, const D3DXVECTOR3& p0, const D3DXVECTOR3& p1, const D3DXVECTOR3& p2)
{
	bool find = false;

	D3DXVECTOR3 rayStart(pos.x, 1000.0f, pos.z);
	D3DXVECTOR3 rayDirection(0, -1, 0);

	float u, v, distance;
	find = D3DXIntersectTri(
		&p0, &p1, &p2,
		&rayStart, &rayDirection,
		&u, &v, &distance) != 0;

	if (find == true)
	{
		pos.y = 1000.0f - distance;

		//pos = p0 + (p1 - p0) * u + (p2 - p0) * v;
	}

	return find;
}
float CollisionManager::getWorldFloorCollision(float x, float y, Zone* zone, bool testWater) {
	SortedVector<ManagedReference<QuadTreeEntry*> > closeObjects;
	zone->getInRangeObjects(x, y, 128, &closeObjects, true);

	PlanetManager* planetManager = zone->getPlanetManager();

	if (planetManager == NULL)
		return 0.f;

	float height = 0;

	TerrainManager* terrainManager = planetManager->getTerrainManager();

	//need to include exclude affectors in the terrain calcs
	height = terrainManager->getHeight(x, y);

	Vector3 rayStart(x, 16384.f, y);
	Vector3 rayEnd(x, -16384.f, y);

	Triangle* triangle = NULL;

	if (testWater) {
		float waterHeight;

		if (terrainManager->getWaterHeight(x, y, waterHeight))
			if (waterHeight > height)
				height = waterHeight;
	}

	float intersectionDistance;

	for (int i = 0; i < closeObjects.size(); ++i) {
		BuildingObject* building = dynamic_cast<BuildingObject*>(closeObjects.get(i).get());

		if (building == NULL)
			continue;

		//building->getObjectTemplate()->get

		SharedObjectTemplate* templateObject = building->getObjectTemplate();

		if (templateObject == NULL)
			continue;

		PortalLayout* portalLayout = templateObject->getPortalLayout();

		if (portalLayout == NULL)
			continue;

		if (portalLayout->getFloorMeshNumber() == 0)
			continue;

		//find nearest entrance
		FloorMesh* exteriorFloorMesh = portalLayout->getFloorMesh(0); // get outside layout
		AABBTree* aabbTree = exteriorFloorMesh->getAABBTree();

		if (aabbTree == NULL)
			continue;

		Ray ray = convertToModelSpace(rayStart, rayEnd, building);

		if (aabbTree->intersects(ray, 16384 * 2, intersectionDistance, triangle, true)) {
			float floorHeight = 16384 - intersectionDistance;

			if (floorHeight > height)
				height = floorHeight;
		}
	}

	return height;
}