コード例 #1
0
/// checks if a ray intersects the mesh, ray_origin and ray_dir must be in local coordinates
/// returns face index that was hit, or -1 if nothing hit
int		MeshShape::RayIntersect	(const Vector3& ray_origin,const Vector3& ray_dir,float* pfHitDist) {
	if (mpMesh.isNull()) return -1;
	// check bounding sphere first
	
	//printf("#WWW### MeshShape::RayIntersect %f\n",mpMesh->getBoundingSphereRadius());
	
	Vector3 vMid = 0.5*(mvMin + mvMax);
	float fRad = mymax((mvMin-vMid).length(),(mvMax-vMid).length());
	//float fRad = mpMesh->getBoundingSphereRadius();
	
	if (!Ogre::Ray(ray_origin,ray_dir).intersects(Ogre::Sphere(vMid,fRad + 0.1)).first) return -1;
	
	//printf("MeshShape::RayIntersect hitbounds : rad=%f\n",fRad);
	
	
	int iFaceHit = -1;
	float myHitDist;
	
	//printf("#WWW### MeshShape::RayIntersect rayhit %d\n",mlIndices.size());
	
	for (int i=0;i<mlIndices.size();i+=3) {
		if (IntersectRayTriangle(ray_origin,ray_dir,
			mlVertices[mlIndices[i+0]],
			mlVertices[mlIndices[i+1]],
			mlVertices[mlIndices[i+2]],&myHitDist)) {
			if (iFaceHit == -1 || myHitDist < *pfHitDist) { *pfHitDist = myHitDist; iFaceHit = i/3; }
		}
	}
	//printf("MeshShape::RayIntersect hit=%d dist=%f\n",bHit?1:0,bHit?(*pfHitDist):0);
	return iFaceHit;
}
コード例 #2
0
void	MeshShape::RayIntersect	(const Ogre::Vector3& ray_origin,const Ogre::Vector3& ray_dir,std::vector<std::pair<float,int> > &pHitList) {
	if (mpMesh.isNull()) return;
	Vector3 vMid = 0.5*(mvMin + mvMax);
	float fRad = mymax((mvMin-vMid).length(),(mvMax-vMid).length());	
	if (!Ogre::Ray(ray_origin,ray_dir).intersects(Ogre::Sphere(vMid,fRad + 0.1)).first) return;
	float myHitDist;
	for (int i=0;i<mlIndices.size();i+=3) {
		if (IntersectRayTriangle(ray_origin,ray_dir,
			mlVertices[mlIndices[i+0]],
			mlVertices[mlIndices[i+1]],
			mlVertices[mlIndices[i+2]],&myHitDist)) {
			pHitList.push_back(std::make_pair(myHitDist,i/3));
		}
	}
}
コード例 #3
0
DWORD MeshParameterization::OnIntersectRayTriangle( DWORD size, void * params )
{
	VERIFY_MESSAGE_SIZE( size, sizeof( MESHPARAMINTERSECTRAYTRIANGLEMSG ) );
	MESHPARAMINTERSECTRAYTRIANGLEMSG * msg = (MESHPARAMINTERSECTRAYTRIANGLEMSG*)params;
	if( msg != NULL )
	{
		if( msg->inRay != NULL )
		{			
			Ray inRay = *msg->inRay;
			msg->outCollided = 
				IntersectRayTriangle( inRay, msg->outFaceIndex, &msg->outIntersectionDistance, &msg->outULength, &msg->outVLength );
			return MSG_HANDLED_STOP;
		}
	}
	return MSG_ERROR;
}
コード例 #4
0
ファイル: hacdRaycastMesh.cpp プロジェクト: 120pulsations/SDK
	bool RMNode::Raycast(const Vec3<Float> & from, const Vec3<Float> & dir, long & triID, Float & distance, Vec3<Real> & hitPoint, Vec3<Real> & hitNormal) const 
	{
		Float distToSphere;
		if (m_bBox.Raycast(from, dir, distToSphere) && (distToSphere < distance))
		{
			if (m_leaf)
			{
				long f, i1, j1, k1;
				Vec3<long> * const triangles = m_rm->m_triangles;			
				Vec3<Float> * const vertices = m_rm->m_vertices;
				Vec3<Real> u1, v1, normal1;
				double dist = 0.0;
				long nhit = 0;
				bool ret = false;
				for(size_t id = 0; id < m_triIDs.Size(); ++id)
				{
					f = m_triIDs[id];
					i1 = triangles[f].X();
					j1 = triangles[f].Y();
					k1 = triangles[f].Z();
					u1 = vertices[j1] - vertices[i1];
					v1 = vertices[k1] - vertices[i1];
					normal1 = (u1 ^ v1);
					if (dir * normal1 > 0.0)
					{
						nhit = IntersectRayTriangle(from, dir, vertices[i1], vertices[j1], vertices[k1], dist);
						if (nhit==1 && distance>dist)
						{
							normal1.Normalize();
							hitNormal = normal1;
							hitPoint = from + dist * dir;
							distance = dist;
							triID = f;
							ret = true;
						}						
					}
				}
				return ret;
			}
			bool ret1 = false;
			bool ret2 = false;
			if (m_idRight >= 0) ret1 = m_rm->m_nodes[m_idRight].Raycast(from, dir, triID, distance, hitPoint, hitNormal);
			if (m_idLeft >= 0)  ret2 = m_rm->m_nodes[m_idLeft].Raycast(from, dir, triID, distance, hitPoint, hitNormal);
			return ret1 || ret2;
		}
		return false;
	}
