Example #1
0
bool lineIntersectsTriangle(const float *rayStart,const float *rayEnd,const float *p1,const float *p2,const float *p3,float *sect)
{
	float dir[3];

  dir[0] = rayEnd[0] - rayStart[0];
  dir[1] = rayEnd[1] - rayStart[1];
  dir[2] = rayEnd[2] - rayStart[2];

  float d = sqrtf(dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]);
  float r = 1.0f / d;

  dir[0]*=r;
  dir[1]*=r;
  dir[2]*=r;


  float t;

	bool ret = rayIntersectsTriangle(rayStart, dir, p1, p2, p3, t );

	if ( ret )
	{
		if ( t > d )
		{
			sect[0] = rayStart[0] + dir[0]*t;
			sect[1] = rayStart[1] + dir[1]*t;
			sect[2] = rayStart[2] + dir[2]*t;
		}
		else
		{
			ret = false;
		}
	}

  return ret;
}
bool lineIntersectsTriangle(const double *rayStart,const double *rayEnd,const double *p1,const double *p2,const double *p3,double *sect)
{
	double dir[3];

  dir[0] = rayEnd[0] - rayStart[0];
  dir[1] = rayEnd[1] - rayStart[1];
  dir[2] = rayEnd[2] - rayStart[2];

  double d = sqrt(dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]);
  double r = 1.0f / d;

  dir[0]*=r;
  dir[1]*=r;
  dir[2]*=r;


  double t;

	bool ret = rayIntersectsTriangle(rayStart, dir, p1, p2, p3, t );

	if ( ret )
	{
		if ( t > d )
		{
			sect[0] = rayStart[0] + dir[0]*t;
			sect[1] = rayStart[1] + dir[1]*t;
			sect[2] = rayStart[2] + dir[2]*t;
		}
		else
		{
			ret = false;
		}
	}

  return ret;
}
Example #3
0
	// pocitanie funkcie pre vsetky trojuholniky, O(n2)
	void CSDFController::Compute(LinkedList<Face>* triangles, Octree* root)
	{
		float min = FLOAT_MAX;
		float max = 0.0;
		
		unsigned int n_rays = 30;
		float angle = 120.0f;
		unsigned int counter = 0;

		//------------------prealocated variables------------------
		Vector4 tangens, normal, binormal;
		Mat4 t_mat;
		std::vector<float> rays;
		std::vector<float> weights;

		// precompute those N rays
		srand (123);											// initial seed for random number generator
		float* rndy = new float[n_rays];
		float* rndx = new float[n_rays];
		for(unsigned int i = 0; i < n_rays; i++)
		{
			rndy[i] = float(rand()%int(angle / 2));
			rndx[i] = float(rand()%(360));
			if(rndy[i] == 0.0)
				rndy[i] = 0.5;
		}

		float dist = FLOAT_MAX;
		float dist2 = FLOAT_MAX;
		float theta = 0.0f;
		bool intersected = false;

		LinkedList<Face>* face_list = NULL;
		LinkedList<Face>::Cell<Face>* intersected_face = NULL;
		//------------------prealocated variables------------------

		LinkedList<Face>::Cell<Face>* current_face = triangles->start;
		while(current_face != NULL)
		{
			// vypocet TNB vektorov a matice
			ComputeTNB(current_face->data, tangens, normal, binormal);
			t_mat = Mat4(tangens, normal, binormal);

			rays.clear();
			weights.clear();
			for(unsigned int i = 0; i < n_rays; i++)
			{
				Vector4 ray = CalcRayFromAngle(rndx[i], rndy[i]) * t_mat;
				ray.Normalize();

				dist = FLOAT_MAX;
				face_list = GetFaceList(triangles, root, current_face->data->center, ray);
				intersected_face = face_list->start;
				while(intersected_face != NULL)
				{
					if(current_face == intersected_face)
					{
						intersected_face = intersected_face->next;
						continue;
					}

					dist2 = FLOAT_MAX;
					intersected = rayIntersectsTriangle(current_face->data->center, ray, intersected_face->data->v[0]->P, intersected_face->data->v[1]->P, intersected_face->data->v[2]->P, dist2);
					if(intersected == true)
					{
						theta = acos( (ray * intersected_face->data->normal) / (ray.Length() * intersected_face->data->normal.Length()) );
						theta = theta * float(180.0 / M_PI);
						//loggger->logInfo(MarshalString("pridany ray s thetou: " + theta));
						if((theta < 90.0f) && (dist2 < dist))
							dist = dist2;
					}

					intersected_face = intersected_face->next;
				}
				if(dist < (FLOAT_MAX - 1.0f))
				{
					//loggger->logInfo(MarshalString("pridany ray s dlzkou: " + dist));
					rays.push_back(dist);
					weights.push_back(180.0f - rndy[i]);
				}
				//if(root != NULL)
					//delete face_list;						// generated list, bez prealokovania
			}
			if(rays.size() > 0)
			{
				current_face->data->ComputeSDFValue(rays, weights);
				if(current_face->data->diameter->value < min)
					min = current_face->data->diameter->value;
				if(current_face->data->diameter->value > max)
					max = current_face->data->diameter->value;
			}
			counter = counter + 1;
			current_face = current_face->next;
		}
		fc_list->Clear();
		oc_list->Clear();
		delete [] rndy;
		delete [] rndx;

		// postprocessing - smoothing and normalization
		//float kernel[] = {1.0,4.0,6.0,4.0,1.0};
		float* kernel = ComputeGaussianKernel(kernel_size);
		current_face = triangles->start;
		while(current_face != NULL)
		{
			Smooth(current_face->data, kernel, kernel_size);
			current_face->data->diameter->Normalize1(min, max, 4.0);
			current_face->data->diameter->Normalize2(0, max, 4.0);
			//tmp->data->diameter->Normalize2(0, diagonal, 4.0);

			current_face = current_face->next;
		}
		delete kernel;
	}
