本文整理汇总了C++中Ray::HitDistance方法的典型用法代码示例。如果您正苦于以下问题:C++ Ray::HitDistance方法的具体用法?C++ Ray::HitDistance怎么用?C++ Ray::HitDistance使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Ray
的用法示例。
在下文中一共展示了Ray::HitDistance方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: CollectNodes
void Octree::CollectNodes(Vector<Pair<OctreeNode*, float> >& result, const Octant* octant, const Ray& ray, unsigned short nodeFlags,
float maxDistance, unsigned layerMask) const
{
float octantDist = ray.HitDistance(octant->cullingBox);
if (octantDist >= maxDistance)
return;
const Vector<OctreeNode*>& octantNodes = octant->nodes;
for (auto it = octantNodes.Begin(); it != octantNodes.End(); ++it)
{
OctreeNode* node = *it;
if ((node->Flags() & nodeFlags) == nodeFlags && (node->LayerMask() & layerMask))
{
float distance = ray.HitDistance(node->WorldBoundingBox());
if (distance < maxDistance)
result.Push(MakePair(node, distance));
}
}
for (size_t i = 0; i < NUM_OCTANTS; ++i)
{
if (octant->children[i])
CollectNodes(result, octant->children[i], ray, nodeFlags, maxDistance, layerMask);
}
}
示例2: OnRaycast
void Light::OnRaycast(Vector<RaycastResult>& dest, const Ray& ray, float maxDistance)
{
if (lightType == LIGHT_SPOT)
{
float distance = ray.HitDistance(WorldFrustum());
if (distance <= maxDistance)
{
RaycastResult res;
res.position = ray.origin + distance * ray.direction;
res.normal = -ray.direction;
res.distance = distance;
res.node = this;
res.subObject = 0;
dest.Push(res);
}
}
else if (lightType == LIGHT_POINT)
{
float distance = ray.HitDistance(WorldSphere());
if (distance <= maxDistance)
{
RaycastResult res;
res.position = ray.origin + distance * ray.direction;
res.normal = -ray.direction;
res.distance = distance;
res.node = this;
res.subObject = 0;
dest.Push(res);
}
}
}
示例3: GetHitDistance
float Geometry::GetHitDistance(const Ray& ray, Vector3* outNormal, Vector2* outUV) const
{
const unsigned char* vertexData;
const unsigned char* indexData;
unsigned vertexSize;
unsigned indexSize;
const PODVector<VertexElement>* elements;
GetRawData(vertexData, vertexSize, indexData, indexSize, elements);
if (!vertexData || !elements || VertexBuffer::GetElementOffset(*elements, TYPE_VECTOR3, SEM_POSITION) != 0)
return M_INFINITY;
unsigned uvOffset = VertexBuffer::GetElementOffset(*elements, TYPE_VECTOR2, SEM_TEXCOORD);
if (outUV && uvOffset == M_MAX_UNSIGNED)
{
// requested UV output, but no texture data in vertex buffer
ATOMIC_LOGWARNING("Illegal GetHitDistance call: UV return requested on vertex buffer without UV coords");
*outUV = Vector2::ZERO;
outUV = 0;
}
return indexData ? ray.HitDistance(vertexData, vertexSize, indexData, indexSize, indexStart_, indexCount_, outNormal, outUV,
uvOffset) : ray.HitDistance(vertexData, vertexSize, vertexStart_, vertexCount_, outNormal, outUV, uvOffset);
}
示例4: ProcessRayQuery
void TerrainPatch::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results)
{
RayQueryLevel level = query.level_;
switch (level)
{
case RAY_AABB_NOSUBOBJECTS:
case RAY_AABB:
Drawable::ProcessRayQuery(query, results);
break;
case RAY_OBB:
case RAY_TRIANGLE:
Matrix3x4 inverse(node_->GetWorldTransform().Inverse());
Ray localRay = query.ray_.Transformed(inverse);
float distance = localRay.HitDistance(boundingBox_);
if (level == RAY_TRIANGLE && distance < query.maxDistance_)
distance = geometry_->GetHitDistance(localRay);
if (distance < query.maxDistance_)
{
RayQueryResult result;
result.drawable_ = this;
result.node_ = node_;
result.distance_ = distance;
result.subObject_ = M_MAX_UNSIGNED;
results.Push(result);
}
break;
}
}
示例5: GetHitDistance
float Geometry::GetHitDistance(const Ray& ray, Vector3* outNormal) const
{
const unsigned char* vertexData;
const unsigned char* indexData;
unsigned vertexSize;
unsigned indexSize;
unsigned elementMask;
GetRawData(vertexData, vertexSize, indexData, indexSize, elementMask);
if (vertexData && indexData)
return ray.HitDistance(vertexData, vertexSize, indexData, indexSize, indexStart_, indexCount_, outNormal);
else if (vertexData)
return ray.HitDistance(vertexData, vertexSize, vertexStart_, vertexCount_, outNormal);
else
return M_INFINITY;
}
示例6: ProcessRayQuery
void CustomGeometry::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results)
{
RayQueryLevel level = query.level_;
switch (level)
{
case RAY_AABB:
Drawable::ProcessRayQuery(query, results);
break;
case RAY_OBB:
case RAY_TRIANGLE:
{
Matrix3x4 inverse(node_->GetWorldTransform().Inverse());
Ray localRay = query.ray_.Transformed(inverse);
float distance = localRay.HitDistance(boundingBox_);
Vector3 normal = -query.ray_.direction_;
if (level == RAY_TRIANGLE && distance < query.maxDistance_)
{
distance = M_INFINITY;
for (unsigned i = 0; i < batches_.Size(); ++i)
{
Geometry* geometry = batches_[i].geometry_;
if (geometry)
{
Vector3 geometryNormal;
float geometryDistance = geometry->GetHitDistance(localRay, &geometryNormal);
if (geometryDistance < query.maxDistance_ && geometryDistance < distance)
{
distance = geometryDistance;
normal = (node_->GetWorldTransform() * Vector4(geometryNormal, 0.0f)).Normalized();
}
}
}
}
if (distance < query.maxDistance_)
{
RayQueryResult result;
result.position_ = query.ray_.origin_ + distance * query.ray_.direction_;
result.normal_ = normal;
result.distance_ = distance;
result.drawable_ = this;
result.node_ = node_;
result.subObject_ = M_MAX_UNSIGNED;
results.Push(result);
}
}
break;
case RAY_TRIANGLE_UV:
ATOMIC_LOGWARNING("RAY_TRIANGLE_UV query level is not supported for CustomGeometry component");
break;
}
}
示例7: ProcessRayQuery
void StaticModel::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results)
{
RayQueryLevel level = query.level_;
switch (level)
{
case RAY_AABB:
Drawable::ProcessRayQuery(query, results);
break;
case RAY_OBB:
case RAY_TRIANGLE:
case RAY_TRIANGLE_UV:
Matrix3x4 inverse(node_->GetWorldTransform().Inverse());
Ray localRay = query.ray_.Transformed(inverse);
float distance = localRay.HitDistance(boundingBox_);
Vector3 normal = -query.ray_.direction_;
Vector2 geometryUV;
unsigned hitBatch = M_MAX_UNSIGNED;
if (level >= RAY_TRIANGLE && distance < query.maxDistance_)
{
distance = M_INFINITY;
for (unsigned i = 0; i < batches_.Size(); ++i)
{
Geometry* geometry = batches_[i].geometry_;
if (geometry)
{
Vector3 geometryNormal;
float geometryDistance = level == RAY_TRIANGLE ? geometry->GetHitDistance(localRay, &geometryNormal) :
geometry->GetHitDistance(localRay, &geometryNormal, &geometryUV);
if (geometryDistance < query.maxDistance_ && geometryDistance < distance)
{
distance = geometryDistance;
normal = (node_->GetWorldTransform() * Vector4(geometryNormal, 0.0f)).Normalized();
hitBatch = i;
}
}
}
}
if (distance < query.maxDistance_)
{
RayQueryResult result;
result.position_ = query.ray_.origin_ + distance * query.ray_.direction_;
result.normal_ = normal;
result.textureUV_ = geometryUV;
result.distance_ = distance;
result.drawable_ = this;
result.node_ = node_;
result.subObject_ = hitBatch;
results.Push(result);
}
break;
}
}
示例8: ProcessRayQuery
void StaticModelGroup::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results)
{
// If no bones or no bone-level testing, use the Drawable test
RayQueryLevel level = query.level_;
if (level < RAY_AABB)
{
Drawable::ProcessRayQuery(query, results);
return;
}
// Check ray hit distance to AABB before proceeding with more accurate tests
// GetWorldBoundingBox() updates the world transforms
if (query.ray_.HitDistance(GetWorldBoundingBox()) >= query.maxDistance_)
return;
for (unsigned i = 0; i < numWorldTransforms_; ++i)
{
// Initial test using AABB
float distance = query.ray_.HitDistance(boundingBox_.Transformed(worldTransforms_[i]));
// Then proceed to OBB and triangle-level tests if necessary
if (level >= RAY_OBB && distance < query.maxDistance_)
{
Matrix3x4 inverse = worldTransforms_[i].Inverse();
Ray localRay = query.ray_.Transformed(inverse);
distance = localRay.HitDistance(boundingBox_);
if (level == RAY_TRIANGLE && distance < query.maxDistance_)
{
distance = M_INFINITY;
for (unsigned j = 0; j < batches_.Size(); ++j)
{
Geometry* geometry = batches_[j].geometry_;
if (geometry)
{
float geometryDistance = geometry->GetHitDistance(localRay);
if (geometryDistance < query.maxDistance_ && geometryDistance < distance)
distance = geometryDistance;
}
}
}
}
if (distance < query.maxDistance_)
{
RayQueryResult result;
result.drawable_ = this;
result.node_ = node_;
result.distance_ = distance;
result.subObject_ = i;
results.Push(result);
}
}
}
示例9: ProcessRayQuery
void Light::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results)
{
// Do not record a raycast result for a directional light, as it would block all other results
if (lightType_ == LIGHT_DIRECTIONAL)
return;
float distance = query.maxDistance_;
switch (query.level_)
{
case RAY_AABB:
Drawable::ProcessRayQuery(query, results);
return;
case RAY_OBB:
{
Matrix3x4 inverse(node_->GetWorldTransform().Inverse());
Ray localRay = query.ray_.Transformed(inverse);
distance = localRay.HitDistance(GetWorldBoundingBox().Transformed(inverse));
if (distance >= query.maxDistance_)
return;
}
break;
case RAY_TRIANGLE:
if (lightType_ == LIGHT_SPOT)
{
distance = query.ray_.HitDistance(GetFrustum());
if (distance >= query.maxDistance_)
return;
}
else
{
distance = query.ray_.HitDistance(Sphere(node_->GetWorldPosition(), range_));
if (distance >= query.maxDistance_)
return;
}
break;
case RAY_TRIANGLE_UV:
LOGWARNING("RAY_TRIANGLE_UV query level is not supported for Light component");
return;
}
// If the code reaches here then we have a hit
RayQueryResult result;
result.position_ = query.ray_.origin_ + distance * query.ray_.direction_;
result.normal_ = -query.ray_.direction_;
result.distance_ = distance;
result.drawable_ = this;
result.node_ = node_;
result.subObject_ = M_MAX_UNSIGNED;
results.Push(result);
}
示例10: ProcessRayQuery
void StaticModel::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results)
{
RayQueryLevel level = query.level_;
switch (level)
{
case RAY_AABB_NOSUBOBJECTS:
case RAY_AABB:
Drawable::ProcessRayQuery(query, results);
break;
case RAY_OBB:
case RAY_TRIANGLE:
Matrix3x4 inverse(node_->GetWorldTransform().Inverse());
Ray localRay = query.ray_.Transformed(inverse);
float distance = localRay.HitDistance(boundingBox_);
if (distance < query.maxDistance_)
{
if (level == RAY_TRIANGLE)
{
for (unsigned i = 0; i < batches_.Size(); ++i)
{
Geometry* geometry = batches_[i].geometry_;
if (geometry)
{
distance = geometry->GetHitDistance(localRay);
if (distance < query.maxDistance_)
{
RayQueryResult result;
result.drawable_ = this;
result.node_ = node_;
result.distance_ = distance;
result.subObject_ = M_MAX_UNSIGNED;
results.Push(result);
break;
}
}
}
}
else
{
RayQueryResult result;
result.drawable_ = this;
result.node_ = node_;
result.distance_ = distance;
result.subObject_ = M_MAX_UNSIGNED;
results.Push(result);
}
}
break;
}
}
示例11: OnRaycast
void OctreeNode::OnRaycast(Vector<RaycastResult>& dest, const Ray& ray, float maxDistance)
{
float distance = ray.HitDistance(WorldBoundingBox());
if (distance < maxDistance)
{
RaycastResult res;
res.position = ray.origin + distance * ray.direction;
res.normal = -ray.direction;
res.distance = distance;
res.node = this;
res.subObject = 0;
dest.Push(res);
}
}
示例12: ProcessRayQuery
void TerrainPatch::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results)
{
RayQueryLevel level = query.level_;
switch (level)
{
case RAY_AABB:
Drawable::ProcessRayQuery(query, results);
break;
case RAY_OBB:
case RAY_TRIANGLE:
{
Matrix3x4 inverse(node_->GetWorldTransform().Inverse());
Ray localRay = query.ray_.Transformed(inverse);
float distance = localRay.HitDistance(boundingBox_);
Vector3 normal = -query.ray_.direction_;
if (level == RAY_TRIANGLE && distance < query.maxDistance_)
{
Vector3 geometryNormal;
distance = geometry_->GetHitDistance(localRay, &geometryNormal);
normal = (node_->GetWorldTransform() * Vector4(geometryNormal, 0.0f)).Normalized();
}
if (distance < query.maxDistance_)
{
RayQueryResult result;
result.position_ = query.ray_.origin_ + distance * query.ray_.direction_;
result.normal_ = normal;
result.distance_ = distance;
result.drawable_ = this;
result.node_ = node_;
result.subObject_ = M_MAX_UNSIGNED;
results.Push(result);
}
}
break;
case RAY_TRIANGLE_UV:
URHO3D_LOGWARNING("RAY_TRIANGLE_UV query level is not supported for TerrainPatch component");
break;
}
}
示例13: ProcessRayQuery
void AnimatedModel::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results)
{
// If no bones or no bone-level testing, use the StaticModel test
RayQueryLevel level = query.level_;
if (level < RAY_TRIANGLE || !skeleton_.GetNumBones())
{
StaticModel::ProcessRayQuery(query, results);
return;
}
// Check ray hit distance to AABB before proceeding with bone-level tests
if (query.ray_.HitDistance(GetWorldBoundingBox()) >= query.maxDistance_)
return;
const Vector<Bone>& bones = skeleton_.GetBones();
Sphere boneSphere;
for (unsigned i = 0; i < bones.Size(); ++i)
{
const Bone& bone = bones[i];
if (!bone.node_)
continue;
float distance;
// Use hitbox if available
if (bone.collisionMask_ & BONECOLLISION_BOX)
{
// Do an initial crude test using the bone's AABB
const BoundingBox& box = bone.boundingBox_;
const Matrix3x4& transform = bone.node_->GetWorldTransform();
distance = query.ray_.HitDistance(box.Transformed(transform));
if (distance >= query.maxDistance_)
continue;
if (level != RAY_AABB)
{
// Follow with an OBB test if required
Matrix3x4 inverse = transform.Inverse();
Ray localRay = query.ray_.Transformed(inverse);
distance = localRay.HitDistance(box);
if (distance >= query.maxDistance_)
continue;
}
}
else if (bone.collisionMask_ & BONECOLLISION_SPHERE)
{
boneSphere.center_ = bone.node_->GetWorldPosition();
boneSphere.radius_ = bone.radius_;
distance = query.ray_.HitDistance(boneSphere);
if (distance >= query.maxDistance_)
continue;
}
else
continue;
// If the code reaches here then we have a hit
RayQueryResult result;
result.position_ = query.ray_.origin_ + distance * query.ray_.direction_;
result.normal_ = -query.ray_.direction_;
result.distance_ = distance;
result.drawable_ = this;
result.node_ = node_;
result.subObject_ = i;
results.Push(result);
}
}