コード例 #5
0
    bool CCoherentGeometry::IntersectWithRay( const Vec3& rayOriginModelSpace, const Vec3& rayDirectionModelSpace, float& outDist, float& outU, float& outV )
    {
        static const int NO_HIT = -1;
        int hitFaceIndex = NO_HIT; // Actually index of the hit face's first vertex index in the indices array, but never mind
        float minDist = std::numeric_limits<float>::max();
        float texU = 0;
        float texV = 0;

        for ( size_t i = 0; i < m_Vertices.size(); i += 3 )
        {
            float t, u, v;
            const Vec3& v0 = m_Vertices[i];
            const Vec3& v1 = m_Vertices[i + 1];
            const Vec3& v2 = m_Vertices[i + 2];

            if ( IntersectRayTriangle( rayOriginModelSpace, rayDirectionModelSpace, v0, v1, v2, t, u, v ) )
            {
                if ( t < minDist )
                {
                    minDist = t;
                    // Temporarily save barycentric coordinates here
                    texU = u;
                    texV = v;

                    hitFaceIndex = i;
                }
            }
        }

        if ( hitFaceIndex != NO_HIT )
        {
            // Compute texture coordinates from barycentric coordinates
            Vec2 texCoords =
                ( 1 - texU - texV ) * m_TexCoords[hitFaceIndex] +
                texU * m_TexCoords[hitFaceIndex + 1] +
                texV * m_TexCoords[hitFaceIndex + 2];

            outU = texCoords.x;
            outV = 1.0f - texCoords.y;
            outDist = minDist;

            return true;
        }

        return false;
    }