Example #4
0
	virtual bool raycast(const double *from,			// The starting point of the raycast
		const double *to,				// The ending point of the raycast
		const double *closestToPoint,	// The point to match the nearest hit location (can just be the 'from' location of no specific point)
		double *hitLocation,			// The point where the ray hit nearest to the 'closestToPoint' location
		double *hitDistance) final		// The distance the ray traveled to the hit location
	{
		bool ret = false;

		double dir[3];

		dir[0] = to[0] - from[0];
		dir[1] = to[1] - from[1];
		dir[2] = to[2] - from[2];

		double distance = sqrt( dir[0]*dir[0] + dir[1]*dir[1]+dir[2]*dir[2] );
		if ( distance < 0.0000000001f ) return false;
		double recipDistance = 1.0f / distance;
		dir[0]*=recipDistance;
		dir[1]*=recipDistance;
		dir[2]*=recipDistance;
		const uint32_t *indices = mIndices;
		const double *vertices = mVertices;
		double nearestDistance = distance;

		for (uint32_t tri=0; tri<mTcount; tri++)
		{
			uint32_t i1 = indices[tri*3+0];
			uint32_t i2 = indices[tri*3+1];
			uint32_t i3 = indices[tri*3+2];

			const double *p1 = &vertices[i1*3];
			const double *p2 = &vertices[i2*3];
			const double *p3 = &vertices[i3*3];

			double t;
			if ( rayIntersectsTriangle(from,dir,p1,p2,p3,t))
			{
				double hitPos[3];

				hitPos[0] = from[0] + dir[0] * t;
				hitPos[1] = from[1] + dir[1] * t;
				hitPos[2] = from[2] + dir[2] * t;

				double pointDistance = getPointDistance(hitPos, closestToPoint);

				if (pointDistance < nearestDistance )
				{
					nearestDistance = pointDistance;
					if ( hitLocation )
					{
						hitLocation[0] = hitPos[0];
						hitLocation[1] = hitPos[1];
						hitLocation[2] = hitPos[2];
					}
					if ( hitDistance )
					{
						*hitDistance = pointDistance;
					}
					ret = true;
				}
			}
		}
		return ret;
	}
Example #5
0
    virtual void raycast(bool &hit,
                         const float *from,
                         const float *dir,
                         float *hitLocation,
                         float *hitNormal,
                         float *hitDistance,
                         const float *vertices,
                         const uint32 *indices,
                         float &nearestDistance,
                         NodeInterface *callback,
                         unsigned char *raycastTriangles,
                         unsigned char raycastFrame,
                         const TriVector &leafTriangles)
    {
        float sect[3];
        float nd = nearestDistance;
        if ( !intersectLineSegmentAABB(mBounds.mMin,mBounds.mMax,from,dir,nd,sect) )
        {
            return;
        }

        if ( mLeafTriangleIndex != TRI_EOF )
        {
            const uint32 *scan = &leafTriangles[mLeafTriangleIndex];
            uint32 count = *scan++;
            for (uint32 i=0; i<count; i++)
            {
                uint32 tri = *scan++;
                if ( raycastTriangles[tri] != raycastFrame )
                {
                    raycastTriangles[tri] = raycastFrame;
                    uint32 i1 = indices[tri*3+0];
                    uint32 i2 = indices[tri*3+1];
                    uint32 i3 = indices[tri*3+2];

                    const float *p1 = &vertices[i1*3];
                    const float *p2 = &vertices[i2*3];
                    const float *p3 = &vertices[i3*3];

                    float t;
                    if ( rayIntersectsTriangle(from,dir,p1,p2,p3,t))
                    {
                        if ( t < nearestDistance )
                        {
                            nearestDistance = t;
                            if ( hitLocation )
                            {
                                hitLocation[0] = from[0]+dir[0]*t;
                                hitLocation[1] = from[1]+dir[1]*t;
                                hitLocation[2] = from[2]+dir[2]*t;
                            }
                            if ( hitNormal )
                            {
                                callback->getFaceNormal(tri,hitNormal);
                            }
                            if ( hitDistance )
                            {
                                *hitDistance = t;
                            }
                            hit = true;
                        }
                    }
                }
            }
        }
        else
        {
            if ( mLeft )
            {
                mLeft->raycast(hit,from,dir,hitLocation,hitNormal,hitDistance,vertices,indices,nearestDistance,callback,raycastTriangles,raycastFrame,leafTriangles);
            }
            if ( mRight )
            {
                mRight->raycast(hit,from,dir,hitLocation,hitNormal,hitDistance,vertices,indices,nearestDistance,callback,raycastTriangles,raycastFrame,leafTriangles);
            }
        }
    }