bool SetPropertyFromNode( const TreeNode& node, Property::Type type, Property::Value& value, const Replacement& replacer ) { bool done = false; switch(type) { case Property::BOOLEAN: { if( OptionalBoolean v = replacer.IsBoolean(node) ) { value = *v; done = true; } break; } case Property::FLOAT: { if( OptionalFloat v = replacer.IsFloat(node) ) { value = *v; done = true; } break; } case Property::INTEGER: { if( OptionalInteger v = replacer.IsInteger(node) ) { value = *v; done = true; } break; } case Property::VECTOR2: { if( OptionalVector2 v = replacer.IsVector2(node) ) { value = *v; done = true; } break; } case Property::VECTOR3: { if( OptionalVector3 v = replacer.IsVector3(node) ) { value = *v; done = true; } break; } case Property::VECTOR4: { if( OptionalVector4 v = replacer.IsVector4(node) ) { value = *v; done = true; } else if( OptionalString s = replacer.IsString(node) ) { if( (*s)[0] == '#' && 7 == (*s).size() ) { value = HexStringToVector4( &(*s)[1] ); done = true; } else if( Dali::ColorController::Get() ) { Vector4 color; done = Dali::ColorController::Get().RetrieveColor( *s, color ); value = color; } } else if( TreeNode::OBJECT == node.GetType() ) { // check for "r", "g" and "b" child color component nodes OptionalInteger r = replacer.IsInteger( IsChild(node, "r") ); OptionalInteger g = replacer.IsInteger( IsChild(node, "g") ); OptionalInteger b = replacer.IsInteger( IsChild(node, "b") ); if( r && g && b ) { float red( (*r) * (1.0f/255.0f) ); float green( (*g) * (1.0f/255.0f) ); float blue( (*b) * (1.0f/255.0f) ); // check for optional "a" (alpha) node, default to fully opaque if it is not found. float alpha( 1.0f ); OptionalInteger a = replacer.IsInteger( IsChild(node, "a") ); if( a ) { alpha = (*a) * (1.0f/255.0f); } value = Vector4( red, green, blue, alpha ); done = true; } } break; } case Property::MATRIX3: { if( OptionalMatrix3 v = replacer.IsMatrix3(node) ) { value = *v; done = true; } break; } case Property::MATRIX: { if( OptionalMatrix v = replacer.IsMatrix(node) ) { value = *v; done = true; } break; } case Property::RECTANGLE: { if( OptionalRect v = replacer.IsRect(node) ) { value = *v; done = true; } break; } case Property::ROTATION: { if(4 == node.Size()) { if( OptionalVector4 ov = replacer.IsVector4(node) ) { const Vector4& v = *ov; // angle, axis as per spec value = Quaternion(Radian(Degree(v[3])), Vector3(v[0],v[1],v[2])); done = true; } } else { // degrees Euler as per spec if( OptionalVector3 v = replacer.IsVector3(node) ) { value = Quaternion(Radian(Degree((*v).x)), Radian(Degree((*v).y)), Radian(Degree((*v).z))); done = true; } } break; } case Property::STRING: { if( OptionalString v = replacer.IsString(node) ) { value = *v; done = true; } break; } case Property::ARRAY: { if( replacer.IsArray( node, value ) ) { done = true; } else if(node.Size()) { value = Property::Value(Property::ARRAY); Property::Array* array = value.GetArray(); unsigned int i = 0; TreeNode::ConstIterator iter(node.CBegin()); if( array ) { for( ; i < node.Size(); ++i, ++iter) { Property::Value childValue; if( SetPropertyFromNode( (*iter).second, childValue, replacer ) ) { array->PushBack( childValue ); } } if( array->Count() == node.Size() ) { done = true; } else { done = false; } } } break; } case Property::MAP: { if( replacer.IsMap( node, value ) ) { done = true; } else if(node.Size()) { value = Property::Value(Property::MAP); Property::Map* map = value.GetMap(); unsigned int i = 0; TreeNode::ConstIterator iter(node.CBegin()); if( map ) { for( ; i < node.Size(); ++i, ++iter) { Property::Value childValue; if( SetPropertyFromNode( (*iter).second, childValue, replacer ) ) { map->Insert( (*iter).first, childValue ); } } if( map->Count() == node.Size() ) { done = true; } else { done = false; } } } break; } case Property::NONE: { break; } } // switch type return done; }

Degree Degree::operator - (const Radian& rhs) const { return Degree(mValue - rhs.valueDegrees()); }

Degree BasicFunction::degree() { auto deg = Degree(0,Degree::INF); return deg; }

void ScriptEditorSettings::internal_SetRotateHandleSnapAmount(float value) { SPtr<EditorSettings> settings = gEditorApplication().getEditorSettings(); settings->setRotationHandleSnap(Degree(value)); }

void PVNode::setKanoneMaxLeft() { //m_node->pitch(Degree( m_minV)); m_node->yaw(Degree(m_minH)); }

void Viewer::setupLights () { mSceneMgr->setAmbientLight(ColourValue(0.8, 0.8, 0.8)); if ( Ogre::Root::getSingletonPtr()->getRenderSystem()->getCapabilities()->hasCapability(RSC_HWRENDER_TO_TEXTURE) ) { mSceneMgr->setShadowTextureSettings(1024, 2); } else { mSceneMgr->setShadowTextureSettings(512, 2); } mSceneMgr->setShadowColour(ColourValue(0.5,0.5,0.5)); Light * mSunLight = mSceneMgr->createLight("SunLight"); mSunLight->setCastShadows(true); mSunLight->setType(Light::LT_SPOTLIGHT); mSunLight->setPosition(500, 500, 500); mSunLight->setSpotlightRange(Degree(30), Degree(50)); Vector3 dir; dir = - mSunLight->getPosition(); dir.normalise(); mSunLight->setDirection(dir); mSunLight->setDiffuseColour(0.35, 0.35, 0.38); mSunLight->setSpecularColour(0.9, 0.9, 1); timeSince = 0.0f; mBuildMode = BM_NONE; #if 0 mReflectCam = mSceneMgr->createCamera("ReflectCam"); mRTTTex = mRenderer->getRoot()->getRenderSystem()->createRenderTexture("RttTex", 512, 384, TEX_TYPE_2D, PF_R8G8B8); { mReflectCam = mSceneMgr->createCamera("ReflectCam"); mReflectCam->setPosition(mCamera->getPosition()); mReflectCam->setOrientation(mCamera->getOrientation()); mReflectCam->setNearClipDistance(mCamera->getNearClipDistance()); mReflectCam->setFarClipDistance(mCamera->getFarClipDistance()); Viewport * v = mRTTTex->addViewport(mReflectCam); mReflectCam->setAspectRatio(Real(v->getWidth()) / Real(v->getHeight())); v->setOverlaysEnabled(false); v->setClearEveryFrame(true); v->setBackgroundColour(ColourValue::Black); } MaterialPtr mat = MaterialManager::getSingleton().create("RttMat", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); TextureUnitState * t = mat->getTechnique(0)->getPass(0)->createTextureUnitState("RttTex"); t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); //t->setProjectiveTexturing(true, mReflectCam); mat->clone("RttMat.over"); //mGui->createWindow(Vector4(16, 16, 512, 384), "RttMat", BetaGUI::WFT_NONE, ""); #endif }

Vector3 FlexAirfoil::updateShadowVertices() { int i; Vector3 center; center=nodes[nfld].smoothpos; Vector3 vx=nodes[nfrd].smoothpos-nodes[nfld].smoothpos; Vector3 vyl=nodes[nflu].smoothpos-nodes[nfld].smoothpos; Vector3 vzl=nodes[nbld].smoothpos-nodes[nfld].smoothpos; Vector3 vyr=nodes[nfru].smoothpos-nodes[nfrd].smoothpos; Vector3 vzr=nodes[nbrd].smoothpos-nodes[nfrd].smoothpos; if (breakable) {broken=broken || (vx.crossProduct(vzl).squaredLength()>sref)||(vx.crossProduct(vzr).squaredLength()>sref);} else {broken=(vx.crossProduct(vzl).squaredLength()>sref)||(vx.crossProduct(vzr).squaredLength()>sref);} Vector3 facenormal=vx; facenormal.normalise(); //control surface if (hascontrol) { float radius=1.0-chordratio; airfoilpos[82]=0.5+radius*sin(deflection/57.0)/rratio; airfoilpos[79]=0.5+radius*sin(deflection/57.0)/lratio; airfoilpos[83]=chordratio+radius*cos(deflection/57.0); airfoilpos[80]=airfoilpos[83]; airfoilpos[89]=airfoilpos[83]; airfoilpos[88]=airfoilpos[82]; airfoilpos[86]=airfoilpos[80]; airfoilpos[85]=airfoilpos[79]; } if (!broken) { for (i=0; i<30; i++) { if (i%2) coshadowposvertices[i].vertex=airfoilpos[i*3]*vx+airfoilpos[i*3+1]*vyr+airfoilpos[i*3+2]*vzr; else coshadowposvertices[i].vertex=airfoilpos[i*3]*vx+airfoilpos[i*3+1]*vyl+airfoilpos[i*3+2]*vzl; if (i<22) coshadowposvertices[i+30].vertex=coshadowposvertices[i].vertex; } coshadowposvertices[30+22].vertex=coshadowposvertices[28].vertex; coshadowposvertices[30+23].vertex=coshadowposvertices[29].vertex; } else { for (i=0; i<30; i++) { if (i%2) coshadowposvertices[i].vertex=airfoilpos[i*3]*Vector3(0.01,0,0)+airfoilpos[i*3+1]*Vector3(0,0.01,0)+airfoilpos[i*3+2]*Vector3(0,0,0.01); else coshadowposvertices[i].vertex=airfoilpos[i*3]*Vector3(0.01,0,0)+airfoilpos[i*3+1]*Vector3(0,0.01,0)+airfoilpos[i*3+2]*Vector3(0,0,0.01); if (i<22) coshadowposvertices[i+30].vertex=coshadowposvertices[i].vertex; } coshadowposvertices[30+22].vertex=coshadowposvertices[28].vertex; coshadowposvertices[30+23].vertex=coshadowposvertices[29].vertex; } if (isstabilator) { //rotate stabilator Vector3 rcent, raxis; if (!stabilleft) { rcent=((nodes[nflu].smoothpos+nodes[nbld].smoothpos)/2.0+(nodes[nflu].smoothpos-nodes[nblu].smoothpos)/4.0)-center; raxis=(nodes[nflu].smoothpos-nodes[nfld].smoothpos).crossProduct(nodes[nflu].smoothpos-nodes[nblu].smoothpos); } else { rcent=((nodes[nfru].smoothpos+nodes[nbrd].smoothpos)/2.0+(nodes[nfru].smoothpos-nodes[nbru].smoothpos)/4.0)-center; raxis=(nodes[nfru].smoothpos-nodes[nfrd].smoothpos).crossProduct(nodes[nfru].smoothpos-nodes[nbru].smoothpos); } raxis.normalise(); Quaternion rot=Quaternion(Degree(deflection), raxis); for (i=0; i<54; i++) { covertices[i].vertex=rcent+rot*(covertices[i].vertex-rcent); } } //init normals for (i=0; i<(int)nVertices; i++) { coshadowposvertices[i+nVertices]=coshadowposvertices[i]; coshadownorvertices[i].normal=Vector3::ZERO; coshadownorvertices[i].texcoord=covertices[i].texcoord; } //normals //accumulate normals per triangle for (i=0; i<(int)bandibufCount/3; i++) { Vector3 v1, v2; v1=coshadowposvertices[bandfaces[i*3+1]].vertex-coshadowposvertices[bandfaces[i*3]].vertex; v2=coshadowposvertices[bandfaces[i*3+2]].vertex-coshadowposvertices[bandfaces[i*3]].vertex; v1=v1.crossProduct(v2); v1.normalise(); // v1/=3.0; coshadownorvertices[bandfaces[i*3]].normal+=v1; coshadownorvertices[bandfaces[i*3+1]].normal+=v1; coshadownorvertices[bandfaces[i*3+2]].normal+=v1; } for (i=0; i<(int)cupibufCount/3; i++) { Vector3 v1, v2; v1=coshadowposvertices[cupfaces[i*3+1]].vertex-coshadowposvertices[cupfaces[i*3]].vertex; v2=coshadowposvertices[cupfaces[i*3+2]].vertex-coshadowposvertices[cupfaces[i*3]].vertex; v1=v1.crossProduct(v2); v1.normalise(); // v1/=3.0; coshadownorvertices[cupfaces[i*3]].normal+=v1; coshadownorvertices[cupfaces[i*3+1]].normal+=v1; coshadownorvertices[cupfaces[i*3+2]].normal+=v1; } for (i=0; i<(int)cdnibufCount/3; i++) { Vector3 v1, v2; v1=coshadowposvertices[cdnfaces[i*3+1]].vertex-coshadowposvertices[cdnfaces[i*3]].vertex; v2=coshadowposvertices[cdnfaces[i*3+2]].vertex-coshadowposvertices[cdnfaces[i*3]].vertex; v1=v1.crossProduct(v2); v1.normalise(); // v1/=3.0; coshadownorvertices[cdnfaces[i*3]].normal+=v1; coshadownorvertices[cdnfaces[i*3+1]].normal+=v1; coshadownorvertices[cdnfaces[i*3+2]].normal+=v1; } //normalize for (i=0; i<30; i++) { coshadownorvertices[i].normal.normalise(); } //for the faces for (i=0; i<24; i++) if (i%2) coshadownorvertices[i+30].normal=facenormal; else coshadownorvertices[i+30].normal=-facenormal; return center; }

void ComponentPosition::calculateQuaternion() { quatRotation = Quaternion(Degree(rotation.x), Vector3::UNIT_X); quatRotation = Quaternion(Degree(rotation.y), Vector3::UNIT_Y) * quatRotation; quatRotation = Quaternion(Degree(rotation.z), Vector3::UNIT_Z) * quatRotation; }

//----------------------------------------------------------------------- void Frustum::updateFrustumImpl(void) const { // Common calcs Real left, right, bottom, top; #if OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0 if (mOrientationMode != OR_PORTRAIT) calcProjectionParameters(bottom, top, left, right); else #endif calcProjectionParameters(left, right, bottom, top); if (!mCustomProjMatrix) { // The code below will dealing with general projection // parameters, similar glFrustum and glOrtho. // Doesn't optimise manually except division operator, so the // code more self-explaining. Real inv_w = 1 / (right - left); Real inv_h = 1 / (top - bottom); Real inv_d = 1 / (mFarDist - mNearDist); // Recalc if frustum params changed if (mProjType == PT_PERSPECTIVE) { // Calc matrix elements Real A = 2 * mNearDist * inv_w; Real B = 2 * mNearDist * inv_h; Real C = (right + left) * inv_w; Real D = (top + bottom) * inv_h; Real q, qn; if (mFarDist == 0) { // Infinite far plane q = Frustum::INFINITE_FAR_PLANE_ADJUST - 1; qn = mNearDist * (Frustum::INFINITE_FAR_PLANE_ADJUST - 2); } else { q = - (mFarDist + mNearDist) * inv_d; qn = -2 * (mFarDist * mNearDist) * inv_d; } // NB: This creates 'uniform' perspective projection matrix, // which depth range [-1,1], right-handed rules // // [ A 0 C 0 ] // [ 0 B D 0 ] // [ 0 0 q qn ] // [ 0 0 -1 0 ] // // A = 2 * near / (right - left) // B = 2 * near / (top - bottom) // C = (right + left) / (right - left) // D = (top + bottom) / (top - bottom) // q = - (far + near) / (far - near) // qn = - 2 * (far * near) / (far - near) mProjMatrix = Matrix4::ZERO; mProjMatrix[0][0] = A; mProjMatrix[0][2] = C; mProjMatrix[1][1] = B; mProjMatrix[1][2] = D; mProjMatrix[2][2] = q; mProjMatrix[2][3] = qn; mProjMatrix[3][2] = -1; if (mObliqueDepthProjection) { // Translate the plane into view space // Don't use getViewMatrix here, incase overrided by // camera and return a cull frustum view matrix updateView(); Plane plane = mViewMatrix * mObliqueProjPlane; // Thanks to Eric Lenyel for posting this calculation // at www.terathon.com // Calculate the clip-space corner point opposite the // clipping plane // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and // transform it into camera space by multiplying it // by the inverse of the projection matrix /* generalised version Vector4 q = matrix.inverse() * Vector4(Math::Sign(plane.normal.x), Math::Sign(plane.normal.y), 1.0f, 1.0f); */ Vector4 qVec; qVec.x = (Math::Sign(plane.normal.x) + mProjMatrix[0][2]) / mProjMatrix[0][0]; qVec.y = (Math::Sign(plane.normal.y) + mProjMatrix[1][2]) / mProjMatrix[1][1]; qVec.z = -1; qVec.w = (1 + mProjMatrix[2][2]) / mProjMatrix[2][3]; // Calculate the scaled plane vector Vector4 clipPlane4d(plane.normal.x, plane.normal.y, plane.normal.z, plane.d); Vector4 c = clipPlane4d * (2 / (clipPlane4d.dotProduct(qVec))); // Replace the third row of the projection matrix mProjMatrix[2][0] = c.x; mProjMatrix[2][1] = c.y; mProjMatrix[2][2] = c.z + 1; mProjMatrix[2][3] = c.w; } } // perspective else if (mProjType == PT_ORTHOGRAPHIC) { Real A = 2 * inv_w; Real B = 2 * inv_h; Real C = - (right + left) * inv_w; Real D = - (top + bottom) * inv_h; Real q, qn; if (mFarDist == 0) { // Can not do infinite far plane here, avoid divided zero only q = - Frustum::INFINITE_FAR_PLANE_ADJUST / mNearDist; qn = - Frustum::INFINITE_FAR_PLANE_ADJUST - 1; } else { q = - 2 * inv_d; qn = - (mFarDist + mNearDist) * inv_d; } // NB: This creates 'uniform' orthographic projection matrix, // which depth range [-1,1], right-handed rules // // [ A 0 0 C ] // [ 0 B 0 D ] // [ 0 0 q qn ] // [ 0 0 0 1 ] // // A = 2 * / (right - left) // B = 2 * / (top - bottom) // C = - (right + left) / (right - left) // D = - (top + bottom) / (top - bottom) // q = - 2 / (far - near) // qn = - (far + near) / (far - near) mProjMatrix = Matrix4::ZERO; mProjMatrix[0][0] = A; mProjMatrix[0][3] = C; mProjMatrix[1][1] = B; mProjMatrix[1][3] = D; mProjMatrix[2][2] = q; mProjMatrix[2][3] = qn; mProjMatrix[3][3] = 1; } // ortho } // !mCustomProjMatrix #if OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0 // Deal with orientation mode mProjMatrix = mProjMatrix * Quaternion(Degree(mOrientationMode * 90.f), Vector3::UNIT_Z); #endif RenderSystem* renderSystem = Root::getSingleton().getRenderSystem(); // API specific renderSystem->_convertProjectionMatrix(mProjMatrix, mProjMatrixRS); // API specific for Gpu Programs renderSystem->_convertProjectionMatrix(mProjMatrix, mProjMatrixRSDepth, true); // Calculate bounding box (local) // Box is from 0, down -Z, max dimensions as determined from far plane // If infinite view frustum just pick a far value Real farDist = (mFarDist == 0) ? 100000 : mFarDist; // Near plane bounds Vector3 min(left, bottom, -farDist); Vector3 max(right, top, 0); if (mCustomProjMatrix) { // Some custom projection matrices can have unusual inverted settings // So make sure the AABB is the right way around to start with Vector3 tmp = min; min.makeFloor(max); max.makeCeil(tmp); } if (mProjType == PT_PERSPECTIVE) { // Merge with far plane bounds Real radio = farDist / mNearDist; min.makeFloor(Vector3(left * radio, bottom * radio, -farDist)); max.makeCeil(Vector3(right * radio, top * radio, 0)); } mBoundingBox.setExtents(min, max); mRecalcFrustum = false; // Signal to update frustum clipping planes mRecalcFrustumPlanes = true; }

//----------------------------------------------------------------------- void RevolutionAffector::_affectParticles(ParticleSystem* pSystem, Real timeElapsed) { // 因为timeElapsed有可能有0，加上判断，避免除0错 if (false == Ogre::Math::RealEqual(timeElapsed, 0.0f)) { ParticleIterator pi = pSystem->_getIterator(); Particle *p; Quaternion q( Radian(Degree(mRotationSpeed*timeElapsed).valueRadians()), mRotateAxis); Matrix3 mat(Matrix3::IDENTITY); q.ToRotationMatrix(mat); Ogre::Vector3 randomPoint; randomPoint.x = Math::RangeRandom(mCenterOffsetMin.x, mCenterOffsetMax.x); randomPoint.y = Math::RangeRandom(mCenterOffsetMin.y, mCenterOffsetMax.y); randomPoint.z = Math::RangeRandom(mCenterOffsetMin.z, mCenterOffsetMax.z); Vector3 particleSystemPos(Vector3::ZERO); bool localSpace = pSystem->getKeepParticlesInLocalSpace(); particleSystemPos = pSystem->getParentSceneNode()->_getDerivedPosition(); Ogre::Vector3 destPoint = particleSystemPos + randomPoint; Vector3 particlePos(Vector3::ZERO); Vector3 RadiusIncrementDir(Vector3::ZERO); bool needFmod = mRepeatTimes != 1.0f; while (!pi.end()) { p = pi.getNext(); particlePos = p->position; /** 如果是localSpace，那么p->position得到的是粒子的相对位置，所以要加上 粒子系统的位置particleSystemPos，得到绝对位置，再减去destPoint才能得到 正确的向量 particlePos + particleSystemPos - destPoint = particlePos + particleSystemPos - particleSystemPos - randomPoint = particlePos - randomPoint */ if (localSpace) { RadiusIncrementDir = particlePos - randomPoint; RadiusIncrementDir.normalise(); particlePos = mat *( particlePos - randomPoint ) + randomPoint - particlePos; } else { RadiusIncrementDir = particlePos - destPoint; RadiusIncrementDir.normalise(); particlePos = mat *( particlePos - destPoint ) + destPoint - particlePos; } p->direction = particlePos / timeElapsed; if (mUseRadiusIncrementScale) { const Real life_time = p->totalTimeToLive; Real particle_time = 1.0f - (p->timeToLive / life_time); // wrap the particle time Real repeatedParticleTime = needFmod ? fmod( particle_time * mRepeatTimes, 1.0f ) : particle_time; if (repeatedParticleTime <= mTimeAdj[0]) { p->direction += RadiusIncrementDir * mRadiusIncrementAdj[0]; } else if (repeatedParticleTime >= mTimeAdj[MAX_STAGES - 1]) { p->direction += RadiusIncrementDir * mRadiusIncrementAdj[MAX_STAGES - 1]; } else { for (int i=0;i<MAX_STAGES-1;i++) { if (repeatedParticleTime >= mTimeAdj[i] && repeatedParticleTime < mTimeAdj[i + 1]) { repeatedParticleTime -= mTimeAdj[i]; repeatedParticleTime /= (mTimeAdj[i+1]-mTimeAdj[i]); p->direction += RadiusIncrementDir * ( (mRadiusIncrementAdj[i+1] * repeatedParticleTime) + (mRadiusIncrementAdj[i] * (1.0f - repeatedParticleTime)) ); break; } } } } else { p->direction += RadiusIncrementDir*mRadiusIncrement; } // case RotationType::OUTER_NORMAL: //// p->direction.x += pos.x; // // p->direction.z += pos.z; // p->direction = pos; // break; // case RotationType::OUTER_FAST: //// p->direction.x += (p->direction.x + pos.x) /2; // // p->direction.z += (p->direction.z + pos.z) /2; // p->direction += (p->direction + pos) /2; // break; } } }

Camera::Camera() : mPosition(0, 1000, 1000) { mOrientation = Quaternion::IDENTITY; rotate(Vector3f::UNIT_X, Radian(Degree(-45))); }

bool Node::IsPolynomial(VariableGroup const&v) const { return Degree(v)>=0; }

bool Node::IsPolynomial(std::shared_ptr<Variable> const&v) const { return Degree(v)>=0; }

// 设置属性 bool CameraObject::setProperty(uint id , const Any &value) { if(id > ID_NullObject_Begin && id < ID_NullObject_End) return NullObject::setProperty(id , value); switch(id) { case ID_Camera: // 摄像机设置 { return true; } break; case ID_PolygonMode: // 几何渲染模式 { m_camera->setPolygonMode((PolygonMode)any_cast<long>(value)); return true; } break; case ID_LodBias: // LOD偏移 { m_camera->setLodBias(any_cast<Real>(value)); return true; } break; case ID_NearClipDistance: // 近裁面 { m_camera->setNearClipDistance(any_cast<Real>(value)); return true; } break; case ID_FarClipDistance: // 远裁面 { m_camera->setFarClipDistance(any_cast<Real>(value)); return true; } break; case ID_FOVy: // FOVy角度 { m_camera->setFOVy(Degree(any_cast<Real>(value))); return true; } break; case ID_AspectRatio: // 窗口比率 { m_camera->setAspectRatio(any_cast<Real>(value)); return true; } break; case ID_ProjectionType: // 投影方式 { m_camera->setProjectionType((ProjectionType)any_cast<long>(value)); return true; } break; case ID_OrthoWindow: // 正交投影窗口大小 { Vector2 window(any_cast<Vector2>(value)); m_camera->setOrthoWindow(window.x , window.y); return true; } break; default: return false; break; } }

void WeaponTower::Build( SceneManager *scene ) { char name[30]; m_sceneMgr = scene; // Nodules don't have weapons if (m_type == Type_NODULE ) { sprintf( name, "Nodule%d\n", m_towerIndex ); Entity *ent1 = scene->createEntity( name, "tower_nodule.mesh"); sprintf( name, "NoduleNode%d\n", m_towerIndex ); m_platform = scene->getRootSceneNode()->createChildSceneNode( name ); m_platform->attachObject( ent1 ); ent1->setQueryFlags( MASK_OBSTACLE | MASK_TOWER ); } else { sprintf( name, "Platform%d\n", m_towerIndex ); Entity *ent1 = scene->createEntity( name, "tower_platform.mesh"); sprintf( name, "PlatformNode%d\n", m_towerIndex ); m_platform = scene->getRootSceneNode()->createChildSceneNode( name ); m_platform->attachObject( ent1 ); ent1->setQueryFlags( MASK_OBSTACLE | MASK_TOWER ); sprintf( name, "Bracket%d\n", m_towerIndex ); Entity *ent2 = scene->createEntity( name, "tower_bracket.mesh"); sprintf( name, "BracketNode%d\n", m_towerIndex ); m_bracket = m_platform->createChildSceneNode( name, Vector3( 0.0, 5.0, 0.0 ) ); m_bracket->attachObject( ent2 ); sprintf( name, "Gun%d\n", m_towerIndex ); Entity *ent3 = scene->createEntity( name, "tower_gun.mesh"); sprintf( name, "GunNode%d\n", m_towerIndex ); m_gun = m_bracket->createChildSceneNode( name, Vector3( 0.0, 2.0, 0.0) ); m_gun->attachObject( ent3 ); if (true) //(m_towerHighIndex == 1) { if ( m_type==Type_FLAMETHROWER) { sprintf( name, "FlameThower%d\n", m_towerIndex ); m_psys = scene->createParticleSystem( name,"Tower/Flamethrower"); } else { sprintf( name, "TracerFire%d\n", m_towerIndex ); m_psys = scene->createParticleSystem( name,"Tower/TracerFire"); } // Point the fountain at an angle m_psysNode = m_gun->createChildSceneNode(); m_psysNode->translate(0,0,-10.0); m_psysNode->rotate(Vector3::UNIT_X, Degree(90)); m_psysNode->attachObject(m_psys); } } }

bool PlayState::frameStarted (const Ogre::FrameEvent& evt) { std::cout << "frameStarted PLAY" << std::endl; Ogre::Vector3 vt(0,0,0); Ogre::Real tSpeed = 20.0; _deltaT = evt.timeSinceLastFrame; _world->stepSimulation(_deltaT); // Actualizar simulacion Bullet _timeLastObject -= _deltaT; _camera->moveRelative(vt * _deltaT * tSpeed); if (_camera->getPosition().length() < 10.0) { _camera->moveRelative(-vt * _deltaT * tSpeed); } _camera->yaw(Degree(CAM_ROTATION_SPEED * _deltaT * _mouseRotation.x)); //, Node::TS_PARENT _camera->pitch(Degree(CAM_ROTATION_SPEED * _deltaT * _mouseRotation.y)); //, Node::TS_LOCAL _mouseRotation = Vector2::ZERO; //CONTROLAR LA DIRECCION DE LA CAMARA DEL PROYECTIL _projectileCamera->lookAt(_camera->getDerivedDirection()); if(_trackedBody){ _projectileCamera->setPosition(_trackedBody->getCenterOfMassPosition()); Ogre::Vector3 trackedBodyPosition = _trackedBody->getCenterOfMassPosition(); Ogre::Vector3 projectileLookAt(trackedBodyPosition.x - _camera->getPosition().x, trackedBodyPosition.y - _camera->getPosition().y, trackedBodyPosition.z - _camera->getPosition().z); //_projectileCamera->lookAt(_camera->getDerivedDirection()); _projectileCamera->lookAt(trackedBodyPosition + projectileLookAt); } std::cout << "CAMERAS" << std::endl; if(_shootKeyDown){ _keyDownTime = _keyDownTime + _deltaT; } if(_keyDownTime * THROW_FORCE > 100){ _forcePercent = 100; } else{ _forcePercent = _keyDownTime * THROW_FORCE; } //_points++; _sPF->updatePower(_forcePercent); _sPF->updatePoints(_points); //std::cout<<_sPF->getSheet()->getChild("PowerWindow")->getUpdateMode() <<std::endl; //_sPF->getSheet()->getChild("PowerWindow")->update(_deltaT); //CEGUI::System::getSingleton().injectTimePulse(_deltaT); //DetectCollisionPig(); std::cout << "points power" << std::endl; _physicsController->detectCollision(); //Este es el bueno. Hay que cambiarlo para que compruebe colisiones sobre todo std::cout << "pisis" << std::endl; _movementController->moveAll(); std::cout << "collision moveall" << std::endl; if(_finalGame){ pushState(FinalState::getSingletonPtr()); } lifeWolf(); std::cout << "wolf" << std::endl; if (_lanzaranimationPig){ for (int i = 0; i < 3; ++i){ std::ostringstream os; os << "pigA" <<i; Ogre::AnimationState* animStatePig = _sceneMgr->getEntity(os.str())-> getAnimationState("SaltoR"); animStatePig->setTimePosition(0.0); animStatePig->setEnabled(true); animStatePig->setLoop(true); _vector_anims_pig -> push_back(animStatePig); } _lanzaranimationPig = false; } for (int i = 0; i < 3; ++i){ Ogre::AnimationState* animStatePig = _vector_anims_pig->at(i); if (animStatePig != NULL){ if (animStatePig->hasEnded()){ animStatePig->setTimePosition(0.0); animStatePig->setEnabled(false); }else{ animStatePig->addTime(_deltaT); } } } std::cout << "animation" << std::endl; //RecorreVectorTAOAnadirMovimientoConstante(); //std::cout << "Hasta aqui todo bien 1" << std::endl; return true; }

void MapPresenter::initializeScene(const QRectF& rect, const Ogre::ColourValue& bkcolor, const Ogre::Vector3& eye_pos, const Ogre::Vector3& target_pos) { if (!view_->renderWindow()) return; OgreContext* pOgreContext = WorkspaceRoot::instance()->ogreContext(); scene_ = pOgreContext->createScene("MainRenderScene"); //----------------------------------scene rendering test------------------- // Setup animation default Ogre::Animation::setDefaultInterpolationMode(Ogre::Animation::IM_LINEAR); Ogre::Animation::setDefaultRotationInterpolationMode(Ogre::Animation::RIM_LINEAR); // Set ambient light scene_->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 1)); //create camera active_camera_ = scene_->createCamera("MainRenderScene.Camera"); //initialise camera man camera_man_= new SdkCameraMan(active_camera_); camera_man_->setStyle(OgreBites::CS_ORBIT); // Position it at 500 in Z direction active_camera_->setPosition(eye_pos); // Look back along -Z active_camera_->lookAt(target_pos); //camera->setPolygonMode(Ogre::PM_WIREFRAME); //set aspect ratio determine left and right active_camera_->setAspectRatio(rect.width() / rect.height()); //set fovy determine top and bottom float near_distance = 10; float far_distance = 10000; float fov = 2 * ::atan(rect.height() * 0.5F / near_distance); //camera->setFOVy(Ogre::Radian(fov)); //set near and far distance active_camera_->setNearClipDistance(near_distance); active_camera_->setFarClipDistance(far_distance); //add viewport Ogre::RenderWindow* pRenderWindow = view_->renderWindow(); Viewport* vp = pRenderWindow->addViewport(active_camera_); vp->setBackgroundColour(bkcolor); //------------------------------rendering test--------------------- // Create the robot scene Entity* robotEntity = scene_->createEntity("robot", "robot.mesh"); // Add entity to the scene node // Place and rotate to face the Z direction Vector3 robotLoc(1500, 1480, 0); Quaternion robotRot(Degree(-90), Vector3(0, 1, 0)); scene_->getRootSceneNode()->createChildSceneNode(robotLoc, robotRot)->attachObject(robotEntity); /*AnimationState* robotWalkState = robotEntity->getAnimationState("Walk"); robotWalkState->setEnabled(true);*/ // Create the ninja entity Entity *ent = scene_->createEntity("ninja", "ninja.mesh"); // Add entity to the scene node // Place and rotate to face the Z direction Vector3 ninjaLoc(1460, 1470, 0); Quaternion ninjaRot(Degree(180), Vector3(0, 1, 0)); SceneNode *ninjaNode = scene_->getRootSceneNode()->createChildSceneNode(ninjaLoc, ninjaRot); ninjaNode->scale(0.5, 0.5, 0.5); // He's twice as big as our robot... ninjaNode->attachObject(ent); /*AnimationState* ninjaWalkState = ent->getAnimationState("Walk"); ninjaWalkState->setEnabled(true);*/ // Give it a little ambience with lights Ogre::Light* l; l = scene_->createLight("BlueLight"); l->setPosition(1500,1500,100); l->setDiffuseColour(0.5, 0.5, 1.0); l = scene_->createLight("GreenLight"); l->setPosition(1460,1450,-100); l->setDiffuseColour(0.5, 1.0, 0.5); camera_man_->setTarget(ninjaNode); //---------------------------------------------rendering test------------------------- view_->sceneLoaded(); }

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

// Create the background nebulae void createBackground(SceneManager *sceneMgr) { // Get the background image String bgImage = ScriptSystem::getSingleton().getScriptString("backgroundImage"); MaterialPtr mat = MaterialManager::getSingleton().getByName("Background"); mat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(bgImage); // Get the nebula textures, and set their colors ColourValue col; col.r = ScriptSystem::getSingleton().getScriptNumber("nebula1_R"); col.g = ScriptSystem::getSingleton().getScriptNumber("nebula1_G"); col.b = ScriptSystem::getSingleton().getScriptNumber("nebula1_B"); mat = MaterialManager::getSingleton().getByName("BackgroundNebula1"); TextureUnitState *tu = mat->getTechnique(0)->getPass(0)->getTextureUnitState(1); tu->setColourOperationEx(LBX_MODULATE, LBS_CURRENT, LBS_MANUAL, col, col); col.r = ScriptSystem::getSingleton().getScriptNumber("nebula2_R"); col.g = ScriptSystem::getSingleton().getScriptNumber("nebula2_G"); col.b = ScriptSystem::getSingleton().getScriptNumber("nebula2_B"); mat = MaterialManager::getSingleton().getByName("BackgroundNebula2"); tu = mat->getTechnique(0)->getPass(0)->getTextureUnitState(1); tu->setColourOperationEx(LBX_MODULATE, LBS_CURRENT, LBS_MANUAL, col, col); col.r = ScriptSystem::getSingleton().getScriptNumber("nebula3_R"); col.g = ScriptSystem::getSingleton().getScriptNumber("nebula3_G"); col.b = ScriptSystem::getSingleton().getScriptNumber("nebula3_B"); mat = MaterialManager::getSingleton().getByName("BackgroundNebula3"); tu = mat->getTechnique(0)->getPass(0)->getTextureUnitState(1); tu->setColourOperationEx(LBX_MODULATE, LBS_CURRENT, LBS_MANUAL, col, col); // Create background rectangle covering the whole screen bgRect = new Rectangle2D(true); // Flipping and mirroring Real bgx = rand()%100 < 50 ? -1.0f : 1.0f; Real bgy = rand()%100 < 50 ? -1.0f : 1.0f; bgRect->setCorners(-bgx, bgy, bgx, -bgy); bgRect->setMaterial(MaterialManager::getSingleton().getByName("Background")); // Render the background before everything else bgRect->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY); AxisAlignedBox box; box.setInfinite(); bgRect->setBoundingBox(box); // Attach background to the scene SceneNode* node = sceneMgr->getRootSceneNode()->createChildSceneNode("Background"); node->attachObject(bgRect); // Background stars int starsCount = (int)ScriptSystem::getSingleton().getScriptNumber("starsCount"); ManualObject *stars[4]; for(int ii=0; ii<4; ii++) { stars[ii] = sceneMgr->createManualObject("BackgroundStars" + StringConverter::toString(ii+1)); stars[ii]->begin("BackgroundStars", RenderOperation::OT_POINT_LIST); for(int j=0; j<starsCount; j++) { Vector3 pos; pos.x = Math::RangeRandom(-playfieldWidth, playfieldWidth); pos.y = Math::RangeRandom(-playfieldHeight, playfieldHeight); pos.z = Math::RangeRandom(-140, -5); stars[ii]->position(pos); Real c = Math::RangeRandom(0.1f, 1.0f); stars[ii]->colour(c, c, c); stars[ii]->index(j); } stars[ii]->end(); stars[ii]->setRenderQueueGroup(RENDER_QUEUE_1); stars[ii]->setCastShadows(false); } // Create four groups of stars SceneNode *starsNode = sceneMgr->getRootSceneNode()->createChildSceneNode("BackgroundStars1"); starsNode->attachObject(stars[0]); starsNode->translate(-playfieldWidth/2, -playfieldHeight/2, 0); starsNode = sceneMgr->getRootSceneNode()->createChildSceneNode("BackgroundStars2"); starsNode->attachObject(stars[1]); starsNode->translate(+playfieldWidth/2, -playfieldHeight/2, 0); starsNode = sceneMgr->getRootSceneNode()->createChildSceneNode("BackgroundStars3"); starsNode->attachObject(stars[2]); starsNode->translate(+playfieldWidth/2, +playfieldHeight/2, 0); starsNode = sceneMgr->getRootSceneNode()->createChildSceneNode("BackgroundStars4"); starsNode->attachObject(stars[3]); starsNode->translate(-playfieldWidth/2, +playfieldHeight/2, 0); // Create the nebulae nebulaCount = (int)ScriptSystem::getSingleton().getScriptNumber("nebulaCount"); for(int f=0; f<nebulaCount; f++) { Entity *ent = sceneMgr->createEntity("BackgroundNebula" + StringConverter::toString(f), "Plane.mesh"); ent->setMaterialName("BackgroundNebula" + StringConverter::toString(f%3 + 1)); ent->setCastShadows(false); ent->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY); Vector3 pos; pos.x = Math::RangeRandom(-playfieldWidth, playfieldWidth); pos.y = Math::RangeRandom(-playfieldHeight, playfieldHeight); pos.z = Math::RangeRandom(-30, -5); SceneNode *node = sceneMgr->getRootSceneNode()->createChildSceneNode("NebulaNode" + StringConverter::toString(f), pos); node->attachObject(ent); Real s = Math::RangeRandom(25, 55); node->scale(s,s,s); node->roll(Degree(Math::RangeRandom(0,360))); node->yaw(Degree(Math::RangeRandom(-15,15))); } }

void Turboprop::updateForces(float dt, int doUpdate) { if (doUpdate) { //tropospheric model valid up to 11.000m (33.000ft) float altitude=nodes[noderef].AbsPosition.y; float sea_level_temperature=273.15+15.0; //in Kelvin float sea_level_pressure=101325; //in Pa float airtemperature=sea_level_temperature-altitude*0.0065; //in Kelvin float airpressure=sea_level_pressure*pow(1.0-0.0065*altitude/288.15, 5.24947); //in Pa airdensity=airpressure*0.0000120896;//1.225 at sea level #ifdef USE_OPENAL //sound update if(ssm) ssm->modulate(trucknum, mod_id, rpm); #endif //OPENAL } timer+=dt; //evaluate the rotation speed float velacc=0; for (int i=0; i<numblades; i++) velacc+=(nodes[nodep[i]].Velocity-nodes[noderef].Velocity).length(); rpm=(velacc/numblades) * RAD_PER_SEC_TO_RPM / radius; //check for broken prop Vector3 avg=Vector3::ZERO; for (int i=0; i<numblades; i++) avg+=nodes[nodep[i]].RelPosition; avg=avg/numblades; if ((avg-nodes[noderef].RelPosition).length()>0.4) { failed=true; } //evaluate engine power float enginepower=0; //in kilo-Watt float warmupfactor=1.0; if (warmup) { warmupfactor=(timer-warmupstart)/warmuptime; if (warmupfactor>=1.0) warmup=false; } float revpenalty=1.0; if (reverse) revpenalty=0.5; if (!failed && ignition) enginepower=(0.0575+throtle*revpenalty*0.9425)*fullpower*warmupfactor; //the magic formula float enginecouple=0.0; //in N.m if (rpm>10.0) enginecouple=9549.3*enginepower/rpm; else enginecouple=9549.3*enginepower/10.0; indicated_torque=enginecouple; if (torquenode!=-1) { Vector3 along=nodes[noderef].RelPosition-nodes[nodeback].RelPosition; Plane ppl=Plane(along, 0); Vector3 orth=ppl.projectVector(nodes[noderef].RelPosition)-ppl.projectVector(nodes[torquenode].RelPosition); Vector3 cdir=orth.crossProduct(along); cdir.normalise(); nodes[torquenode].Forces+=(enginecouple/torquedist)*cdir; } float tipforce=(enginecouple/radius)/numblades; //okay, now we know the contribution from the engine //pitch if (fixed_pitch>0) pitch=fixed_pitch; else { if (!reverse) { if (throtle<0.01) { //beta range if (pitch>0 && rpm<regspeed*1.4) pitch-=pitchspeed*dt; if (rpm>regspeed*1.4) pitch+=pitchspeed*dt; } else { float dpitch=rpm-regspeed; if (dpitch>pitchspeed) dpitch=pitchspeed; if (dpitch<-pitchspeed) dpitch=-pitchspeed; if (!(dpitch<0 && pitch<0) && !(dpitch>0 && pitch>45)) pitch+=dpitch*dt; } } else { if (rpm<regspeed*1.1) { if (pitch<-4.0) pitch+=pitchspeed*dt; else pitch-=pitchspeed*dt; } if (rpm>regspeed*1.11) { pitch-=pitchspeed*dt; } } } if (!failed) { axis=nodes[noderef].RelPosition-nodes[nodeback].RelPosition; axis.normalise(); } //estimate amount of energy float estrotenergy=0.5*numblades*nodes[nodep[0]].mass*radius*radius*(rpm/RAD_PER_SEC_TO_RPM)*(rpm/RAD_PER_SEC_TO_RPM); //for each blade float totthrust=0; float tottorque=0; for (int i=0; i<numblades; i++) { float dragfactor=0.01; if (!failed && ignition) { Vector3 totaltipforce=Vector3::ZERO; //span vector, left to right Vector3 spanv=(nodes[nodep[i]].RelPosition-nodes[noderef].RelPosition); spanv.normalise(); //chord vector, front to back Vector3 refchordv=-axis.crossProduct(spanv); //grab this for propulsive forces Vector3 tipf=-refchordv; totaltipforce+=(tipforce-rpm/10.0)*tipf; //add a bit of mechanical friction //for each blade segment (there are 6 elements) for (int j=0; j<5; j++) //outer to inner, the 6th blade element is ignored { //proportion float proport=((float)j+0.5)/6.0; //evaluate wind direction Vector3 wind=-(nodes[nodep[i]].Velocity*(1.0-proport)+nodes[noderef].Velocity*proport); float wspeed=wind.length(); Vector3 liftv=spanv.crossProduct(-wind); liftv.normalise(); //rotate according to pitch Vector3 chordv=Quaternion(Degree(pitch+twistmap[j]-7.0), spanv)*refchordv; //wing normal Vector3 normv=chordv.crossProduct(spanv); //calculate angle of attack Vector3 pwind=Plane(Vector3::ZERO, normv, chordv).projectVector(wind); Vector3 dumb; Degree daoa; chordv.getRotationTo(pwind).ToAngleAxis(daoa, dumb); float aoa=daoa.valueDegrees(); float raoa=daoa.valueRadians(); if (dumb.dotProduct(spanv)>0) {aoa=-aoa; raoa=-raoa;}; //get airfoil data float cz, cx, cm; airfoil->getparams(aoa, 1.0, 0.0, &cz, &cx, &cm); //surface computation float s=radius*bladewidth/6.0; //drag //wforce=(8.0*cx+cx*cx/(3.14159*radius/0.4))*0.5*airdensity*wspeed*s*wind; Vector3 eforce=(4.0*cx+cx*cx/(3.14159*radius/bladewidth))*0.5*airdensity*wspeed*s*wind; //lift float lift=cz*0.5*airdensity*wspeed*wspeed*s; eforce+=lift*liftv; totthrust+=eforce.dotProduct(axis); //apply forces nodes[noderef].Forces+=eforce*proport; totaltipforce+=eforce*(1.0-proport); // if (i==0) sprintf(debug, "rend %.4i%%, wind %.3i kts, aoa %.3i, power %.5ihp, thrust %.6ilbf, torque %.6ilbft, pitch %.3i, propwash %.3i kts", (int)(100.0*wforce.dotProduct(axis)*numblades*nodes[noderef].Velocity.length()/(rpm*0.10471976*2.0*3.14159*enginecouple)), (int)(wspeed*1.9438), (int)aoa, (int)(enginepower*1.34), (int)(wforce.dotProduct(axis)*numblades*0.2248), (int)(enginecouple/1.35582), (int)pitch, (int)(propwash*1.9438)); // if (i==0) sprintf(debug, "lfx=%f lfy=%f lfz=%f vx=%f vy=%f vz=%f cx=%f cz=%f lift=%f", liftv.x, liftv.y, liftv.z, wind.x, wind.y, wind.z, cx, cz, lift); } tottorque+=tipf.dotProduct(totaltipforce)*radius; //correct amount of energy float correctfactor=0; if (rpm>100) correctfactor=(rotenergy-estrotenergy)/(numblades*radius*dt*rpm/RAD_PER_SEC_TO_RPM); if (correctfactor>1000.0) correctfactor=1000.0; if (correctfactor<-1000.0) correctfactor=-1000.0; nodes[nodep[i]].Forces+=totaltipforce+correctfactor*tipf; } else { //failed case //add drag Vector3 wind=-nodes[nodep[i]].Velocity; // determine nodes speed and divide by engines speed (with some magic numbers for tuning) to keep it rotating longer when shutoff in flight and stop after a while when plane is stopped (on the ground) float wspeed= (wind.length()/15.0f) / (nodes[noderef].Velocity.length()/2.0f); nodes[nodep[i]].Forces+=airdensity*wspeed*wind; } } //compute the next energy level rotenergy+=(double)tottorque*dt*rpm/RAD_PER_SEC_TO_RPM; // sprintf(debug, "pitch %i thrust %i totenergy=%i apparentenergy=%i", (int)pitch, (int)totthrust, (int)rotenergy, (int)estrotenergy); //prop wash float speed=nodes[noderef].Velocity.length(); float thrsign=1.0; if (totthrust<0) {thrsign=-0.1; totthrust=-totthrust;}; if (!failed) propwash=thrsign*sqrt(totthrust/(0.5*airdensity*proparea)+speed*speed)-speed; else propwash=0; if (propwash<0) propwash=0; }

bool Sample_ParticleFX::frameRenderingQueued ( const FrameEvent& tEvent ) { m_pFountainPivot->yaw ( Degree ( tEvent.timeSinceLastFrame * 30 ) ); // spin the fountains around return SdkSample::frameRenderingQueued ( tEvent ); // don't forget the parent class updates! }

void CameraFlyer::update() { // Check if any movement or rotation keys are being held bool goingForward = gVirtualInput().isButtonHeld(mMoveForward); bool goingBack = gVirtualInput().isButtonHeld(mMoveBack); bool goingLeft = gVirtualInput().isButtonHeld(mMoveLeft); bool goingRight = gVirtualInput().isButtonHeld(mMoveRight); bool fastMove = gVirtualInput().isButtonHeld(mFastMove); bool camRotating = gVirtualInput().isButtonHeld(mRotateCam); // If switch to or from rotation mode, hide or show the cursor if (camRotating != mLastButtonState) { if (camRotating) Cursor::instance().hide(); else Cursor::instance().show(); mLastButtonState = camRotating; } // If camera is rotating, apply new pitch/yaw rotation values depending on the amount of rotation from the // vertical/horizontal axes. float frameDelta = gTime().getFrameDelta(); if (camRotating) { mYaw += Degree(gVirtualInput().getAxisValue(mHorizontalAxis) * ROTATION_SPEED * frameDelta); mPitch += Degree(gVirtualInput().getAxisValue(mVerticalAxis) * ROTATION_SPEED * frameDelta); mYaw = wrapAngle(mYaw); mPitch = wrapAngle(mPitch); Quaternion yRot; yRot.fromAxisAngle(Vector3::UNIT_Y, Radian(mYaw)); Quaternion xRot; xRot.fromAxisAngle(Vector3::UNIT_X, Radian(mPitch)); Quaternion camRot = yRot * xRot; camRot.normalize(); SO()->setRotation(camRot); } // If the movement button is pressed, determine direction to move in Vector3 direction = Vector3::ZERO; if (goingForward) direction += SO()->getForward(); if (goingBack) direction -= SO()->getForward(); if (goingRight) direction += SO()->getRight(); if (goingLeft) direction -= SO()->getRight(); // If a direction is chosen, normalize it to determine final direction. if (direction.squaredLength() != 0) { direction.normalize(); // Apply fast move multiplier if the fast move button is held. float multiplier = 1.0f; if (fastMove) multiplier = FAST_MODE_MULTIPLIER; // Calculate current speed of the camera mCurrentSpeed = Math::clamp(mCurrentSpeed + ACCELERATION * frameDelta, START_SPEED, TOP_SPEED); mCurrentSpeed *= multiplier; } else { mCurrentSpeed = 0.0f; } // If the current speed isn't too small, move the camera in the wanted direction float tooSmall = std::numeric_limits<float>::epsilon(); if (mCurrentSpeed > tooSmall) { Vector3 velocity = direction * mCurrentSpeed; SO()->move(velocity * frameDelta); } }

void View::OrientationChanged( Dali::Orientation orientation ) { // Nothing to do if orientation doesn't really change. if ( orientation.GetDegrees() == mOrientation || !mAutoRotateEnabled ) { return; } mOrientation = orientation.GetDegrees(); // has parent so we expect it to be on stage mRotateAnimation = Animation::New( ROTATION_ANIMATION_DURATION ); mRotateAnimation.RotateTo( Self(), Degree( -orientation.GetDegrees() ), Vector3::ZAXIS, AlphaFunctions::EaseOut ); // Resize the view if( mFullScreen ) { const Vector2& stageSize( Stage::GetCurrent().GetSize() ); const Vector3& currentSize( Self().GetCurrentSize() ); float minSize = std::min( stageSize.width, stageSize.height ); float maxSize = std::max( stageSize.width, stageSize.height ); Vector3 targetSize; View::Orientation viewOrientation = DegreeToViewOrientation( Degree( orientation.GetDegrees() ) ); switch( viewOrientation ) { case View::PORTRAIT: // Fallthrough case View::PORTRAIT_INVERSE: targetSize = Vector3( minSize, maxSize, currentSize.depth ); break; case View::LANDSCAPE: // Fallthrough case View::LANDSCAPE_INVERSE: targetSize = Vector3( maxSize, minSize, currentSize.depth ); break; default: DALI_ASSERT_ALWAYS( false ); } // if we linearly resize from portrait to landscape halfway through the animation // we get size which is square between the both. This would cause a square image to grow // if it is fitted to be 100% of view size. Therefore we do a nonlinear size animation // where we shrink faster // which one grows if( targetSize.width > currentSize.width ) { // width grows, shrink height faster Vector3 shrink( currentSize );shrink.height = targetSize.height; mRotateAnimation.Resize( Self(), shrink, AlphaFunctions::EaseOut, 0.0f, ROTATION_ANIMATION_DURATION * 0.5f ); mRotateAnimation.Resize( Self(), targetSize, AlphaFunctions::EaseIn, 0.0f, ROTATION_ANIMATION_DURATION ); } else { // height grows, shrink width faster Vector3 shrink( currentSize );shrink.width = targetSize.width; mRotateAnimation.Resize( Self(), shrink, AlphaFunctions::EaseOut, 0.0f, ROTATION_ANIMATION_DURATION * 0.5f ); mRotateAnimation.Resize( Self(), targetSize, AlphaFunctions::EaseIn, 0.0f, ROTATION_ANIMATION_DURATION ); } } mRotateAnimation.SetDestroyAction( Animation::Bake ); Toolkit::View handle( GetOwner() ); mOrientationAnimationStartedSignalV2.Emit( handle, mRotateAnimation, orientation ); mRotateAnimation.Play(); }

bool OgreNewtonFrameListener::frameStarted(const FrameEvent &evt) { mKeyboard->capture(); mMouse->capture(); // ---------------------------------------- // CAMERA CONTROLS // ---------------------------------------- if ((mKeyboard->isKeyDown(OIS::KC_LSHIFT)) || (mKeyboard->isKeyDown(OIS::KC_RSHIFT))) { Vector3 trans, strafe, vec; Quaternion quat; quat = mCamera->getOrientation(); vec = Vector3(0.0,0.0,-0.5); trans = quat * vec; vec = Vector3(0.5,0.0,0.0); strafe = quat * vec; mCamera->pitch( Degree(mMouse->getMouseState().Y.rel * -0.5) ); mCamera->setFixedYawAxis(true); mCamera->yaw( Degree(mMouse->getMouseState().X.rel * -0.5) ); if (mKeyboard->isKeyDown(OIS::KC_UP)) mCamera->moveRelative(trans); if (mKeyboard->isKeyDown(OIS::KC_DOWN)) mCamera->moveRelative(trans * -1.0); if (mKeyboard->isKeyDown(OIS::KC_LEFT)) mCamera->moveRelative(strafe * -1.0); if (mKeyboard->isKeyDown(OIS::KC_RIGHT)) mCamera->moveRelative(strafe); } // ---------------------------------------- // DRAGGING! // ---------------------------------------- if (!dragging) { //user pressing the left mouse button? if (mMouse->getMouseState().buttonDown(OIS::MB_Left)) { // perform a raycast! // start at the camera, and go for 100 units in the Z direction. Ogre::Vector3 start, end; CEGUI::Point mouse = CEGUI::MouseCursor::getSingleton().getPosition(); CEGUI::Renderer* rend = CEGUI::System::getSingleton().getRenderer(); Ogre::Real mx,my; mx = mouse.d_x / rend->getWidth(); my = mouse.d_y / rend->getHeight(); Ogre::Ray camray = mCamera->getCameraToViewportRay(mx,my); start = camray.getOrigin(); end = camray.getPoint( 100.0 ); OgreNewt::BasicRaycast* ray = new OgreNewt::BasicRaycast( m_World, start, end, true ); OgreNewt::BasicRaycast::BasicRaycastInfo info = ray->getFirstHit(); if (info.mBody) { // a body was found. first let's find the point we clicked, in local coordinates of the body. // while dragging, make sure the body can't fall asleep. info.mBody->unFreeze(); //info.mBody->setAutoFreeze(0); Ogre::Vector3 bodpos; Ogre::Quaternion bodorient; info.mBody->getPositionOrientation( bodpos, bodorient ); // info.mDistance is in the range [0,1]. Ogre::Vector3 globalpt = camray.getPoint( 100.0 * info.mDistance ); Ogre::Vector3 localpt = bodorient.Inverse() * (globalpt - bodpos); // now we need to save this point to apply the spring force, I'm using the userData of the bodies in this example. // (where is it used? probably not needed here...) #ifndef OGRENEWT_NO_OGRE_ANY info.mBody->setUserData( Ogre::Any(this) ); #else info.mBody->setUserData( this ); #endif // now change the force callback from the standard one to the one that applies the spring (drag) force. // this is an example of binding a callback to a member of a specific class. in previous versions of OgreNewt you were // required to use a static member function fr all callbacks... but now through the fantastic FastDelegate library, you can // now use callbacks that are members of specific classes. to do this, use the syntax shown below. the "this" is a pointer // to the specific class, and the 2nd parameter is a pointer to the function you want to use. you can do this for all // body callbacks (ForceAndTorque, Transform, addBuoyancyPlane). info.mBody->setCustomForceAndTorqueCallback<OgreNewtonFrameListener>( &OgreNewtonFrameListener::dragCallback, this ); // save the relevant drag information. dragBody = info.mBody; dragDist = (100.0 * info.mDistance); dragPoint = localpt; dragging = true; } delete ray; } if (mDragLine) remove3DLine(); } else { // currently dragging! if (!mMouse->getMouseState().buttonDown(OIS::MB_Left)) { // no longer holding mouse button, so stop dragging! // remove the special callback, and put it back to standard gravity. dragBody->setStandardForceCallback(); //dragBody->setAutoFreeze(1); dragBody = NULL; dragPoint = Ogre::Vector3::ZERO; dragDist = 0.0; dragging = false; } } OgreNewt::Debugger& debug(m_World->getDebugger()); if (mKeyboard->isKeyDown(OIS::KC_F3)) { debug.showDebugInformation(); debug.startRaycastRecording(); debug.clearRaycastsRecorded(); } else { debug.hideDebugInformation(); debug.clearRaycastsRecorded(); debug.stopRaycastRecording(); } if (mKeyboard->isKeyDown(OIS::KC_T)) m_World->setThreadCount( m_World->getThreadCount() % 2 + 1); if (mKeyboard->isKeyDown(OIS::KC_ESCAPE)) return false; return true; }

void main(){ unsigned Mersenne[500], S[500], T[500], quot[500], res[500]; int a[500]; int p, j, k, t, d, r; p = 5; while(p <525){ Initialize(Mersenne); Mersenne[0] = 1; LongLeftShift(Mersenne, p); Initialize(a); a[0] = 1; Sub(Mersenne, a); // Mersenne = 2 の p 乗 - 1 printf("p = %d \n", p); // Display(Mersenne); Initialize(S); S[0] = 4; for(j = 1; j<p-1; j++){ Copy(S, a); LongMul(S, a); // S -> S^2 Initialize(a); a[0] = 2; Sub(S, a); // S -> S^2 - 2 LongDiv(S, Mersenne, quot, res); if(DivCheck(S, Mersenne, quot, res)==0) { printf("DivCheck Failed\n"); return; } Copy(S,T); LongRightShift(T, p); t = p/16; r = p - 16*t; d = Degree(S); for(k = d; k>t; k--){ S[k] = 0; } S[t] = (S[t]<<(32-r))>>(32-r); Add(S, T); k = Compare(S, Mersenne); if(k==1 || k==0){ Sub(S, Mersenne); } k = Compare(res, S); if(k!=0) { printf("Something is wrong\n"); return; } } if(ZeroCheck(S)==0) printf("mersenne, p = %d\n", p); p = p+2; p = NextPrime(p); } }

SPtr<TAnimationCurve<Quaternion>> AnimationUtility::eulerToQuaternionCurve(const SPtr<TAnimationCurve<Vector3>>& eulerCurve) { // TODO: We calculate tangents by sampling which can introduce error in the tangents. The error can be exacerbated // by the fact we constantly switch between the two representations, possibly losing precision every time. Instead // there must be an analytical way to calculate tangents when converting a curve, or a better way of dealing with // tangents. // Consider: // - Sampling multiple points to calculate tangents to improve precision // - Store the original quaternion curve with the euler curve // - This way conversion from euler to quaternion can be done while individual keyframes are being modified // ensuring the conversion results are immediately visible, and that no accumulation error happens are curves // are converted between two formats back and forth. // - Don't store rotation tangents directly, instead store tangent parameters (TCB) which can be shared between // both curves, and used for tangent calculation. // // If we decide to keep tangents in the current form, then we should also enforce that all euler curve tangents are // the same. const float FIT_TIME = 0.001f; auto eulerToQuaternion = [&](INT32 keyIdx, Vector3& angles, const Quaternion& lastQuat) { Quaternion quat( Degree(angles.x), Degree(angles.y), Degree(angles.z)); // Flip quaternion in case rotation is over 180 degrees (use shortest path) if (keyIdx > 0) { float dot = quat.dot(lastQuat); if (dot < 0.0f) quat = -quat; } return quat; }; INT32 numKeys = (INT32)eulerCurve->getNumKeyFrames(); Vector<TKeyframe<Quaternion>> quatKeyframes(numKeys); // Calculate key values Quaternion lastQuat(BsZero); for (INT32 i = 0; i < numKeys; i++) { float time = eulerCurve->getKeyFrame(i).time; Vector3 angles = eulerCurve->getKeyFrame(i).value; Quaternion quat = eulerToQuaternion(i, angles, lastQuat); quatKeyframes[i].time = time; quatKeyframes[i].value = quat; quatKeyframes[i].inTangent = Quaternion::ZERO; quatKeyframes[i].outTangent = Quaternion::ZERO; lastQuat = quat; } // Calculate extra values between keys so we can approximate tangents. If we're sampling very close to the key // the values should pretty much exactly match the tangent (assuming the curves are cubic hermite) for (INT32 i = 0; i < numKeys - 1; i++) { TKeyframe<Quaternion>& currentKey = quatKeyframes[i]; TKeyframe<Quaternion>& nextKey = quatKeyframes[i + 1]; const TKeyframe<Vector3>& currentEulerKey = eulerCurve->getKeyFrame(i); const TKeyframe<Vector3>& nextEulerKey = eulerCurve->getKeyFrame(i + 1); float dt = nextKey.time - currentKey.time; float startFitTime = currentKey.time + dt * FIT_TIME; float endFitTime = currentKey.time + dt * (1.0f - FIT_TIME); Vector3 anglesStart = eulerCurve->evaluate(startFitTime, false); Vector3 anglesEnd = eulerCurve->evaluate(endFitTime, false); Quaternion startFitValue = eulerToQuaternion(i, anglesStart, currentKey.value); Quaternion endFitValue = eulerToQuaternion(i, anglesEnd, startFitValue); float invFitTime = 1.0f / (dt * FIT_TIME); currentKey.outTangent = (startFitValue - currentKey.value) * invFitTime; nextKey.inTangent = (nextKey.value - endFitValue) * invFitTime; setStepTangent(currentEulerKey, nextEulerKey, currentKey, nextKey); } return bs_shared_ptr_new<TAnimationCurve<Quaternion>>(quatKeyframes); }

void ImpostorTexture::renderTextures(bool force) { #ifdef IMPOSTOR_FILE_SAVE TexturePtr renderTexture; #else TexturePtr renderTexture(texture); //if we're not using a file image we need to set up a resource loader, so that the texture is regenerated if it's ever unloaded (such as switching between fullscreen and the desktop in win32) loader = std::auto_ptr<ImpostorTextureResourceLoader>(new ImpostorTextureResourceLoader(*this)); #endif RenderTexture *renderTarget; Camera *renderCamera; Viewport *renderViewport; SceneNode *camNode; //Set up RTT texture uint32 textureSize = ImpostorPage::impostorResolution; if (renderTexture.isNull()) { renderTexture = TextureManager::getSingleton().createManual(getUniqueID("ImpostorTexture"), "Impostors", TEX_TYPE_2D, textureSize * IMPOSTOR_YAW_ANGLES, textureSize * IMPOSTOR_PITCH_ANGLES, 0, PF_A8R8G8B8, TU_RENDERTARGET, loader.get()); } renderTexture->setNumMipmaps(MIP_UNLIMITED); //Set up render target renderTarget = renderTexture->getBuffer()->getRenderTarget(); renderTarget->setAutoUpdated(false); //Set up camera camNode = sceneMgr->getSceneNode("ImpostorPage::cameraNode"); renderCamera = sceneMgr->createCamera(getUniqueID("ImpostorCam")); camNode->attachObject(renderCamera); renderCamera->setLodBias(1000.0f); renderViewport = renderTarget->addViewport(renderCamera); renderViewport->setOverlaysEnabled(false); renderViewport->setClearEveryFrame(true); renderViewport->setShadowsEnabled(false); renderViewport->setBackgroundColour(ImpostorPage::impostorBackgroundColor); //Set up scene node SceneNode* node = sceneMgr->getSceneNode("ImpostorPage::renderNode"); Ogre::SceneNode* oldSceneNode = entity->getParentSceneNode(); if (oldSceneNode) { oldSceneNode->detachObject(entity); } node->attachObject(entity); node->setPosition(-entityCenter); //Set up camera FOV const Real objDist = entityRadius * 100; const Real nearDist = objDist - (entityRadius + 1); const Real farDist = objDist + (entityRadius + 1); renderCamera->setAspectRatio(1.0f); renderCamera->setFOVy(Math::ATan(entityDiameter / objDist)); renderCamera->setNearClipDistance(nearDist); renderCamera->setFarClipDistance(farDist); //Disable mipmapping (without this, masked textures look bad) MaterialManager *mm = MaterialManager::getSingletonPtr(); FilterOptions oldMinFilter = mm->getDefaultTextureFiltering(FT_MIN); FilterOptions oldMagFilter = mm->getDefaultTextureFiltering(FT_MAG); FilterOptions oldMipFilter = mm->getDefaultTextureFiltering(FT_MIP); mm->setDefaultTextureFiltering(FO_POINT, FO_LINEAR, FO_NONE); //Disable fog FogMode oldFogMode = sceneMgr->getFogMode(); ColourValue oldFogColor = sceneMgr->getFogColour(); Real oldFogDensity = sceneMgr->getFogDensity(); Real oldFogStart = sceneMgr->getFogStart(); Real oldFogEnd = sceneMgr->getFogEnd(); sceneMgr->setFog(Ogre::FOG_EXP2, Ogre::ColourValue(0,0,0,0), 0.0f, 0.0f, 0.0f); //Ember change //We need to disable all lightning and render it full bright Ogre::ColourValue oldAmbientColour = sceneMgr->getAmbientLight(); sceneMgr->setAmbientLight(ColourValue::White); std::vector<Ogre::MovableObject*> lightStore; Ogre::SceneManager::MovableObjectIterator lightIterator = sceneMgr->getMovableObjectIterator(Ogre::LightFactory::FACTORY_TYPE_NAME); while (lightIterator.hasMoreElements()) { Ogre::MovableObject* light = lightIterator.getNext(); if (light) { if (light->getVisible()) { lightStore.push_back(light); light->setVisible(false); } } } // Get current status of the queue mode Ogre::SceneManager::SpecialCaseRenderQueueMode OldSpecialCaseRenderQueueMode = sceneMgr->getSpecialCaseRenderQueueMode(); //Only render the entity sceneMgr->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_INCLUDE); sceneMgr->addSpecialCaseRenderQueue(group->geom->getRenderQueue() + 1); uint8 oldRenderQueueGroup = entity->getRenderQueueGroup(); entity->setRenderQueueGroup(group->geom->getRenderQueue() + 1); bool oldVisible = entity->getVisible(); entity->setVisible(true); float oldMaxDistance = entity->getRenderingDistance(); entity->setRenderingDistance(0); bool needsRegen = true; #ifdef IMPOSTOR_FILE_SAVE //Calculate the filename hash used to uniquely identity this render String strKey = entityKey; char key[32] = {0}; uint32 i = 0; for (String::const_iterator it = entityKey.begin(); it != entityKey.end(); ++it) { key[i] ^= *it; i = (i+1) % sizeof(key); } for (i = 0; i < sizeof(key); ++i) key[i] = (key[i] % 26) + 'A'; String tempdir = this->group->geom->getTempdir(); ResourceGroupManager::getSingleton().addResourceLocation(tempdir, "FileSystem", "BinFolder"); String fileNamePNG = "Impostor." + String(key, sizeof(key)) + '.' + StringConverter::toString(textureSize) + ".png"; String fileNameDDS = "Impostor." + String(key, sizeof(key)) + '.' + StringConverter::toString(textureSize) + ".dds"; //Attempt to load the pre-render file if allowed needsRegen = force; if (!needsRegen){ try{ texture = TextureManager::getSingleton().load(fileNameDDS, "BinFolder", TEX_TYPE_2D, MIP_UNLIMITED); } catch (...){ try{ texture = TextureManager::getSingleton().load(fileNamePNG, "BinFolder", TEX_TYPE_2D, MIP_UNLIMITED); } catch (...){ needsRegen = true; } } } #endif if (needsRegen){ //If this has not been pre-rendered, do so now const float xDivFactor = 1.0f / IMPOSTOR_YAW_ANGLES; const float yDivFactor = 1.0f / IMPOSTOR_PITCH_ANGLES; for (int o = 0; o < IMPOSTOR_PITCH_ANGLES; ++o){ //4 pitch angle renders #ifdef IMPOSTOR_RENDER_ABOVE_ONLY Radian pitch = Degree((90.0f * o) * yDivFactor); //0, 22.5, 45, 67.5 #else Radian pitch = Degree((180.0f * o) * yDivFactor - 90.0f); #endif for (int i = 0; i < IMPOSTOR_YAW_ANGLES; ++i){ //8 yaw angle renders Radian yaw = Degree((360.0f * i) * xDivFactor); //0, 45, 90, 135, 180, 225, 270, 315 //Position camera camNode->setPosition(0, 0, 0); camNode->setOrientation(Quaternion(yaw, Vector3::UNIT_Y) * Quaternion(-pitch, Vector3::UNIT_X)); camNode->translate(Vector3(0, 0, objDist), Node::TS_LOCAL); //Render the impostor renderViewport->setDimensions((float)(i) * xDivFactor, (float)(o) * yDivFactor, xDivFactor, yDivFactor); renderTarget->update(); } } #ifdef IMPOSTOR_FILE_SAVE //Save RTT to file with respecting the temp dir renderTarget->writeContentsToFile(tempdir + fileNamePNG); //Load the render into the appropriate texture view texture = TextureManager::getSingleton().load(fileNamePNG, "BinFolder", TEX_TYPE_2D, MIP_UNLIMITED); #else texture = renderTexture; #endif } entity->setVisible(oldVisible); entity->setRenderQueueGroup(oldRenderQueueGroup); entity->setRenderingDistance(oldMaxDistance); sceneMgr->removeSpecialCaseRenderQueue(group->geom->getRenderQueue() + 1); // Restore original state sceneMgr->setSpecialCaseRenderQueueMode(OldSpecialCaseRenderQueueMode); //Re-enable mipmapping mm->setDefaultTextureFiltering(oldMinFilter, oldMagFilter, oldMipFilter); //Re-enable fog sceneMgr->setFog(oldFogMode, oldFogColor, oldFogDensity, oldFogStart, oldFogEnd); //Re-enable both scene lightning and disabled individual lights sceneMgr->setAmbientLight(oldAmbientColour); for (std::vector<Ogre::MovableObject*>::const_iterator I = lightStore.begin(); I != lightStore.end(); ++I) { (*I)->setVisible(true); } //Delete camera renderTarget->removeViewport(0); renderCamera->getSceneManager()->destroyCamera(renderCamera); //Delete scene node node->detachAllObjects(); if (oldSceneNode) { oldSceneNode->attachObject(entity); } #ifdef IMPOSTOR_FILE_SAVE //Delete RTT texture assert(!renderTexture.isNull()); String texName2(renderTexture->getName()); renderTexture.setNull(); if (TextureManager::getSingletonPtr()) TextureManager::getSingleton().remove(texName2); #endif }

void MoveDemoApplication::createScene(void) { // Set the default lighting. mSceneMgr->setAmbientLight( ColourValue( 1.0f, 1.0f, 1.0f ) ); createAxes(); createGrid(); createPath(); // Create the entity mEntity = mSceneMgr->createEntity( "Robot", "robot.mesh" ); mNode = mSceneMgr->getRootSceneNode( )->createChildSceneNode( "RobotNode", Vector3( 0.0f, 0.0f, 25.0f ) ); mNode->attachObject( mEntity ); mNode->showBoundingBox(true); // Create the walking list mWalkList.push_back( Vector3( 550.0f, 0.0f, 50.0f ) ); mWalkList.push_back( Vector3(-100.0f, 0.0f, -200.0f ) ); mWalkList.push_back( Vector3( 0.0f, 0.0f, 25.0f ) ); // Create objects so we can see movement Entity *ent; SceneNode *node; ent = mSceneMgr->createEntity( "ninja", "ninja.mesh" ); node = mSceneMgr->getRootSceneNode( )->createChildSceneNode( "ninja", Vector3( 50.0f, 0.0f, -50.0f ) ); node->attachObject( ent ); node->yaw( Degree(-180) ); ent = mSceneMgr->createEntity( "Knot1", "knot.mesh" ); node = mSceneMgr->getRootSceneNode( )->createChildSceneNode( "Knot1Node", Vector3( 0.0f, -10.0f, 25.0f ) ); node->attachObject( ent ); node->setScale( 0.1f, 0.1f, 0.1f ); ent = mSceneMgr->createEntity( "Knot2", "knot.mesh" ); node = mSceneMgr->getRootSceneNode( )->createChildSceneNode( "Knot2Node", Vector3( 550.0f, -10.0f, 50.0f ) ); node->attachObject( ent ); node->setScale( 0.1f, 0.1f, 0.1f ); ent = mSceneMgr->createEntity( "Knot3", "knot.mesh" ); node = mSceneMgr->getRootSceneNode( )->createChildSceneNode( "Knot3Node", Vector3(-100.0f, -10.0f,-200.0f ) ); node->attachObject( ent ); node->setScale( 0.1f, 0.1f, 0.1f ); // Set the camera to look at our handywork mCamera->setPosition( 90.0f, 280.0f, 535.0f ); mCamera->pitch( Degree(-30.0f) ); mCamera->yaw( Degree(-15.0f) ); //! TEST ONLY //AnimationState *mAnimationState; // The current animation state of the object //mAnimationState = mEntity->getAnimationState("Idle"); //mAnimationState->setLoop(true); //mAnimationState->setEnabled(true); }

#include "Engine/savable.hpp" /*---------------------------------------------- Definitions ----------------------------------------------*/ const Ogre::String XML_FILE_DIR = "Content/Save/0000/"; const Ogre::String XML_TEMPLATE_DIR = "Content/Templates/"; const char* XML_FILE_VALUE_NAME = "value"; const char* XML_FILE_SAVE_NAME = "savefile"; const char* XML_FILE_TEMPLATE_NAME = "template"; const char* XML_FILE_HEADER = "xml version=\"1.0\" encoding=\"UTF-8\""; const Quaternion LEFT = Quaternion(Radian(Degree(-90).valueRadians()), Vector3(0,1,0)); const Quaternion RIGHT = Quaternion(Radian(Degree(+90).valueRadians()), Vector3(0,1,0)); const Quaternion TOP = Quaternion(Radian(Degree(-90).valueRadians()), Vector3(1,0,0)); const Quaternion BOTTOM = Quaternion(Radian(Degree(+90).valueRadians()), Vector3(1,0,0)); const Quaternion FORWARD = Quaternion(Radian(Degree(180).valueRadians()), Vector3(0,1,0)); const Quaternion BACK = Quaternion(Radian(Degree( 0).valueRadians()), Vector3(0,1,0)); /*---------------------------------------------- Public methods (save) ----------------------------------------------*/ void Savable::saveToFile() { if (!isSavable()) {

void ShadowView::OnInitialize() { // root actor to parent all user added actors. Used as source actor for shadow render task. mChildrenRoot.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION ); mChildrenRoot.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS ); Vector2 stageSize = Stage::GetCurrent().GetSize(); mCameraActor = CameraActor::New(stageSize); mCameraActor.SetParentOrigin( ParentOrigin::CENTER ); // Target is constrained to point at the shadow plane origin mCameraActor.SetNearClippingPlane( 1.0f ); mCameraActor.SetType( Dali::Camera::FREE_LOOK ); // Camera orientation constrained to point at shadow plane world position mCameraActor.SetOrientation(Radian(Degree(180)), Vector3::YAXIS); mCameraActor.SetPosition(DEFAULT_LIGHT_POSITION); Property::Map customShader; customShader[ "vertex-shader" ] = RENDER_SHADOW_VERTEX_SOURCE; customShader[ "fragment-shader" ] = RENDER_SHADOW_FRAGMENT_SOURCE; customShader[ "subdivide-grid-x" ] = 20; customShader[ "subdivide-grid-y" ] = 20; customShader[ "hints" ] = "output-is-transparent"; mShadowRenderShader[ "shader" ] = customShader; // Create render targets needed for rendering from light's point of view mSceneFromLightRenderTarget = FrameBufferImage::New( stageSize.width, stageSize.height, Pixel::RGBA8888 ); mOutputImage = FrameBufferImage::New( stageSize.width * 0.5f, stageSize.height * 0.5f, Pixel::RGBA8888 ); ////////////////////////////////////////////////////// // Connect to actor tree Self().Add( mChildrenRoot ); Stage::GetCurrent().Add( mCameraActor ); mBlurFilter.SetRefreshOnDemand(false); mBlurFilter.SetInputImage(mSceneFromLightRenderTarget); mBlurFilter.SetOutputImage(mOutputImage); mBlurFilter.SetSize(stageSize * 0.5f); mBlurFilter.SetPixelFormat(Pixel::RGBA8888); mBlurRootActor = Actor::New(); mBlurRootActor.SetName( "BLUR_ROOT_ACTOR" ); // Turn off inheritance to ensure filter renders properly mBlurRootActor.SetPositionInheritanceMode(USE_PARENT_POSITION); mBlurRootActor.SetInheritOrientation(false); mBlurRootActor.SetInheritScale(false); mBlurRootActor.SetColorMode(USE_OWN_COLOR); Self().Add(mBlurRootActor); mBlurFilter.SetRootActor(mBlurRootActor); mBlurFilter.SetBackgroundColor(Vector4::ZERO); CustomActor self = Self(); // Register a property that the user can use to control the blur in the internal object mBlurStrengthPropertyIndex = self.RegisterProperty(BLUR_STRENGTH_PROPERTY_NAME, BLUR_STRENGTH_DEFAULT); Constraint blurStrengthConstraint = Constraint::New<float>( mBlurFilter.GetHandleForAnimateBlurStrength(), mBlurFilter.GetBlurStrengthPropertyIndex(), EqualToConstraint() ); blurStrengthConstraint.AddSource( Source( self, mBlurStrengthPropertyIndex) ); blurStrengthConstraint.Apply(); }