예제 #1
0
    PlaneSide classifyTriangle(const Vec3f &p0, const Vec3f &p1,
                               const Vec3f &p2, const float ep = 0) const
    {
        const PlaneSide r1 = classifyPoint(p0, ep);
        const PlaneSide r2 = classifyPoint(p1, ep);
        const PlaneSide r3 = classifyPoint(p2, ep);

        if ( r1 == Coplanar && r2 == Coplanar && r3 == Coplanar )
            return Coplanar;

        if ( r1 != r2 || r1 != r3 )
            return Spanning;

        return r1;
    }
예제 #2
0
 //The route will be generated using the A* pathfinding algorithm
 //Returns a path that only contains the startPoint if no path can be found
 //If not, it contains a path up to and including the goal but not including the start point
 //(It will not generate a path through unknown or unpassable terrain)
 //
 //THE CODE EXPLAINED:
 //
 //We then loop continuously, every time we loop:
 //  We pick the the point with the lowest cost on the OPEN list
 //    If there are no more points on the OPEN list then we stop looping
 //  Put the point on the CLOSE list
 //  We call this point "current"
 //  Examine every point adjacent to it, for each of those points:
 //    If it is OPEN we check if we can get to it faster from "current" and if so chenge current to the pathParent of the point
 //    If it is NONE we make "current" the pathParent of the point
 //	 If it is GOAL we set atGoal to true
 //	 If it is CLOSED we've already considered it completely and so do nothing
 //Finish if there are no points left that cost less to get to than the goal
