////////////////////////////////////////////////////////////////////////////// // transformFrustum - // Transform srcFrustum by mat, result in dstFrustum. // ////////////////////////////////////////////////////////////////////////////// void transformFrustum( const hduMatrix& mat, const hduVector3Dd* srcFrustum, hduVector3Dd* dstFrustum ) { for (int i = 0; i < 8; ++i) { hduVector3Dd dst; mat.multVecMatrix(srcFrustum[i], dst); dstFrustum[i][0] = dst[0]; dstFrustum[i][1] = dst[1]; dstFrustum[i][2] = dst[2]; } }
/*************************************************************************************** Servo loop thread callback. Computes a force effect. This callback defines the motion of the purple skull and calculates the force based on the "real-time" Proxy position in Device space. ****************************************************************************************/ void HLCALLBACK computeForceCB(HDdouble force[3], HLcache *cache, void *userdata) { DataTransportClass *localdataObject = (DataTransportClass *) userdata;//Typecast the pointer passed in appropriately hduVector3Dd skullPositionDS;//Position of the skull (Moving sphere) in Device Space. hduVector3Dd proxyPosition;//Position of the proxy in device space HDdouble instRate = 0.0; HDdouble deltaT = 0.0; static float counter = 0.0; float degInRad = 0.0; static int counter1 = 0; // Get the time delta since the last update. hdGetDoublev(HD_INSTANTANEOUS_UPDATE_RATE, &instRate); deltaT = 1.0 / instRate; counter+=deltaT; degInRad = counter*20*3.14159/180; hduVector3Dd ModelPos = localdataObject->Model->getTranslation(); localdataObject->Model->setTranslation(-ModelPos); localdataObject->Model->setTranslation(cos(degInRad)*64.0, sin(degInRad)*64.0,5.0);//Move the skull aroubnd in a circle WorldToDevice.multVecMatrix(localdataObject->Model->getTranslation(),skullPositionDS);//Convert the position of the sphere from world space to device space hlCacheGetDoublev(cache, HL_PROXY_POSITION, proxyPosition);//Get the position of the proxy in Device Coordinates (All HL commands in the servo loop callback fetch values in device coordinates) forceVec = forceField(proxyPosition, skullPositionDS, 40.0, 5.0);//Calculate the force counter1++; if(counter1>2000)//Make the force start after 2 seconds of program start. This is because the servo loop thread executes before the graphics thread. //Hence global variables set in the graphics thread will not be valid for sometime in the begining og the program { force[0] = forceVec[0]; force[1] = forceVec[1]; force[2] = forceVec[2]; counter1 = 2001; } else { force[0] = 0.0; force[1] = 0.0; force[2] = 0.0; } }