コード例 #6
0
int IntersectSegmentTriangle(const vec3d& s0, const vec3d& s1, const vec3d p[3], double& t, vec3d& uvw, vec3d& xyz) {

	vec3d delta = s1 - s0;
	vec3d rd = delta.normalized();
	double deltaLen = delta.length();
	vec3d uvt;
	int res = IntersectRayTriangle(s0, rd, p, uvt);
	if(res > 0) {
		if(uvt.z >= 0.0 && uvt.z <= deltaLen) {
			//Barycentric coordinate
			uvw = vec3d(uvt.x, uvt.y, 1.0 - uvt.x - uvt.y);

			//Cartesian Coordinate
			xyz = s0 + rd * uvt.z;

			//return the t distance on the segment
			t = uvt.z;

			return res;
		}
	}
	return 0;
}
コード例 #7
0
ファイル: hacdHACD.cpp プロジェクト: Bredoto/Bullet
    void HACD::InitializeDualGraph()
    {
        long i, j, k;
        Vec3<Real> u, v, w, normal;
		delete [] m_normals;
		m_normals = new Vec3<Real>[m_nPoints];
        if (m_addFacesPoints)
        {
            delete [] m_facePoints;
            delete [] m_faceNormals;
            m_facePoints = new Vec3<Real>[m_nTriangles];
            m_faceNormals = new Vec3<Real>[m_nTriangles];
        }
		memset(m_normals, 0, sizeof(Vec3<Real>) * m_nPoints);
        for(unsigned long f = 0; f < m_nTriangles; f++)
        {
			if (m_callBack) (*m_callBack)("+ InitializeDualGraph\n", f, m_nTriangles, 0);
			
			if (gCancelRequest)
				return;

            i = m_triangles[f].X();
            j = m_triangles[f].Y();
            k = m_triangles[f].Z();
		
			m_graph.m_vertices[f].m_distPoints[i].m_distOnly = false;
			m_graph.m_vertices[f].m_distPoints[j].m_distOnly = false;
			m_graph.m_vertices[f].m_distPoints[k].m_distOnly = false;
            
            ICHull  * ch = new ICHull;
            m_graph.m_vertices[f].m_convexHull = ch;
            ch->AddPoint(m_points[i], i);
            ch->AddPoint(m_points[j], j);
            ch->AddPoint(m_points[k], k);
			ch->SetDistPoints(&m_graph.m_vertices[f].m_distPoints);

			u = m_points[j] - m_points[i];
			v = m_points[k] - m_points[i];
			w = m_points[k] - m_points[j];
			normal = u ^ v;

			m_normals[i] += normal;
			m_normals[j] += normal;
			m_normals[k] += normal;

			m_graph.m_vertices[f].m_surf = normal.GetNorm();
			m_graph.m_vertices[f].m_perimeter = u.GetNorm() + v.GetNorm() + w.GetNorm();
            
            normal.Normalize();

			m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(i,j));
			m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(j,k));
			m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(k,i));
            if(m_addFacesPoints)
            {
                m_faceNormals[f] = normal;
                m_facePoints[f] = (m_points[i] + m_points[j] + m_points[k]) / 3.0;
                m_graph.m_vertices[f].m_distPoints[-static_cast<long>(f)-1].m_distOnly = true;
            }
            if (m_addExtraDistPoints)	
            {// we need a kd-tree structure to accelerate this part!
                long i1, j1, k1;
                Vec3<Real> u1, v1, normal1;
				normal = -normal;
                double distance = 0.0;
                double distMin = 0.0;
                size_t faceIndex = m_nTriangles;
                Vec3<Real> seedPoint((m_points[i] + m_points[j] + m_points[k]) / 3.0);
                long nhit = 0;
                for(size_t f1 = 0; f1 < m_nTriangles; f1++)
                {
                    i1 = m_triangles[f1].X();
                    j1 = m_triangles[f1].Y();
                    k1 = m_triangles[f1].Z();
                    u1 = m_points[j1] - m_points[i1];
                    v1 = m_points[k1] - m_points[i1];
                    normal1 = (u1 ^ v1);
                    if (normal * normal1 > 0.0)
                    {
                        nhit = IntersectRayTriangle(Vec3<double>(seedPoint.X(), seedPoint.Y(), seedPoint.Z()),
													Vec3<double>(normal.X(), normal.Y(), normal.Z()),
													Vec3<double>(m_points[i1].X(), m_points[i1].Y(), m_points[i1].Z()),
													Vec3<double>(m_points[j1].X(), m_points[j1].Y(), m_points[j1].Z()),
													Vec3<double>(m_points[k1].X(), m_points[k1].Y(), m_points[k1].Z()),
													distance);
                        if ((nhit==1) && ((distMin > distance) || (faceIndex == m_nTriangles)))
                        {
                            distMin = distance;
                            faceIndex = f1;
                        }

                    }
                }
                if (faceIndex < m_nTriangles )
                {
                    i1 = m_triangles[faceIndex].X();
                    j1 = m_triangles[faceIndex].Y();
                    k1 = m_triangles[faceIndex].Z();
                    m_graph.m_vertices[f].m_distPoints[i1].m_distOnly = true;
                    m_graph.m_vertices[f].m_distPoints[j1].m_distOnly = true;
                    m_graph.m_vertices[f].m_distPoints[k1].m_distOnly = true;
					if (m_addFacesPoints)
					{
						m_graph.m_vertices[f].m_distPoints[-static_cast<long>(faceIndex)-1].m_distOnly = true;
					}
				}
            }
        }
        for (size_t v = 0; v < m_nPoints; v++) 
		{
			m_normals[v].Normalize();
		}
    }
