void* dNewtonBody::GetInterpolatedRotation() { const dNewtonWorld* const world = (dNewtonWorld*) NewtonWorldGetUserData(NewtonBodyGetWorld(m_body)); ScopeLock scopelock(&m_lock); m_interpolatedRotation = m_rotation0.Slerp(m_rotation1, world->m_interpotationParam); return &m_interpolatedRotation.m_q0; }
void rayPickerManager::PreUpdate(dFloat timestep) { // all of the work will be done here; dNewton::ScopeLock scopelock (&m_lock); if (m_pickedBody) { if (m_pickedBody->GetType() == dNewtonBody::m_dynamic) { newtonDynamicBody* const body = (newtonDynamicBody*)m_pickedBody; dFloat invTimeStep = 1.0f / timestep; Matrix matrix (body->GetMatrix()); Vec4 omega0 (body->GetOmega()); Vec4 veloc0 (body->GetVeloc()); Vec4 peekPosit (m_localpHandlePoint * matrix); Vec4 peekStep (m_globalTarget - peekPosit); Vec4 pointVeloc (body->GetPointVeloc (peekPosit)); Vec4 deltaVeloc (peekStep * (m_stiffness * invTimeStep) - pointVeloc); for (int i = 0; i < 3; i ++) { Vec4 veloc (0.0f, 0.0f, 0.0f, 0.0f); veloc[i] = deltaVeloc[i]; body->ApplyImpulseToDesiredPointVeloc (peekPosit, veloc); } // damp angular velocity Vec4 omega1 (body->GetOmega()); Vec4 veloc1 (body->GetVeloc()); omega1 = omega1 * (0.9f); // restore body velocity and angular velocity body->SetVeloc(veloc0); body->SetOmega(omega0); // convert the delta velocity change to a external force and torque dFloat Ixx; dFloat Iyy; dFloat Izz; dFloat mass; body->GetMassAndInertia (mass, Ixx, Iyy, Izz); matrix.setTrans(Vec3(0.0f, 0.0f, 0.0f)); Vec4 relOmega (omega1 - omega0); relOmega = matrix.preMult(relOmega); Vec4 angularMomentum (Ixx, Iyy, Izz, 0.0f); angularMomentum = componentMultiply (relOmega, angularMomentum); angularMomentum = matrix.postMult(angularMomentum); Vec4 torque (angularMomentum * invTimeStep); body->AddTorque(torque); Vec4 relVeloc (veloc1 - veloc0); Vec4 force (relVeloc * (mass * invTimeStep)); body->AddForce (force); } else { dAssert (0); } } }
void* dNewtonBody::GetInterpolatedPosition() { const dNewtonWorld* const world = (dNewtonWorld*)NewtonWorldGetUserData(NewtonBodyGetWorld(m_body)); ScopeLock scopelock(&m_lock); m_interpolatedPosit = m_posit0 + (m_posit1 - m_posit0).Scale(world->m_interpotationParam); return &m_interpolatedPosit.m_x; }
void dNewtonBody::OnBodyTransform(const dFloat* const matrixPtr, int threadIndex) { dMatrix matrix(matrixPtr); ScopeLock scopelock(&m_lock); m_posit0 = m_posit1; m_rotation0 = m_rotation1; m_posit1 = matrix.m_posit; m_rotation1 = dQuaternion(matrix); dFloat angle = m_rotation0.DotProduct(m_rotation1); if (angle < 0.0f) { m_rotation1.Scale(-1.0f); } }
void rayPickerManager::SetPickedBody (dNewtonBody* const body, const Vec4& handle) { dNewton::ScopeLock scopelock (&m_lock); m_pickedBody = body; if (m_pickedBody) { Matrix matrix; if (m_pickedBody->GetType() == dNewtonBody::m_dynamic) { matrix.invert(((newtonDynamicBody*) body)->GetMatrix()); } else { dAssert (0); } m_localpHandlePoint = handle * matrix; m_globalTarget = handle; } }
/** * routine executed by worker threads. * * @function worker_routine * * @date 2016-01-15 * * @revision none * * @designer Eric Tsang * * @programmer Eric Tsang * * @note * * continuously reads tasks from the tasks vector, executes them, and writes the * results to the results pipe for the parent to receive. * * once there are no more tasks to execute, the thread terminates. * * @signature void* worker_routine(void*) */ void* worker_routine(void*) { bool yield = false; while(true) { if (yield) { pthread_yield(); yield = false; } Number* loBoundPtr; // get the next task that needs processing { Lock scopelock(&taskAccess.sem); // if there are tasks available to get, get them if(!tasks.empty()) { loBoundPtr = tasks.back(); tasks.pop_back(); } // otherwise, if there are tasks available in the future, wait for // them to be available else if(!allTasksProduced) { yield = true; continue; } // otherwise, there are no more tasks, end the loop else { break; } } tasksNotFullSem.post(); // calculate the hiBound for a task Number hiBound; mpz_add_ui(hiBound.value,loBoundPtr->value,MAX_NUMBERS_PER_TASK-1); if(mpz_cmp(hiBound.value,prime.value) > 0) { mpz_set(hiBound.value,prime.value); } // create the task FindFactorsTask newTask(prime.value,hiBound.value,loBoundPtr->value); // do the processing newTask.execute(); // post results of the tasks { Lock scopelock(&resultAccess.sem); std::vector<mpz_t*>* taskResults = newTask.get_results(); for(register unsigned int i = 0; i < taskResults->size(); ++i) { Number* numPtr = new Number(); mpz_set(numPtr->value,*taskResults->at(i)); results.push_back(numPtr); } } delete loBoundPtr; } pthread_exit(0); }
/** * entry point of the program. * * @function main * * @date 2016-01-15 * * @revision none * * @designer Eric Tsang * * @programmer Eric Tsang * * @note * * sets up synchronization primitives, spawns worker threads, generates tasks * for workers, receives results from workers, waits for workers to terminate, * writes results to a file, and stdout. * * @signature int main(int argc,char** argv) * * @param argc number of command line arguments * @param argv array of c strings of command line arguments * * @return status code. */ int main(int argc,char** argv) { // parse command line arguments if (argc != 4) { fprintf(stderr,"usage: %s [integer] [path to log file] [num workers]\n",argv[0]); return 1; } if(mpz_set_str(prime.value,argv[1],10) == -1) { fprintf(stderr,"usage: %s [integer] [path to log file] [num workers]\n",argv[0]); return 1; } int logfile = open(argv[2],O_CREAT|O_WRONLY|O_APPEND); FILE* logFileOut = fdopen(logfile,"w"); if(logfile == -1 || errno) { fprintf(stderr,"usage: %s [integer] [path to log file] [num workers]\nerror occurred: ",argv[0]); perror(0); return 1; } unsigned int numWorkers = atoi(argv[3]); if (numWorkers <= 0) { fprintf(stderr,"usage: %s [integer] [path to log file] [num workers]\n num workers must be larger than or equal to 1",argv[0]); return 1; } // set up synchronization primitives for(register unsigned int i; i < numWorkers*MAX_PENDING_TASKS_PER_WORKER; ++i) { tasksNotFullSem.post(); } // get start time long startTime = current_timestamp(); // create the worker threads std::vector<pthread_t> workers; for(register unsigned int i = 0; i < numWorkers; ++i) { pthread_t worker; pthread_create(&worker,0,worker_routine,0); workers.push_back(worker); } // create tasks and place them into the tasks vector { Number prevPercentageComplete; Number percentageComplete; Number tempLoBound; Number loBound; for(mpz_set_ui(loBound.value,1); mpz_cmp(loBound.value,prime.value) <= 0; mpz_add_ui(loBound.value,loBound.value,MAX_NUMBERS_PER_TASK)) { // calculate and print percentage complete mpz_set(prevPercentageComplete.value,percentageComplete.value); mpz_mul_ui(tempLoBound.value,loBound.value,100); mpz_div(percentageComplete.value,tempLoBound.value,prime.value); if(mpz_cmp(prevPercentageComplete.value,percentageComplete.value) != 0) { gmp_fprintf(stdout,"%Zd%\n",percentageComplete.value); gmp_fprintf(logFileOut,"%Zd%\n",percentageComplete.value); } // insert the task into the task queue once there is room Number* newNum = new Number(); mpz_set(newNum->value,loBound.value); tasksNotFullSem.wait(); Lock scopelock(&taskAccess.sem); tasks.push_back(newNum); } } allTasksProduced = true; // join all worker threads for(register unsigned int i = 0; i < numWorkers; ++i) { void* unused; pthread_join(workers[i],&unused); } // get end time long endTime = current_timestamp(); // print out calculation results std::sort(results.begin(),results.end(),[](Number* i,Number* j) { return mpz_cmp(i->value,j->value) < 0; }); fprintf(stdout,"factors: "); fprintf(logFileOut,"factors: "); for(register unsigned int i = 0; i < results.size(); ++i) { gmp_fprintf(stdout,"%s%Zd",i?", ":"",results[i]->value); gmp_fprintf(logFileOut,"%s%Zd",i?", ":"",results[i]->value); delete results[i]; } fprintf(stdout,"\n"); fprintf(logFileOut,"\n"); // print out execution results fprintf(stdout,"total runtime: %lums\n",endTime-startTime); fprintf(logFileOut,"total runtime: %lums\n",endTime-startTime); // release system resources fclose(logFileOut); close(logfile); return 0; }
void rayPickerManager::SetTarget (const Vec4& targetPoint) { dNewton::ScopeLock scopelock (&m_lock); m_globalTarget = targetPoint; }