void MxCore::moveLocal( const osg::Vec3d& delta ) { const osg::Vec3d scaledDelta( delta[0] * _moveScale[0], delta[1] * _moveScale[1], delta[2] * _moveScale[2] ); _position += ( scaledDelta * getOrientationMatrix() ); _orbitCenter += ( scaledDelta * getOrientationMatrix() ); }
void Quadrotor::lookAtQuad() { if(orientationMode == QuadOrientationMode::ANOTHERQUAD) { glm::vec3 otherQuadPosition = otherQuad->getQuadPosition(); glm::vec3 otherDirectionRelative = otherQuadPosition - getQuadPosition(); glm::vec3 upVector,tempVector; //getOrientation(); glm::vec3 eye = glm::vec3(0,0,0),center = otherDirectionRelative,up = glm::vec3(0,1,0); Model = getOrientationMatrix(eye,center,up); Model = glm::rotate(Model,-glm::half_pi<float>(),glm::vec3(0,1,0)); } else if(orientationMode == QuadOrientationMode::POINT) { glm::vec3 otherDirectionRelative = lookAtPoint - getQuadPosition(); glm::vec3 upVector,tempVector; //getOrientation(); glm::vec3 eye = glm::vec3(0,0,0),center = otherDirectionRelative,up = glm::vec3(0,1,0); Model = getOrientationMatrix(eye,center,up); Model = glm::rotate(Model,-glm::half_pi<float>(),glm::vec3(0,1,0)); } }
glm::mat4 Transform::getModelMatrix(){ if(mDirty){ mMatrix = getTranslationMatrix() * getOrientationMatrix() * getScaleMatrix(); mDirty = false; } return mMatrix; }
const glm::mat4 & Transform::getOrientationScaleMatrix(){ if(osDirty){ osMatrix = getOrientationMatrix() * getScaleMatrix(); osDirty = false; } return osMatrix; }
void chase(glm::mat4 tar) { float newRadian; // showMat4("Chase target: ", tar); //get the foward vector of the missile glm::vec3 missileForwardVec = getIn(getOrientationMatrix()); //get the distance vector between the missile and the target glm::vec3 distanceVec = getPosition(tar) - getMissilePosition(); //normalizethe missile's forward and distance vector glm::vec3 targetNormal = glm::normalize(distanceVec); glm::vec3 missileNormal = glm::normalize(missileForwardVec); //showVec3("Target", targetNormal); // showVec3("Missile", missileNormal); if (!(colinear(targetNormal, missileNormal, 0.1f)) ) { //showVec3("distance Vec Normal",targetNormal); //gets the cross product to find the axis of rotation //glm::vec3 axisOfRotation = glm::cross(targetNormal, missileNormal); glm::vec3 axisOfRotation = glm::cross(missileNormal, targetNormal); axisOfRotation = glm::normalize(axisOfRotation); //gets the axis of rotation's direction float axisOfRotationDirection = axisOfRotation.x + axisOfRotation.y + axisOfRotation.z; //printf("AOR-Direction: %f\n",axisOfRotationDirection); // get the dot product to find the rotation amount float totalRotation = glm::dot(missileNormal, targetNormal); //float totalRotation = glm::dot(targetNormal, missileNormal); // get the length of the missile and target's normal float LOMN = glm::abs(distance(missileNormal, glm::vec3(0, 0, 0))); float LOTN = glm::abs(distance(targetNormal, glm::vec3(0, 0, 0))); //float totalRotation = glm::acos(glm::dot(targetNormal, missileNormal)); //printf("Total Rotation: %f\n", totalRotation); //printf("AOR Direction: %f\n", axisOfRotationDirection); //check for the direction in which the missile is suppose to move in if (axisOfRotationDirection >= 0.01) newRadian = glm::acos(totalRotation); else newRadian = - glm::acos(totalRotation); rotationMatrix = glm::rotate(identity, (newRadian / 4.0f), axisOfRotation); } else { rotationMatrix = identity; //printf("colinear\n"); } }
// function tests for collision from cases // case 0: tests for collision if the missile is looking for a target in its detection radius // case 1: tests for collision if the missile has it's target and when it collides with the target // return int; 1 for collision, 0 no collision bool collision(glm::mat4 tar, float tarBR, int whichBR) { float getDistance; float rad; switch (whichBR) { case 0: getDistance = distance(getPosition(tar), getPosition(getDetectionMatrix())); rad = detectionRadius; break; case 1: getDistance = distance(getPosition(tar),getPosition(getOrientationMatrix())); rad = tarBR; break; } if (getDistance < rad + modelBR) return true; return false; }
// function that sets the new translation // glm::mat4 newTranslation & glm::vec3 newVector void setTranslationMatrix(glm::vec3 newVector) { translationMatrix = glm::translate(getOrientationMatrix(), newVector); }
void ViewingCore::rotate( osg::Vec2d start, osg::Vec2d dir ) { if( dir.length2() == 0. ) // No motion return; if( _mode == FIRST_PERSON ) { // Position is constant in 1st person view. Obtain it (for later use) // *before* we alter the _viewDir. const osg::Vec3d position = getEyePosition(); // Compute rotation matrix. osg::Vec3d cross = _viewDir ^ _viewUp; osg::Matrix m = osg::Matrix::rotate( dir[ 0 ], _viewUp ) * osg::Matrix::rotate( -dir[ 1 ], cross ); // Re-orient the basis. _viewDir = _viewDir * m; _viewUp = _viewUp * m; // Orthonormalize. cross = _viewDir ^ _viewUp; _viewUp = cross ^ _viewDir; _viewDir.normalize(); _viewUp.normalize(); // Compute the new view center. _viewCenter = position + ( _viewDir * _viewDistance ); } else { // THIRD_PERSON const osg::Matrixd orientMat = getOrientationMatrix(); // Take the spin direction 'dir' and rotate it 90 degrees // to get our base axis (still in the window plane). // Simultaneously convert to current view space. osg::Vec2d screenAxis( -dir[ 1 ], dir[ 0 ] ); const osg::Vec3d baseAxis = osg::Vec3d( screenAxis[ 0 ], screenAxis[ 1 ], 0. ) * orientMat; osg::Vec3d dir3 = osg::Vec3d( dir[ 0 ], dir[ 1 ], 0. ) * orientMat; dir3.normalize(); // The distance from center, along with the roll sensitivity, // tells us how much to rotate the baseAxis (ballTouchAngle) to get // the actual ballAxis. const double distance = start.length(); const double rotationDir( ( screenAxis * start > 0. ) ? -1. : 1. ); const double ballTouchAngle = rotationDir * _trackballRollSensitivity * distance; osg::Vec3d ballAxis = baseAxis * osg::Matrixd::rotate( ballTouchAngle, dir3 ); ballAxis.normalize(); osg::Matrixd m = osg::Matrixd::rotate( -( dir.length() ), ballAxis ); // Re-orient the basis. _viewDir = _viewDir * m; _viewUp = _viewUp * m; // Orthonormalize. osg::Vec3d cross = _viewDir ^ _viewUp; _viewUp = cross ^ _viewDir; _viewDir.normalize(); _viewUp.normalize(); } }
wxThread::ExitCode HaloRenderingThread::Entry() { wxCommandEvent evt(wxEVT_HALO_RENDERING_THREAD_NOTIFY, wxID_ANY); setupStruct.resultValid = false; setupStruct.imageBuffer = 0; setupStruct.rayPaths = new map<RayPathId, RayPathDescriptor>; if (setupStruct.crystals.size() == 0) { evt.SetString(wxT("No crystal population set up.")); evt.SetInt(1); setupStruct.notifee->AddPendingEvent(evt); return 0; } // Cast rays on crystals and refracted rays will form a pixel. int crystalTypeIndex = 0; CrystalDescriptor *currentDescriptor = &setupStruct.crystals[0]; const int N_CRYSTAL_TYPES = setupStruct.crystals.size(); int crystalsRemaining = currentDescriptor->populationWeight; Mesh currentMesh; size_t percentStep = setupStruct.crystalCount / 100; if (percentStep < 1) percentStep = 1; Vector3 sunPos(0, 0, -100000); rotate2d(sunPos.y, sunPos.z, setupStruct.solarAltitude * 3.14159265636 / 180.0); // Two prependicular vector Vector3 prepX = sunPos % Vector3(0, 1, 0); // FIXME: Sun on the zenith Vector3 prepY = sunPos % prepX; prepX /= ~prepX; prepY /= ~prepY; setupStruct.deleteBuffer = freeBuffer; setupStruct.deleteMap = freeMap; size_t size = setupStruct.imageSize; setupStruct.imageBuffer = new uint32_t[size * size * 6]; memset(setupStruct.imageBuffer, 0, size * size * 6 * sizeof(uint32_t)); uint32_t *leftPlane = setupStruct.imageBuffer; // 0th plane uint32_t *rightPlane = setupStruct.imageBuffer + size * size; // 1st plane uint32_t *topPlane = setupStruct.imageBuffer + 2 * size * size; // 2nd plane uint32_t *bottomPlane = setupStruct.imageBuffer + 3 * size * size; // 3rd plane uint32_t *backPlane = setupStruct.imageBuffer + 4 * size * size; // 4th plane uint32_t *frontPlane = setupStruct.imageBuffer + 5 * size * size; // 5th plane double halfImageSize = size * 0.5; int maxRays = (setupStruct.maxRayCastInfoSize * 1000000) / (sizeof(RayPathDescriptor) + sizeof(RayPathId)); if (maxRays == 0) maxRays = 1; int recordRayModulus = setupStruct.crystalCount / maxRays; if (!recordRayModulus) recordRayModulus = 1; struct RefractionColor { int rgb; double refractionIndex; }; RefractionColor colors[] = { { 0x0000FF, 1.3072 }, { 0x0080FF, 1.3094 }, { 0x00FFFF, 1.31 }, { 0x00FF80, 1.3107 }, { 0x00FF00, 1.3114 }, { 0x80FF00, 1.3125 }, { 0xFFFF00, 1.3136 }, { 0xFF8000, 1.3147 }, { 0xFF0000, 1.3158 }, { 0xFF0040, 1.3172 }, { 0xFF0080, 1.32 }, }; const int N_COLORS = sizeof(colors) / sizeof(colors[0]); // Cast many rays. for (size_t i = 0; i < setupStruct.crystalCount; i++) { if (setupStruct.cancelled) { // If the user shut the rendering down... delete[] setupStruct.imageBuffer; setupStruct.imageBuffer = 0; return 0; } if (!crystalsRemaining) { // We iterate through the crystals based on their population weights. crystalTypeIndex++; if (crystalTypeIndex >= N_CRYSTAL_TYPES) crystalTypeIndex = 0; currentDescriptor = &setupStruct.crystals[crystalTypeIndex]; crystalsRemaining = currentDescriptor->populationWeight; } // Get the raw mesh currentMesh = currentDescriptor->mesh; // Rotate it according to the orientation. Matrix orientationMatrix = getOrientationMatrix(currentDescriptor->orientation); // Apply wobbliness Vector3 wobbleRotationAxis(1, 0, 0); rotate2d(wobbleRotationAxis.x, wobbleRotationAxis.z, randFloat(0, 3.1415)); double wobblinessLimit = currentDescriptor->wobbliness * 3.1415 / 180.0; Matrix wobbleMatrix = createRotationMatrix( wobbleRotationAxis, randFloatNormal( 0, wobblinessLimit ) ); Matrix transformation = orientationMatrix % wobbleMatrix; transformMesh(currentMesh, transformation); // Crystal created, now cast a ray on it. Vector3 offset = prepX * randFloat(-1, 1) + prepY * randFloat(-1, 1); vector<RayPath> rayPaths; // Compute color here double colorCode = randFloat(0, N_COLORS - 1); RefractionColor prev = colors[(int)(floor(colorCode))]; RefractionColor next = colors[(int)(ceil(colorCode))]; double kColor = colorCode - floor(colorCode); RefractionColor currentColor; currentColor.rgb = prev.rgb; currentColor.refractionIndex = (1 - kColor) * prev.refractionIndex + kColor * next.refractionIndex; // Compute real poisition of the ray (Sun is a disk) Vector3 realSunPos = sunPos; Vector3 rayRotVector; double rayRotVectorLength; do { rayRotVector = realSunPos % getRandomVector(); rayRotVectorLength = ~rayRotVector; } while (rayRotVectorLength == 0); rayRotVector /= rayRotVectorLength; realSunPos = transformVector( createRotationMatrix( rayRotVector, randFloat( 0, setupStruct.solarDiskRadius * 3.1415926536 / 180.0 ) ), realSunPos ); computeRayPathInGlassMesh(currentMesh, currentColor.refractionIndex, realSunPos + offset, -realSunPos, 0.01, rayPaths); /* Project rays on the six planes. */ for (size_t j = 0; j < rayPaths.size(); j++) { RayPath ¤t = rayPaths[j]; size_t pathLength = current.size(); Vector3 exitDir = current[pathLength - 1].first - current[pathLength - 2].first; Vector3 projectionDir = -exitDir; double xPos, yPos; // select the plane to project on. uint32_t *plane; double xm = 1, ym = 1; int planeId; if ((fabs(projectionDir.x) > fabs(projectionDir.y)) && (fabs(projectionDir.x) > fabs(projectionDir.z))) { if (projectionDir.x < 0) { plane = leftPlane; planeId = 0; xm = -1; } else { plane = rightPlane; planeId = 1; } xPos = xm * projectionDir.z / fabs(projectionDir.x) * halfImageSize + halfImageSize; yPos = -ym * projectionDir.y / fabs(projectionDir.x) * halfImageSize + halfImageSize; } if ((fabs(projectionDir.y) > fabs(projectionDir.x)) && (fabs(projectionDir.y) > fabs(projectionDir.z))) { if (projectionDir.y < 0) { plane = bottomPlane; planeId = 3; ym = -1; } else { plane = topPlane; planeId = 2; } xPos = xm * projectionDir.x / fabs(projectionDir.y) * halfImageSize + halfImageSize; yPos = -ym * projectionDir.z / fabs(projectionDir.y) * halfImageSize + halfImageSize; } if ((fabs(projectionDir.z) > fabs(projectionDir.x)) && (fabs(projectionDir.z) > fabs(projectionDir.y))) { if (projectionDir.z < 0) { plane = frontPlane; planeId = 5; } else { plane = backPlane; planeId = 4; xm = -1; } xPos = xm * projectionDir.x / fabs(projectionDir.z) * halfImageSize + halfImageSize; yPos = -ym * projectionDir.y / fabs(projectionDir.z) * halfImageSize + halfImageSize; } // Calculate the new intensity of the pixel. xPos = clampInInt(xPos, 0, size - 1); yPos = clampInInt(yPos, 0, size - 1); int prevPixel = plane[(int)(yPos) * size + (int)(xPos)]; int nextPixel = 0; double intensity = current[pathLength - 2].second * 20; for (int j = 0; j < 3; j++) { int currentSaturation = (prevPixel >> (8 * j)) & 0xFF; int toAdd = (int)(((currentColor.rgb >> (8 * j)) & 0xFF) * intensity) >> 8; int nextSaturation; if (currentSaturation + toAdd > 255) nextSaturation = 255; else nextSaturation = currentSaturation + toAdd; nextPixel += (1 << (8 * j)) * nextSaturation * setupStruct.pixelIntensity; } plane[(int)(yPos) * size + (int)(xPos)] = nextPixel; // Record the ray if needed if (!(i % recordRayModulus)) { RayPathId pixelId(planeId, (int)xPos, (int)yPos); RayPathDescriptor theDescriptor( ¤tDescriptor->mesh, transformation, realSunPos + offset, -realSunPos, intensity ); map<RayPathId, RayPathDescriptor>::iterator it = setupStruct.rayPaths->find(pixelId); if (it == setupStruct.rayPaths->end()) { // If not found, insert it as new setupStruct.rayPaths->insert( make_pair( pixelId, theDescriptor ) ); } else if (it->second.intensity < intensity) { // If found, update it if the current ray is more intense it->second = theDescriptor; } } } if (i % percentStep == 0) { sendNotifyString(wxString::Format(wxT("Casting rays: %d%%"), i / percentStep)); } crystalsRemaining--; } evt.SetString(wxT("Completed.")); evt.SetInt(1); //< 1 means the operation is finished. setupStruct.resultValid = true; setupStruct.notifee->AddPendingEvent(evt); return 0; }
void Quadrotor::executeTimeLineCommand() { //* //return; if(readTimeline) { double current_time = QuadTimer::GetProcessTime(); if(!isExecuting) { char command[100]; char* commandstr; double peektime = -1; //double com_time; commandstr = timeline->readNextCommand(peektime); //read the command type if(sscanf(commandstr,"%lf %s",&comTime,command)==EOF) {readTimeline = false; return;} sprintf(delayedCommand,"%lf %s",peektime,commandstr); isExecuting = true; } else if(current_time>=comTime && !isMoving) { //command to set quad position sscanf(delayedCommand,"%lf %lf %s",&nextTime,&comTime,command); //printf("\n%s",command); //printf("\n%s",delayedCommand); comOrientationTime = 0; if(!strcmp(command,"POS")) { sscanf(delayedCommand,"%lf %lf %s %f %f %f",&nextTime,&comTime, command,&comVect.x,&comVect.y,&comVect.z); moveAbs(comVect) ; } else if(!strcmp(command,"ROT")) { sscanf(delayedCommand,"%lf %lf %s %f %f %f",&nextTime,&comTime, command,&comVect.x,&comVect.y,&comVect.z); } else if(!strcmp(command,"MOV")) { sscanf(delayedCommand,"%lf %lf %s %lf %f %f %f",&nextTime,&comTime, command,&comOrientationTime,&comVect.x,&comVect.y,&comVect.z); isExecuting = true; quadTime.getTimeDiffSec(); comOrientationTime = current_time + comOrientationTime; if(orientationMode == QuadOrientationMode::FREE) {} else if(orientationMode == QuadOrientationMode::ANOTHERQUAD) { } else if(orientationMode == QuadOrientationMode::UPRIGHT) {} //Operations to align the quad with the direction of motion comDirection = glm::vec3(comVect.x-pos_x,comVect.y-pos_y,comVect.z-pos_z); comDirection = glm::normalize(comDirection); /*glm::vec3 x_axis(1.0f,0.0f,0.0f); * glm::vec3 rotation_axis = glm::cross(comDirection,x_axis); * * * rotation_axis = glm::normalize(rotation_axis); * float angle = glm::angle(x_axis,comDirection); * Model = glm::rotate(glm::mat4(1.0f), -angle, rotation_axis); */ } else if(!strcmp(command,"LOOKATQUAD")) { char quadname[10]; sscanf(delayedCommand,"%lf %lf %s %s",&nextTime,&comTime,command, quadname); otherQuad = Quadrotor::getQuadFromName(quadname); orientationMode = QuadOrientationMode::ANOTHERQUAD; } else if(!strcmp(command,"LOOKATPOINT")) { glm::vec3 position; sscanf(delayedCommand,"%lf %lf %s %f %f %f",&nextTime,&comTime,command, &position.x,&position.y,&position.z); lookAtPoint = position; orientationMode = QuadOrientationMode::POINT; } else if(!strcmp(command,"FREE")) { orientationMode = QuadOrientationMode::FREE; } else if(!strcmp(command,"FIREAT")) { float r,g,b,a; char ammotype[20]; char quadname[10]; sscanf(delayedCommand,"%lf %lf %s %s %f %f %f %f %s",&nextTime,&comTime,command, quadname,&r,&g,&b,&a,ammotype); AMMOTYPE::ENUM ammo_type = AMMOTYPE::getAmmotypeFromString(string(ammotype)); Ammo::fire(getBarrelPosition(),string(quadname),glm::vec4(r,g,b,a),5,this,ammo_type); } else if(!strcmp(command,"FIREATPOINT")) { float r,g,b,a; char ammotype[20]; glm::vec3 position; sscanf(delayedCommand,"%lf %lf %s %f %f %f %f %f %f %f %s",&nextTime,&comTime,command, &position.x, &position.y, &position.z,&r,&g,&b,&a,ammotype); AMMOTYPE::ENUM ammo_type = AMMOTYPE::getAmmotypeFromString(string(ammotype)); Ammo::fire(getBarrelPosition(),position,glm::vec4(r,g,b,a),5,this,ammo_type); } customCommandParser(string(delayedCommand)); //Operations to align the quad with the direction of motion isMoving = true; // printf("\nGot command:%f %f %f %f",com_time,com_posx,com_posy,com_posz); } else if(current_time<=comOrientationTime) //dont have to worry about modes other than MOV { glm::vec3 current_axis, current_up; double delta_time = comOrientationTime-current_time; getOrientation(current_axis,current_up,glm::vec3(1.0,0.0,0.0)); current_axis = glm::normalize(current_axis); comRotationAxis = glm::cross(current_axis,comDirection); double timediff = quadTime.getTimeDiffSec(); if(timediff>delta_time) timediff = delta_time; float axisAngle = glm::angle(current_axis,comDirection); // printf("\nX: %f",angle_axis); /*if(axisAngle>Pi) { printf("\n%f",axisAngle); axisAngle = (2*Pi-axisAngle); }*/ axisAngle = axisAngle*(float) (timediff/ delta_time); Model = glm::rotate(Model,axisAngle,comRotationAxis); //* glm::vec3 eye = glm::vec3(0,0,0), center = glm::vec3( Model*glm::vec4(1.0f,0.0f,0.0f,1.0f)), up = glm::vec3(0,1,0); glm::mat4 mm = getOrientationMatrix(eye,center,up); Model = mm; Model = glm::rotate(Model,-glm::half_pi<float>(),glm::vec3(0,1,0)); //*/ } else if(current_time>=nextTime) { isExecuting = false;isMoving=false;} else if(current_time>=comTime) { if(!strcmp(command,"MOV")) { glm::vec3 distance = glm::vec3(comVect.x-pos_x,comVect.y-pos_y,comVect.z-pos_z); /* if(orientationMode == QuadOrientationMode::ANOTHERQUAD) { glm::vec3 otherQuadPosition = otherQuad->getQuadPosition(); glm::vec3 otherDirectionRelative = otherQuadPosition - getQuadPosition(); glm::vec3 upVector,tempVector; //getOrientation(); glm::vec3 eye = glm::vec3(0,0,0),center = otherDirectionRelative,up = glm::vec3(0,1,0); glm::mat4 mm = getOrientationMatrix(eye,center,up); Model = mm; Model = glm::rotate(Model,-glm::half_pi<float>(),glm::vec3(0,1,0)); }*/ if(orientationMode != QuadOrientationMode::ANOTHERQUAD && orientationMode != QuadOrientationMode::POINT) { //* glm::vec3 eye = glm::vec3(0,0,0), center = comDirection, up = glm::vec3(0,1,0); glm::mat4 mm = getOrientationMatrix(eye,center,up); Model = mm; Model = glm::rotate(Model,-glm::half_pi<float>(),glm::vec3(0,1,0)); //*/ } double delta_time = nextTime-current_time; double timediff = quadTime.getTimeDiffSec(); if(delta_time < timediff) timediff=delta_time; glm::vec3 dist2 = distance *(float) (timediff/ delta_time); moveRel(dist2); // printf("\ndelta pos:%f %f %f",dist2.x,dist2.y,dist2.z); } } // printf("\ncurrent pos:%f %f %f",pos_x, pos_y,pos_z); } //*/ }