void ImpostorPage::update() { //Calculate the direction the impostor batches should be facing Vector3 camPos = geom->_convertToLocal(geom->getCamera()->getDerivedPosition()); //Update all batches float distX = camPos.x - center.x; float distZ = camPos.z - center.z; float distY = camPos.y - center.y; float distRelZ = Math::Sqrt(distX * distX + distZ * distZ); Radian pitch = Math::ATan2(distY, distRelZ); Radian yaw; if (distRelZ > geom->getPageSize() * 3) { yaw = Math::ATan2(distX, distZ); } else { Vector3 dir = geom->_convertToLocal(geom->getCamera()->getDerivedDirection()); yaw = Math::ATan2(-dir.x, -dir.z); } std::map<String, ImpostorBatch *>::iterator iter; for (iter = impostorBatches.begin(); iter != impostorBatches.end(); ++iter){ ImpostorBatch *ibatch = iter->second; ibatch->setAngle(pitch.valueDegrees(), yaw.valueDegrees()); } }
//----------------------------------------------------------------------------- /// void ImpostorPage::update() { if (m_mapImpostorBatches.empty()) // SVA speed up return; //Calculate the direction the impostor batches should be facing Vector3 camPos = m_pPagedGeom->_convertToLocal(m_pPagedGeom->getCamera()->getDerivedPosition()); // Update all batches Ogre::Real distX = camPos.x - m_vecCenter.x; Ogre::Real distZ = camPos.z - m_vecCenter.z; Ogre::Real distY = camPos.y - m_vecCenter.y; Ogre::Real distRelZ = Math::Sqrt(distX * distX + distZ * distZ); Radian pitch = Math::ATan2(distY, distRelZ); Radian yaw; if (distRelZ > m_pPagedGeom->getPageSize() * 3) { yaw = Math::ATan2(distX, distZ); } else { Vector3 dir = m_pPagedGeom->_convertToLocal(m_pPagedGeom->getCamera()->getDerivedDirection()); yaw = Math::ATan2(-dir.x, -dir.z); } TImpostorBatchs::iterator iter = m_mapImpostorBatches.begin(), iend = m_mapImpostorBatches.end(); while (iter != iend) { iter->second->setAngle(pitch.valueDegrees(), yaw.valueDegrees()); ++iter; } }
//----------------------------------------------------------------------- void MeshParticleVisualData::setOrientation( const Radian &yaw, const Radian &pitch, const Radian &roll ) { Quaternion yawQua(Degree(yaw.valueDegrees()), Vector3::UNIT_Y); Quaternion pitchQua(Degree(pitch.valueDegrees()), Vector3::UNIT_X); Quaternion rollQua(Degree(roll.valueDegrees()), Vector3::UNIT_Z); mSceneNode->setOrientation(yawQua * pitchQua * rollQua); }
void Camera::renderObject() { if(polygonMode == PM_SOLID) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); else if(polygonMode == PM_WIREFRAME) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); else if(polygonMode == PM_POINTS) glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); glLoadIdentity(); // Reset The View // update parameters if it's tracking if(autoTrackingEnabled && trackingTarget != NULL) { setOrientation(trackingTarget->getOrientation()); setPosition(trackingTarget->getPosition() + trackingOffset); } Radian radRotation; WasVec3d axis; rotation.inverse().toAngleAxis(radRotation, axis); glRotatef(radRotation.valueDegrees(), axis.x, axis.y, axis.z); glTranslatef(-translation[0], -translation[1], -translation[2]); }
Degree::Degree(const Radian& value) : mValue(value.valueDegrees()) { }
Degree Degree::operator - (const Radian& rhs) const { return Degree(mValue - rhs.valueDegrees()); }
inline Degree::Degree(Radian radians) : mDegValue(radians.valueDegrees()) {}
/// Default shadow camera setup implementation void DefaultShadowCameraSetup::getShadowCamera (const SceneManager *sm, const Camera *cam, const Viewport *vp, const Light *light, Camera *texCam, size_t iteration) const { Vector3 pos, dir; // reset custom view / projection matrix in case already set texCam->setCustomViewMatrix(false); texCam->setCustomProjectionMatrix(false); texCam->setNearClipDistance(light->_deriveShadowNearClipDistance(cam)); texCam->setFarClipDistance(light->_deriveShadowFarClipDistance(cam)); // get the shadow frustum's far distance Real shadowDist = light->getShadowFarDistance(); if (!shadowDist) { // need a shadow distance, make one up shadowDist = cam->getNearClipDistance() * 300; } Real shadowOffset = shadowDist * (sm->getShadowDirLightTextureOffset()); // Directional lights if (light->getType() == Light::LT_DIRECTIONAL) { // set up the shadow texture // Set ortho projection texCam->setProjectionType(PT_ORTHOGRAPHIC); // set ortho window so that texture covers far dist texCam->setOrthoWindow(shadowDist * 2, shadowDist * 2); // Calculate look at position // We want to look at a spot shadowOffset away from near plane // 0.5 is a little too close for angles Vector3 target = cam->getDerivedPosition() + (cam->getDerivedDirection() * shadowOffset); // Calculate direction, which same as directional light direction dir = - light->getDerivedDirection(); // backwards since point down -z dir.normalise(); // Calculate position // We want to be in the -ve direction of the light direction // far enough to project for the dir light extrusion distance pos = target + dir * sm->getShadowDirectionalLightExtrusionDistance(); // Round local x/y position based on a world-space texel; this helps to reduce // jittering caused by the projection moving with the camera // Viewport is 2 * near clip distance across (90 degree fov) //~ Real worldTexelSize = (texCam->getNearClipDistance() * 20) / vp->getActualWidth(); //~ pos.x -= fmod(pos.x, worldTexelSize); //~ pos.y -= fmod(pos.y, worldTexelSize); //~ pos.z -= fmod(pos.z, worldTexelSize); Real worldTexelSize = (shadowDist * 2) / texCam->getViewport()->getActualWidth(); //get texCam orientation Vector3 up = Vector3::UNIT_Y; // Check it's not coincident with dir if (Math::Abs(up.dotProduct(dir)) >= 1.0f) { // Use camera up up = Vector3::UNIT_Z; } // cross twice to rederive, only direction is unaltered Vector3 left = dir.crossProduct(up); left.normalise(); up = dir.crossProduct(left); up.normalise(); // Derive quaternion from axes Quaternion q; q.FromAxes(left, up, dir); //convert world space camera position into light space Vector3 lightSpacePos = q.Inverse() * pos; //snap to nearest texel lightSpacePos.x -= fmod(lightSpacePos.x, worldTexelSize); lightSpacePos.y -= fmod(lightSpacePos.y, worldTexelSize); //convert back to world space pos = q * lightSpacePos; } // Spotlight else if (light->getType() == Light::LT_SPOTLIGHT) { // Set perspective projection texCam->setProjectionType(PT_PERSPECTIVE); // set FOV slightly larger than the spotlight range to ensure coverage Radian fovy = light->getSpotlightOuterAngle()*1.2; // limit angle if (fovy.valueDegrees() > 175) fovy = Degree(175); texCam->setFOVy(fovy); // Calculate position, which same as spotlight position pos = light->getDerivedPosition(); // Calculate direction, which same as spotlight direction dir = - light->getDerivedDirection(); // backwards since point down -z dir.normalise(); } // Point light else { // Set perspective projection texCam->setProjectionType(PT_PERSPECTIVE); // Use 120 degree FOV for point light to ensure coverage more area texCam->setFOVy(Degree(120)); // Calculate look at position // We want to look at a spot shadowOffset away from near plane // 0.5 is a little too close for angles Vector3 target = cam->getDerivedPosition() + (cam->getDerivedDirection() * shadowOffset); // Calculate position, which same as point light position pos = light->getDerivedPosition(); dir = (pos - target); // backwards since point down -z dir.normalise(); } // Finally set position texCam->setPosition(pos); // Calculate orientation based on direction calculated above /* // Next section (camera oriented shadow map) abandoned // Always point in the same direction, if we don't do this then // we get 'shadow swimming' as camera rotates // As it is, we get swimming on moving but this is less noticeable // calculate up vector, we want it aligned with cam direction Vector3 up = cam->getDerivedDirection(); // Check it's not coincident with dir if (up.dotProduct(dir) >= 1.0f) { // Use camera up up = cam->getUp(); } */ Vector3 up = Vector3::UNIT_Y; // Check it's not coincident with dir if (Math::Abs(up.dotProduct(dir)) >= 1.0f) { // Use camera up up = Vector3::UNIT_Z; } // cross twice to rederive, only direction is unaltered Vector3 left = dir.crossProduct(up); left.normalise(); up = dir.crossProduct(left); up.normalise(); // Derive quaternion from axes Quaternion q; q.FromAxes(left, up, dir); texCam->setOrientation(q); }