bool ModelInstance::intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool pStopAtFirstHit) const { if (!iModel) { //std::cout << "<object not loaded>\n"; return false; } float time = pRay.intersectionTime(iBound); if (time == G3D::inf()) { // std::cout << "Ray does not hit '" << name << "'\n"; return false; } // std::cout << "Ray crosses bound of '" << name << "'\n"; /* std::cout << "ray from:" << pRay.origin().x << ", " << pRay.origin().y << ", " << pRay.origin().z << " dir:" << pRay.direction().x << ", " << pRay.direction().y << ", " << pRay.direction().z << " t/tmax:" << time << "/" << pMaxDist; std::cout << "\nBound lo:" << iBound.low().x << ", " << iBound.low().y << ", " << iBound.low().z << " hi: " << iBound.high().x << ", " << iBound.high().y << ", " << iBound.high().z << std::endl; */ // child bounds are defined in object space: Vector3 p = iInvRot * (pRay.origin() - iPos) * iInvScale; Ray modRay(p, iInvRot * pRay.direction()); float distance = pMaxDist * iInvScale; bool hit = iModel->IntersectRay(modRay, distance, pStopAtFirstHit); if (hit) { distance *= iScale; pMaxDist = distance; } return hit; }
bool ModelInstance::intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool pStopAtFirstHit) const { if (!iModel) { #ifdef VMAP_DEBUG DEBUG_LOG("<object not loaded>"); #endif return false; } float time = pRay.intersectionTime(iBound); if (time == G3D::inf()) { #ifdef VMAP_DEBUG DEBUG_LOG("Ray does not hit '%s'", name.c_str()); #endif return false; } // child bounds are defined in object space: Vector3 p = iInvRot * (pRay.origin() - iPos) * iInvScale; Ray modRay(p, iInvRot * pRay.direction()); float distance = pMaxDist * iInvScale; bool hit = iModel->IntersectRay(modRay, distance, pStopAtFirstHit); if(hit) { distance *= iScale; pMaxDist = distance; } return hit; }
//========================================================== void SubModel::intersect(const G3D::Ray& pRay, float& pMaxDist, bool pStopAtFirstHit, G3D::Vector3& /*pOutLocation*/, G3D::Vector3& /*pOutNormal*/) const { NodeValueAccess<TreeNode, TriangleBox> vna = NodeValueAccess<TreeNode, TriangleBox>(getTreeNodes(), getTriangles()); IntersectionCallBack<TriangleBox> intersectCallback; Ray relativeRay = Ray::fromOriginAndDirection(pRay.origin() - getBasePosition(), pRay.direction()); #ifdef _DEBUG_VMAPS //p6=getBasePosition(); //gBoxArray.push_back(getAABoxBounds()); #endif getTreeNode(0).intersectRay(relativeRay, intersectCallback, pMaxDist, vna, pStopAtFirstHit, false); }
bool IntersectTriangle(const MeshTriangle& tri, std::vector<Vector3>::const_iterator points, const G3D::Ray& ray, float& distance) { static const float EPS = 1e-5f; // See RTR2 ch. 13.7 for the algorithm. const Vector3 e1 = points[tri.idx1] - points[tri.idx0]; const Vector3 e2 = points[tri.idx2] - points[tri.idx0]; const Vector3 p(ray.direction().cross(e2)); const float a = e1.dot(p); if (abs(a) < EPS) { // Determinant is ill-conditioned; abort early return false; } const float f = 1.0f / a; const Vector3 s(ray.origin() - points[tri.idx0]); const float u = f * s.dot(p); if ((u < 0.0f) || (u > 1.0f)) { // We hit the plane of the m_geometry, but outside the m_geometry return false; } const Vector3 q(s.cross(e1)); const float v = f * ray.direction().dot(q); if ((v < 0.0f) || ((u + v) > 1.0f)) { // We hit the plane of the triangle, but outside the triangle return false; } const float t = f * e2.dot(q); if ((t > 0.0f) && (t < distance)) { // This is a new hit, closer than the previous one distance = t; /* baryCoord[0] = 1.0 - u - v; baryCoord[1] = u; baryCoord[2] = v; */ return true; } // This hit is after the previous hit, so ignore it return false; }
void ModelContainer::intersect(const G3D::Ray& pRay, float& pMaxDist, bool pStopAtFirstHit, G3D::Vector3& /*pOutLocation*/, G3D::Vector3& /*pOutNormal*/) const { IntersectionCallBack<SubModel> intersectCallback; NodeValueAccess<TreeNode, SubModel> vna = NodeValueAccess<TreeNode, SubModel>(getTreeNodes(), iSubModel); Ray relativeRay = Ray::fromOriginAndDirection(pRay.origin() - getBasePosition(), pRay.direction()); iTreeNodes[0].intersectRay(pRay, intersectCallback, pMaxDist, vna, pStopAtFirstHit, false); }
/* { ModelList::const_iterator it = model_list.find(info.Displayid); if (it == model_list.end()) return false; G3D::AABox mdl_box(it->second.bound); // ignore models with no bounds if (mdl_box == G3D::AABox::zero()) { VMAP_ERROR_LOG("misc", "GameObject model %s has zero bounds, loading skipped", it->second.name.c_str()); return false; } iModel = ((VMAP::VMapManager2*)VMAP::VMapFactory::createOrGetVMapManager())->acquireModelInstance(sWorld->GetDataPath() + "vmaps/", it->second.name); if (!iModel) return false; name = it->second.name; //flags = VMAP::MOD_M2; //adtId = 0; //ID = 0; iPos = Vector3(go.GetPositionX(), go.GetPositionY(), go.GetPositionZ()); iScale = go.GetObjectScale(); iInvScale = 1.f / iScale; G3D::Matrix3 iRotation = G3D::Matrix3::fromEulerAnglesZYX(go.GetOrientation(), 0, 0); iInvRot = iRotation.inverse(); // transform bounding box: mdl_box = AABox(mdl_box.low() * iScale, mdl_box.high() * iScale); AABox rotated_bounds; for (int i = 0; i < 8; ++i) rotated_bounds.merge(iRotation * mdl_box.corner(i)); this->iBound = rotated_bounds + iPos; #ifdef SPAWN_CORNERS // test: for (int i = 0; i < 8; ++i) { Vector3 pos(iBound.corner(i)); if (Creature* c = const_cast<GameObject&>(go).SummonCreature(24440, pos.x, pos.y, pos.z, 0, TEMPSUMMON_MANUAL_DESPAWN)) { c->setFaction(35); c->SetObjectScale(0.1f); } } #endif return true; } GameObjectModel* GameObjectModel::Create(const GameObject& go) { const GameObjectDisplayInfoEntry* info = sGameObjectDisplayInfoStore.LookupEntry(go.GetDisplayId()); if (!info) return NULL; GameObjectModel* mdl = new GameObjectModel(); if (!mdl->initialize(go, *info)) { delete mdl; return NULL; } return mdl; } */ bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool StopAtFirstHit) const { float time = ray.intersectionTime(iBound); if (time == G3D::inf()) return false; // child bounds are defined in object space: Vector3 p = iInvRot * (ray.origin() - iPos) * iInvScale; Ray modRay(p, iInvRot * ray.direction()); float distance = MaxDist * iInvScale; bool hit = iModel->IntersectRay(modRay, distance, StopAtFirstHit); if (hit) { distance *= iScale; MaxDist = distance; } return hit; }
bool ModelInstance::intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool pStopAtFirstHit) const { if (!iModel) return false; float time = pRay.intersectionTime(iBound); if (time == G3D::inf()) return false; // child bounds are defined in object space: Vector3 p = iInvRot * (pRay.origin() - iPos) * iInvScale; Ray modRay(p, iInvRot * pRay.direction()); float distance = pMaxDist * iInvScale; bool hit = iModel->IntersectRay(modRay, distance, pStopAtFirstHit); if (hit) { distance *= iScale; pMaxDist = distance; } return hit; }
bool GameObjectModel::intersectRay(G3D::Ray const& ray, float& maxDist, bool stopAtFirstHit, PhaseShift const& phaseShift, VMAP::ModelIgnoreFlags ignoreFlags) const { if (!isCollisionEnabled() || !owner->IsSpawned()) return false; if (!owner->IsInPhase(phaseShift)) return false; float time = ray.intersectionTime(iBound); if (time == G3D::finf()) return false; // child bounds are defined in object space: Vector3 p = iInvRot * (ray.origin() - iPos) * iInvScale; Ray modRay(p, iInvRot * ray.direction()); float distance = maxDist * iInvScale; bool hit = iModel->IntersectRay(modRay, distance, stopAtFirstHit, ignoreFlags); if (hit) { distance *= iScale; maxDist = distance; } return hit; }