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; }
/** * 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; }
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); } }
/* * 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; }