コード例 #8
0
	double ICHull::ComputeDistance(long name, const Vec3<Real> & pt, const Vec3<Real> & normal, bool & insideHull, bool updateIncidentPoints)
	{
		if (m_isFlat)
		{
			return  0.0;
		}
		else
		{
			Vec3<double> p0( static_cast<double>(pt.X()), 
							 static_cast<double>(pt.Y()), 
							 static_cast<double>(pt.Z()));

			Vec3<double> ptNormal(static_cast<double>(normal.X()), 
								  static_cast<double>(normal.Y()), 
								  static_cast<double>(normal.Z()));
			Vec3<double> impact;
			long nhit;
			double dist;
			double distance = 0.0; 
			size_t nT = m_mesh.GetNTriangles();
			insideHull = false;
			CircularListElement<TMMTriangle> * face = 0;
			Vec3<double> ver0, ver1, ver2;
			for(size_t f = 0; f < nT; f++)
			{
				TMMTriangle & currentTriangle = m_mesh.m_triangles.GetHead()->GetData();
                nhit = 0;
				if (currentTriangle.m_vertices[0]->GetData().m_name != currentTriangle.m_vertices[1]->GetData().m_name &&
					currentTriangle.m_vertices[1]->GetData().m_name != currentTriangle.m_vertices[2]->GetData().m_name &&
					currentTriangle.m_vertices[2]->GetData().m_name != currentTriangle.m_vertices[0]->GetData().m_name)
				{
					if (currentTriangle.m_vertices[0]->GetData().m_name == name ||
						currentTriangle.m_vertices[1]->GetData().m_name == name ||
						currentTriangle.m_vertices[2]->GetData().m_name == name)
					{
						nhit = 1;
						dist = 0.0;
					}
					else
					{
						ver0.X() = currentTriangle.m_vertices[0]->GetData().m_pos.X();
						ver0.Y() = currentTriangle.m_vertices[0]->GetData().m_pos.Y();
						ver0.Z() = currentTriangle.m_vertices[0]->GetData().m_pos.Z();
						ver1.X() = currentTriangle.m_vertices[1]->GetData().m_pos.X();
						ver1.Y() = currentTriangle.m_vertices[1]->GetData().m_pos.Y();
						ver1.Z() = currentTriangle.m_vertices[1]->GetData().m_pos.Z();
						ver2.X() = currentTriangle.m_vertices[2]->GetData().m_pos.X();
						ver2.Y() = currentTriangle.m_vertices[2]->GetData().m_pos.Y();
						ver2.Z() = currentTriangle.m_vertices[2]->GetData().m_pos.Z();
						Vec3<Real> faceNormal = (ver1-ver0) ^ (ver2-ver0);
						faceNormal.Normalize();
						if (ptNormal*normal > 0.0)
						{
							nhit = IntersectRayTriangle(p0, ptNormal, ver0, ver1, ver2, dist);
						}                        
					}
#ifdef HACD_DEBUG
					std::cout << "T " << currentTriangle.m_vertices[0]->GetData().m_name << " "
									  << currentTriangle.m_vertices[1]->GetData().m_name << " "
									  << currentTriangle.m_vertices[2]->GetData().m_name << " "
									  << nhit << " " << dist << std::endl;
#endif
					if (nhit == 1 && (!insideHull || dist > distance) )
					{
						distance = dist;
						insideHull = true;
						face = m_mesh.m_triangles.GetHead();
					}
				}
				m_mesh.m_triangles.Next();
			}
			if (updateIncidentPoints && face && m_distPoints)
			{
				(*m_distPoints)[name].m_dist = static_cast<Real>(distance);
				face->GetData().m_incidentPoints.Insert(name);
			}
			return distance;
		}
	}