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; }
//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); }
// ---------------------------------------------------------------------- // 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); }
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; }
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; }
//----------------------------------------------------------------------------- // 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; }