void Routing::generateRoute(Point start, Point goal, Direction currDir, Path * path)
{
  generateRouteSetup(start, goal, currDir);
  bool atGoal = false;        //  atGoal is set to true if the goal point was considered while looping
  Point current = start;
  while(maze->contains(current) && !(atGoal && (nodeList.calcCost(current) > nodeList.calcCost(goal))))// loop continuously, it will break if we run out of points to investigate or if we find the goal
  {
    //Check every adjacent node to the current one, allowing diagonal movement
    for (int xDelta = -1; xDelta <= 1; xDelta++)
    {
      for (int yDelta = -1; yDelta <= 1; yDelta++)
      {
	Point adjacentPt(current.x + xDelta, current.y + yDelta); //This will hold every new point adjacent to current that we investigate
        if(maze->joined(current, adjacentPt))//if current = adjacentPt or either point is outside the maze maze->joined() also returns false
        {
	  atGoal = classifyPoint(adjacentPt, current, nodeList.getParent(current), goal) || atGoal;
        }//if
      }//for
    }//for
    nodeList.close(current); //We have finished with this point so we close it
    current = nodeList.findNodeWithLowestSum();//get new point, returns {-1,-1} if no OPEN points left
  }//while
  
  makePath(path, atGoal, goal, start);
}
예제 #3
0
// ----------------------------------------------------------------------
// Name  : intersectRayPlane()
// Input : rOrigin - origin of ray in world space
//         rVector - xr_vector describing direction of ray in world space
//         pOrigin - Origin of plane
//         pNormal - Normal to plane
// Notes : Normalized directional vectors expected
// Return: distance to plane in world units, -1 if no intersection.
// -----------------------------------------------------------------------
IC float intersectRayPlane(	const Fvector& rayOrigin,	const Fvector& rayDirection,
                            const Fvector& planeOrigin,	const Fvector& planeNormal)
{
    float numer = classifyPoint(rayOrigin,planeOrigin,planeNormal);
    float denom = planeNormal.dotproduct(rayDirection);

    if (denom == 0)  // normal is orthogonal to xr_vector, cant intersect
        return (-1.0f);

    return -(numer / denom);
}
예제 #4
0
GMContainmentType GMBoundingFrustum::contains(const GMVector3D& point) const
{
    // Check the top
    if (classifyPoint(point, top) > 0) {
        return GMContainmentTypeDisjoint;
    }

    // Check the bottom
    if (classifyPoint(point, bottom) > 0) {
        return GMContainmentTypeDisjoint;
    }

    // Check the left
    if (classifyPoint(point, left) > 0) {
        return GMContainmentTypeDisjoint;
    }

    // Check the right
    if (classifyPoint(point, right) > 0) {
        return GMContainmentTypeDisjoint;
    }

    // Check the near
    if (classifyPoint(point, near) > 0) {
        return GMContainmentTypeDisjoint;
    }

    // Check the far
    if (classifyPoint(point, far) > 0) {
        return GMContainmentTypeDisjoint;
    }

    return GMContainmentTypeContains;
}
예제 #5
0
void *KMeansSolver::threadSolve(void * param) {

	while (true) {

		//pthread_cond_wait() for start signal? (need_new_iteration)
		pthread_mutex_lock(classifyJob.mutex_jobsAvailable);
		if (classifyJob.jobsAvailable == 0)
			pthread_cond_wait(classifyJob.jobStart,
					classifyJob.mutex_jobsAvailable);
		if (classifyJob.jobsAvailable == 0) {
			pthread_mutex_unlock(classifyJob.mutex_jobsAvailable);
			continue;
		};
		classifyJob.registerWorker();
		calculateCenterJob.registerWorker();
		pthread_mutex_unlock(classifyJob.mutex_jobsAvailable);
		//First classify all points into some cluster
		int fromPtID, toPtID;
		//register
		//std::cout<<"thread starting classification!"<<pthread_self()<<"\n!"; //DEBUG
		while (classifyJob.getJobs(BATCH_JOB_CLASSIFY_QUANTITY, fromPtID,
				toPtID)) { //while there are jobs to do
			while (fromPtID <= toPtID) { //And we haven't taken them all
				//std::cout<<"thread classifing"<<pthread_self()<<" the "<<toPtID<<"\n!"; //DEBUG
				//Classify point toPtID
				classifyPoint(toPtID - 1);
				toPtID--; //This point is done...
			}
		}
		classifyJob.unregisterWorker();
		//Wait for everyone to finish...

		pthread_mutex_lock(classifyJob.mutex_done);
		if (!classifyJob.done)
			pthread_cond_wait(classifyJob.jobDone, classifyJob.mutex_done);
		pthread_mutex_unlock(classifyJob.mutex_done);

		//Start calculating centers...
		//std::cout<<"thread starting center calculation!"<<pthread_self()<<"\n!"; //DEBUG
		int fromClID, toClID;

		while (calculateCenterJob.getJobs(BATCH_JOB_CENTER_CALCULATE_QUANTITY,
				fromClID, toClID)) {
			while (fromClID <= toClID) {

				//std::cout<<"thread starting center calculation!"<<pthread_self()<<"from ("<<fromClID<<" to "<<toClID<<")\n!"; //DEBUG
				//Calculate New Center
				cl_repository->repository[toClID - 1].calculateNewCenter();

				//Update clusters_changed and cluster's center
				if (cl_repository->repository[toClID - 1].hasChanged) {
					pthread_mutex_lock(mutex_clusters_changed);
					clusters_changed = true;
					pthread_mutex_unlock(mutex_clusters_changed);

				}

				toClID--; //Done with this cluster
			}
		}

		calculateCenterJob.unregisterWorker();
		//std::cout<<"thread out"<<pthread_self()<<"\n!"; //DEBUG
		//std::cout<<"thread out"<<pthread_self()<<"\n!"; //DEBUG

	}
	return NULL;
}
예제 #6
0
//-----------------------------------------------------------------------------
// Name: Update()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CParticleSystem::Update( FLOAT fElpasedTime )
{
    Particle  *pParticle;
    Particle **ppParticle;
    Plane     *pPlane;
    Plane    **ppPlane;
    D3DXVECTOR3 vOldPosition;

    m_fCurrentTime += fElpasedTime;     // Update our particle system timer...

    ppParticle = &m_pActiveList; // Start at the head of the active list

    while( *ppParticle )
    {
        pParticle = *ppParticle; // Set a pointer to the head

        // Calculate new position
        float fTimePassed  = m_fCurrentTime - pParticle->m_fInitTime;

        if( fTimePassed >= m_fLifeCycle )
        {
            // Time is up, put the particle back on the free list...
            *ppParticle = pParticle->m_pNext;
            pParticle->m_pNext = m_pFreeList;
            m_pFreeList = pParticle;

            --m_dwActiveCount;
        }
        else
        {
            // Update particle position and velocity

            // Update velocity with respect to Gravity (Constant Acceleration)
            pParticle->m_vCurVel += m_vGravity * fElpasedTime;

            // Update velocity with respect to Wind (Acceleration based on
            // difference of vectors)
            if( m_bAirResistence == true )
                pParticle->m_vCurVel += (m_vWind - pParticle->m_vCurVel) * fElpasedTime;

            // Finally, update position with respect to velocity
            vOldPosition = pParticle->m_vCurPos;
            pParticle->m_vCurPos += pParticle->m_vCurVel * fElpasedTime - m_vDiff;

            //-----------------------------------------------------------------
            // BEGIN Checking the particle against each plane that was set up

            ppPlane = &m_pPlanes; // Set a pointer to the head

            while( *ppPlane )
            {
                pPlane = *ppPlane;
                int result = classifyPoint( &pParticle->m_vCurPos, pPlane );

                if( result == CP_BACK /*|| result == CP_ONPLANE */ )
                {
                    if( pPlane->m_nCollisionResult == CR_BOUNCE )
                    {
                        pParticle->m_vCurPos = vOldPosition;

                        //-----------------------------------------------------------------
                        //
                        // The new velocity vector of a particle that is bouncing off
                        // a plane is computed as follows:
                        //
                        // Vn = (N.V) * N
                        // Vt = V - Vn
                        // Vp = Vt - Kr * Vn
                        //
                        // Where:
                        //
                        // .  = Dot product operation
                        // N  = The normal of the plane from which we bounced
                        // V  = Velocity vector prior to bounce
                        // Vn = Normal force
                        // Kr = The coefficient of restitution ( Ex. 1 = Full Bounce,
                        //      0 = Particle Sticks )
                        // Vp = New velocity vector after bounce
                        //
                        //-----------------------------------------------------------------

                        float Kr = pPlane->m_fBounceFactor;

                        D3DXVECTOR3 Vn = D3DXVec3Dot( &pPlane->m_vNormal,
                                                      &pParticle->m_vCurVel ) *
                                         pPlane->m_vNormal;
                        D3DXVECTOR3 Vt = pParticle->m_vCurVel - Vn;
                        D3DXVECTOR3 Vp = Vt - Kr * Vn;

                        pParticle->m_vCurVel = Vp;
                    }
                    else if( pPlane->m_nCollisionResult == CR_RECYCLE )
                    {
                        pParticle->m_fInitTime -= m_fLifeCycle;
                    }

                    else if( pPlane->m_nCollisionResult == CR_STICK )
                    {
                        pParticle->m_vCurPos = vOldPosition;
                        pParticle->m_vCurVel = D3DXVECTOR3(0.0f,0.0f,0.0f);
                    }
                }

                ppPlane = &pPlane->m_pNext;
            }

            // END Plane Checking
            //-----------------------------------------------------------------

            ppParticle = &pParticle->m_pNext;
        }
    }

    //-------------------------------------------------------------------------
    // Emit new particles in accordance to the flow rate...
    //
    // NOTE: The system operates with a finite number of particles.
    //       New particles will be created until the max amount has
    //       been reached, after that, only old particles that have
    //       been recycled can be reintialized and used again.
    //-------------------------------------------------------------------------

    if( m_fCurrentTime - m_fLastUpdate > m_fReleaseInterval )
    {
        // Reset update timing...
        m_fLastUpdate = m_fCurrentTime;

        // Emit new particles at specified flow rate...
        for( DWORD i = 0; i < m_dwNumToRelease; ++i )
        {
            // Do we have any free particles to put back to work?
            if( m_pFreeList )
            {
                // If so, hand over the first free one to be reused.
                pParticle = m_pFreeList;
                // Then make the next free particle in the list next to go!
                m_pFreeList = pParticle->m_pNext;
            }
            else
            {
                // There are no free particles to recycle...
                // We'll have to create a new one from scratch!
                if( m_dwActiveCount < m_dwMaxParticles )
                {
                    if( NULL == ( pParticle = new Particle ) )
                        return E_OUTOFMEMORY;
                }
            }

            if( m_dwActiveCount < m_dwMaxParticles )
            {
                pParticle->m_pNext = m_pActiveList; // Make it the new head...
                m_pActiveList = pParticle;

                // Set the attributes for our new particle...
                pParticle->m_vCurVel = m_vVelocity;

                if( m_fVelocityVar != 0.0f )
                {
                    D3DXVECTOR3 vRandomVec = getRandomVector();
                    pParticle->m_vCurVel += vRandomVec * m_fVelocityVar;
                }

                pParticle->m_fInitTime  = m_fCurrentTime;
                pParticle->m_vCurPos    = m_vPosition;

                ++m_dwActiveCount;
            }
        }
    }

    return S_OK;
}