//-------------------------------------------------------------------------- void Lightning::processEvent(LightningStrikeEvent* pEvent) { AssertFatal(pEvent->mStart.x >= 0.0f && pEvent->mStart.x <= 1.0f, "Out of bounds coord!"); Strike* pStrike = new Strike; Point3F strikePoint; strikePoint.zero(); if( pEvent->mTarget ) { Point3F objectCenter; pEvent->mTarget->getObjBox().getCenter( &objectCenter ); objectCenter.convolve( pEvent->mTarget->getScale() ); pEvent->mTarget->getTransform().mulP( objectCenter ); strikePoint = objectCenter; } else { strikePoint.x = pEvent->mStart.x; strikePoint.y = pEvent->mStart.y; strikePoint *= mObjScale; strikePoint += getPosition(); strikePoint += Point3F( -mObjScale.x * 0.5f, -mObjScale.y * 0.5f, 0.0f ); RayInfo rayInfo; Point3F start = strikePoint; start.z = mObjScale.z * 0.5f + getPosition().z; strikePoint.z += -mObjScale.z * 0.5f; bool rayHit = gClientContainer.castRay( start, strikePoint, (STATIC_COLLISION_TYPEMASK | WaterObjectType), &rayInfo); if( rayHit ) { strikePoint.z = rayInfo.point.z; } else { strikePoint.z = pStrike->bolt[0].findHeight( strikePoint, getSceneManager() ); } } pStrike->xVal = strikePoint.x; pStrike->yVal = strikePoint.y; pStrike->deathAge = 1.6f; pStrike->currentAge = 0.0f; pStrike->next = mStrikeListHead; for( U32 i=0; i<3; i++ ) { F32 randStart = boltStartRadius; F32 height = mObjScale.z * 0.5f + getPosition().z; pStrike->bolt[i].startPoint.set( pStrike->xVal + gRandGen.randF( -randStart, randStart ), pStrike->yVal + gRandGen.randF( -randStart, randStart ), height ); pStrike->bolt[i].endPoint = strikePoint; pStrike->bolt[i].width = strikeWidth; pStrike->bolt[i].numMajorNodes = 10; pStrike->bolt[i].maxMajorAngle = 30.0f; pStrike->bolt[i].numMinorNodes = 4; pStrike->bolt[i].maxMinorAngle = 15.0f; pStrike->bolt[i].generate(); pStrike->bolt[i].startSplits(); pStrike->bolt[i].lifetime = 1.0f; pStrike->bolt[i].fadeTime = 0.2f; pStrike->bolt[i].renderTime = gRandGen.randF(0.0f, 0.25f); } mStrikeListHead = pStrike; scheduleThunder(pStrike); MatrixF trans(true); trans.setPosition( strikePoint ); if (mDataBlock->strikeSound) { SFX->playOnce(mDataBlock->strikeSound, &trans ); } }
void DecalRoad::_captureVerts() { PROFILE_SCOPE( DecalRoad_captureVerts ); //Con::warnf( "%s - captureVerts", isServerObject() ? "server" : "client" ); if ( isServerObject() ) { //Con::errorf( "DecalRoad::_captureVerts - called on the server side!" ); return; } if ( mEdges.size() == 0 ) return; // // Construct ClippedPolyList objects for each pair // of roadEdges. // Use them to capture Terrain verts. // SphereF sphere; RoadEdge *edge = NULL; RoadEdge *nextEdge = NULL; mTriangleCount = 0; mVertCount = 0; Vector<ClippedPolyList> clipperList; for ( U32 i = 0; i < mEdges.size() - 1; i++ ) { Box3F box; edge = &mEdges[i]; nextEdge = &mEdges[i+1]; box.minExtents = edge->p1; box.maxExtents = edge->p1; box.extend( edge->p0 ); box.extend( edge->p2 ); box.extend( nextEdge->p0 ); box.extend( nextEdge->p1 ); box.extend( nextEdge->p2 ); box.minExtents.z -= 5.0f; box.maxExtents.z += 5.0f; sphere.center = ( nextEdge->p1 + edge->p1 ) * 0.5f; sphere.radius = 100.0f; // NOTE: no idea how to calculate this ClippedPolyList clipper; clipper.mNormal.set(0.0f, 0.0f, 0.0f); VectorF n; PlaneF plane0, plane1; // Construct Back Plane n = edge->p2 - edge->p0; n.normalize(); n = mCross( n, edge->uvec ); plane0.set( edge->p0, n ); clipper.mPlaneList.push_back( plane0 ); // Construct Front Plane n = nextEdge->p2 - nextEdge->p0; n.normalize(); n = -mCross( edge->uvec, n ); plane1.set( nextEdge->p0, -n ); //clipper.mPlaneList.push_back( plane1 ); // Test if / where the planes intersect. bool discardLeft = false; bool discardRight = false; Point3F iPos; VectorF iDir; if ( plane0.intersect( plane1, iPos, iDir ) ) { Point2F iPos2F( iPos.x, iPos.y ); Point2F cPos2F( edge->p1.x, edge->p1.y ); Point2F rVec2F( edge->rvec.x, edge->rvec.y ); Point2F iVec2F = iPos2F - cPos2F; F32 iLen = iVec2F.len(); iVec2F.normalize(); if ( iLen < edge->width * 0.5f ) { F32 dot = mDot( rVec2F, iVec2F ); // The clipping planes intersected on the right side, // discard the right side clipping plane. if ( dot > 0.0f ) discardRight = true; // The clipping planes intersected on the left side, // discard the left side clipping plane. else discardLeft = true; } } // Left Plane if ( !discardLeft ) { n = ( nextEdge->p0 - edge->p0 ); n.normalize(); n = mCross( edge->uvec, n ); clipper.mPlaneList.push_back( PlaneF(edge->p0, n) ); } else { nextEdge->p0 = edge->p0; } // Right Plane if ( !discardRight ) { n = ( nextEdge->p2 - edge->p2 ); n.normalize(); n = -mCross( n, edge->uvec ); clipper.mPlaneList.push_back( PlaneF(edge->p2, -n) ); } else { nextEdge->p2 = edge->p2; } n = nextEdge->p2 - nextEdge->p0; n.normalize(); n = -mCross( edge->uvec, n ); plane1.set( nextEdge->p0, -n ); clipper.mPlaneList.push_back( plane1 ); // We have constructed the clipping planes, // now grab/clip the terrain geometry getContainer()->buildPolyList( PLC_Decal, box, TerrainObjectType, &clipper ); clipper.cullUnusedVerts(); clipper.triangulate(); clipper.generateNormals(); // If we got something, add it to the ClippedPolyList Vector if ( !clipper.isEmpty() && !( smDiscardAll && ( discardRight || discardLeft ) ) ) { clipperList.push_back( clipper ); mVertCount += clipper.mVertexList.size(); mTriangleCount += clipper.mPolyList.size(); } } // // Set the roadEdge height to be flush with terrain // This is not really necessary but makes the debug spline rendering better. // for ( U32 i = 0; i < mEdges.size() - 1; i++ ) { edge = &mEdges[i]; _getTerrainHeight( edge->p0.x, edge->p0.y, edge->p0.z ); _getTerrainHeight( edge->p2.x, edge->p2.y, edge->p2.z ); } // // Allocate the RoadBatch(s) // // If we captured no verts, then we can return here without // allocating any RoadBatches or the Vert/Index Buffers. // PreprenderImage will not allocate a render instance while // mBatches.size() is zero. U32 numClippers = clipperList.size(); if ( numClippers == 0 ) return; mBatches.clear(); // Allocate the VertexBuffer and PrimitiveBuffer mVB.set( GFX, mVertCount, GFXBufferTypeStatic ); mPB.set( GFX, mTriangleCount * 3, 0, GFXBufferTypeStatic ); // Lock the VertexBuffer GFXVertexPNTBT *vertPtr = mVB.lock(); U32 vertIdx = 0; // // Fill the VertexBuffer and vertex data for the RoadBatches // Loop through the ClippedPolyList Vector // RoadBatch *batch = NULL; F32 texStart = 0.0f; F32 texEnd; for ( U32 i = 0; i < clipperList.size(); i++ ) { ClippedPolyList *clipper = &clipperList[i]; RoadEdge &edge = mEdges[i]; RoadEdge &nextEdge = mEdges[i+1]; VectorF segFvec = nextEdge.p1 - edge.p1; F32 segLen = segFvec.len(); segFvec.normalize(); F32 texLen = segLen / mTextureLength; texEnd = texStart + texLen; BiQuadToSqr quadToSquare( Point2F( edge.p0.x, edge.p0.y ), Point2F( edge.p2.x, edge.p2.y ), Point2F( nextEdge.p2.x, nextEdge.p2.y ), Point2F( nextEdge.p0.x, nextEdge.p0.y ) ); // if ( i % mSegmentsPerBatch == 0 ) { mBatches.increment(); batch = &mBatches.last(); batch->bounds.minExtents = clipper->mVertexList[0].point; batch->bounds.maxExtents = clipper->mVertexList[0].point; batch->startVert = vertIdx; } // Loop through each ClippedPolyList for ( U32 j = 0; j < clipper->mVertexList.size(); j++ ) { // Add each vert to the VertexBuffer Point3F pos = clipper->mVertexList[j].point; vertPtr[vertIdx].point = pos; vertPtr[vertIdx].normal = clipper->mNormalList[j]; Point2F uv = quadToSquare.transform( Point2F(pos.x,pos.y) ); vertPtr[vertIdx].texCoord.x = uv.x; vertPtr[vertIdx].texCoord.y = -(( texEnd - texStart ) * uv.y + texStart); vertPtr[vertIdx].tangent = mCross( segFvec, clipper->mNormalList[j] ); vertPtr[vertIdx].binormal = segFvec; vertIdx++; // Expand the RoadBatch bounds to contain this vertex batch->bounds.extend( pos ); } batch->endVert = vertIdx - 1; texStart = texEnd; } // Unlock the VertexBuffer, we are done filling it. mVB.unlock(); // Lock the PrimitiveBuffer U16 *idxBuff; mPB.lock(&idxBuff); U32 curIdx = 0; U16 vertOffset = 0; batch = NULL; S32 batchIdx = -1; // Fill the PrimitiveBuffer // Loop through each ClippedPolyList in the Vector for ( U32 i = 0; i < clipperList.size(); i++ ) { ClippedPolyList *clipper = &clipperList[i]; if ( i % mSegmentsPerBatch == 0 ) { batchIdx++; batch = &mBatches[batchIdx]; batch->startIndex = curIdx; } for ( U32 j = 0; j < clipper->mPolyList.size(); j++ ) { // Write indices for each Poly ClippedPolyList::Poly *poly = &clipper->mPolyList[j]; AssertFatal( poly->vertexCount == 3, "Got non-triangle poly!" ); idxBuff[curIdx] = clipper->mIndexList[poly->vertexStart] + vertOffset; curIdx++; idxBuff[curIdx] = clipper->mIndexList[poly->vertexStart + 1] + vertOffset; curIdx++; idxBuff[curIdx] = clipper->mIndexList[poly->vertexStart + 2] + vertOffset; curIdx++; } batch->endIndex = curIdx - 1; vertOffset += clipper->mVertexList.size(); } // Unlock the PrimitiveBuffer, we are done filling it. mPB.unlock(); // Generate the object/world bounds // Is the union of all batch bounding boxes. Box3F box; for ( U32 i = 0; i < mBatches.size(); i++ ) { const RoadBatch &batch = mBatches[i]; if ( i == 0 ) box = batch.bounds; else box.intersect( batch.bounds ); } Point3F pos = getPosition(); mWorldBox = box; resetObjectBox(); // Make sure we are in the correct bins given our world box. if( getSceneManager() != NULL ) getSceneManager()->notifyObjectDirty( this ); }
// render // override render state void CGameAnimatedMeshSceneNode::render() { #ifdef GSEDITOR CGameObject::EObjectState state = m_owner->getObjectState(); // draw bbox on select if ( state == CGameObject::Move || state == CGameObject::Review ) setDebugDataVisible( EDS_BBOX ); else setDebugDataVisible( 0 ); // call object draw m_owner->drawObject(); #endif // draw animesh CAnimatedMeshSceneNode::render(); #ifdef GSANIMATION // get driver IVideoDriver* driver = getSceneManager()->getVideoDriver(); ISkinnedMesh *mesh = (ISkinnedMesh*)getMesh(); IView *pView = getIView(); irr::gui::IGUIFont* font = getSceneManager()->getGUIEnvironment()->getBuiltInFont(); video::SMaterial debug_mat; debug_mat.Lighting = false; debug_mat.AntiAliasing = 0; debug_mat.ZBuffer = video::ECFN_NEVER; for (u32 g=0; g < mesh->getAllJoints().size(); ++g) { ISkinnedMesh::SJoint *joint = mesh->getAllJoints()[g]; core::vector3df v; //basic bone //core::matrix4 mat1 = joint->GlobalInversedMatrix; //mat1.makeInverse(); //anim bone core::matrix4 mat1 = joint->GlobalAnimatedMatrix; // get position mat1.transformVect( v ); // scale with character v *= m_owner->getScale(); // draw name bone on screen int x, y; pView->getScreenCoordinatesFrom3DPosition( v, &x, &y ); wchar_t text[1024]; uiString::copy<wchar_t, const c8>( text, joint->Name.c_str() ); // draw bone position SColor c = SColor(255,0,0,255); driver->setMaterial(debug_mat); driver->draw2DRectangle( c, core::rect<s32>( x - 2, y - 2, x + 2, y + 2 ) ); // draw text font->draw( text, core::rect<s32>( x + 10, y, x + 100, y + 50), SColor(255, 255,255,0) ); } #endif #ifdef GSEDITOR // draw move if ( state == CGameObject::Move || state == CGameObject::Rotation || state == CGameObject::Scale ) m_owner->drawFrontUpLeftVector(); if ( state == CGameObject::Rotation ) m_owner->drawCircleAroundObject(); #endif }
bool SceneCullingState::isOccludedByTerrain( SceneObject* object ) const { PROFILE_SCOPE( SceneCullingState_isOccludedByTerrain ); // Don't try to occlude globally bounded objects. if( object->isGlobalBounds() ) return false; const Vector< SceneObject* >& terrains = getSceneManager()->getContainer()->getTerrains(); const U32 numTerrains = terrains.size(); for( U32 terrainIdx = 0; terrainIdx < numTerrains; ++ terrainIdx ) { TerrainBlock* terrain = dynamic_cast< TerrainBlock* >( terrains[ terrainIdx ] ); if( !terrain ) continue; Point3F localCamPos = getCameraState().getViewPosition(); terrain->getWorldTransform().mulP( localCamPos ); F32 height; terrain->getHeight( Point2F( localCamPos.x, localCamPos.y ), &height ); bool aboveTerrain = ( height <= localCamPos.z ); // Don't occlude if we're below the terrain. This prevents problems when // looking out from underground bases... if( !aboveTerrain ) continue; const Box3F& oBox = object->getObjBox(); F32 minSide = getMin(oBox.len_x(), oBox.len_y()); if (minSide > 85.0f) continue; const Box3F& rBox = object->getWorldBox(); Point3F ul(rBox.minExtents.x, rBox.minExtents.y, rBox.maxExtents.z); Point3F ur(rBox.minExtents.x, rBox.maxExtents.y, rBox.maxExtents.z); Point3F ll(rBox.maxExtents.x, rBox.minExtents.y, rBox.maxExtents.z); Point3F lr(rBox.maxExtents.x, rBox.maxExtents.y, rBox.maxExtents.z); terrain->getWorldTransform().mulP(ul); terrain->getWorldTransform().mulP(ur); terrain->getWorldTransform().mulP(ll); terrain->getWorldTransform().mulP(lr); Point3F xBaseL0_s = ul - localCamPos; Point3F xBaseL0_e = lr - localCamPos; Point3F xBaseL1_s = ur - localCamPos; Point3F xBaseL1_e = ll - localCamPos; static F32 checkPoints[3] = {0.75, 0.5, 0.25}; RayInfo rinfo; for( U32 i = 0; i < 3; i ++ ) { Point3F start = (xBaseL0_s * checkPoints[i]) + localCamPos; Point3F end = (xBaseL0_e * checkPoints[i]) + localCamPos; if (terrain->castRay(start, end, &rinfo)) continue; terrain->getHeight(Point2F(start.x, start.y), &height); if ((height <= start.z) == aboveTerrain) continue; start = (xBaseL1_s * checkPoints[i]) + localCamPos; end = (xBaseL1_e * checkPoints[i]) + localCamPos; if (terrain->castRay(start, end, &rinfo)) continue; Point3F test = (start + end) * 0.5; if (terrain->castRay(localCamPos, test, &rinfo) == false) continue; return true; } } return false; }
OgreObjectView::OgreObjectView( QWidget* parent ) : OgreWidget(parent), m_SceneNode(nullptr), m_Node(getSceneManager()->createSceneNode()){ m_RollOverCameraController = nullptr; setMouseTracking(true); }
//----------------------------------------------------------------------------------------- TestAnimation::TestAnimation() { // On crée une camera m_pCamera = getSceneManager()->createCamera(); m_pCamera->setEyePosition(QVector3D(2., 1., 2.)); m_pCamera->setCenter(QVector3D(0., 0., 0.)); #ifdef SOFTWARE_RENDERING m_pView = createSoftwareView3D(m_pCamera); #else m_pView = createWidget3D(m_pCamera); #endif m_pCamera->setAspectRatio((real)m_pView->width() / (real)m_pView->height()); // On charge le modéle CSceneNode* pRootNode = m_pSceneManager->getRootNode(); CSceneNode* pModelNode = pRootNode->createChild("dwarf"); // anim_test.x // rotatingcube.3ds // dwarf.x if (!CAssimpImporter::mergeScene("://dwarf.x", m_pSceneManager, true, pModelNode).isEmpty()) { // On récupére la bounding box CBox3D bbox = pRootNode->getGlobalAxisAlignedBoundingBox(); real sizeX = bbox.getMaximum().x() - bbox.getMinimum().x(); real sizeY = bbox.getMaximum().y() - bbox.getMinimum().y(); real sizeZ = bbox.getMaximum().z() - bbox.getMinimum().z(); real maxSize = sizeX; if (sizeY > maxSize) maxSize = sizeY; if (sizeZ > maxSize) maxSize = sizeZ; // On redimensionne la scene de façon à ce qu'elle tienne dans une boite de 1x1x1 pModelNode->scale(1. / maxSize); CBox3D scaledBbox = pModelNode->getGlobalAxisAlignedBoundingBox(); // On la centre pModelNode->translate(-scaledBbox.getCenter()); CSceneNode* pLightNode = pRootNode->createChild("LightNode", QVector3D(8.0, 12.0, 0)); // On crée une lumiére diffuse blanche CLight* pLight = m_pSceneManager->createLight("Light"); pLight->setDiffuseColor(0.8f, 0.8f, 0.8f); pLight->setAmbientColor(0.6f, 0.6f, 0.6f); pLight->setSpecularColor(0.4f, 0.4f, 0.4f); pLight->setDirection(QVector3D(-1, -1, 0)); // On l'associe au noeud pLightNode->addItem(pLight); pRootNode->dumpNodeTree(); //m_pSceneManager->setSceneGraphVisible(true); QList<CAnimation*> anims = m_pSceneManager->getAnimations(); m_pView->setGeometry(QRect(100, 100, 400, 300)); m_pView->getRenderer()->run(); getAnimationManager()->run(); if (anims.size() > 0) { QList<CSceneNodeAnimation*> nodeAnimations = anims[0]->getNodeAnimations(); foreach (CSceneNodeAnimation* pNodeAnim, nodeAnimations) { pNodeAnim->setAnimationBehavior(eAnimationBehaviourRepeat); }
//----------------------------------------------------------------------- void Shadows::createTestScene(bool useOgreMaterials) { Ogre::String planeMatName, knotMatName; if(useOgreMaterials) { planeMatName = "PSSM/Plane"; knotMatName = "PSSM/Knot"; } else { planeMatName = "PSSMPlane"; knotMatName = "PSSMKnot"; } // temp planeMatName = "ESM/Plane"; knotMatName = "ESM/Knot"; SceneManager* sceneMgr = getSceneManager(); /* sceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); Light* l = sceneMgr->createLight("Spot"); l->setType(Light::LT_SPOTLIGHT); Vector3 dir(0.3, -1, 0.2); dir.normalise(); l->setDirection(dir); l->setDiffuseColour(ColourValue(1.0, 1.0, 0.0, 1)); l->setPosition(0, 25.0, 2.0); l->setSpotlightRange((Radian) 0.104, (Radian) 1.40, 1); l->setAttenuation(50, 1.0, 0.009, 0.0032); */ // Create a basic plane to have something in the scene to look at Plane plane; plane.normal = Vector3::UNIT_Y; plane.d = 100; MeshPtr msh = MeshManager::getSingleton().createPlane("Myplane", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, 4500,4500,100,100,true,1,40,40,Vector3::UNIT_Z); msh->buildTangentVectors(VES_TANGENT); Entity* pPlaneEnt; pPlaneEnt = sceneMgr->createEntity( "plane", "Myplane" ); pPlaneEnt->setMaterialName(planeMatName); sceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); Entity* ent = sceneMgr->createEntity("knot", "knot.mesh"); ent->setMaterialName(knotMatName); createRandomEntityClones(ent, 20, Vector3(-100,0,-100), Vector3(100,0,100)); SceneNode* node = sceneMgr->getRootSceneNode()->createChildSceneNode(); node->attachObject(ent); //node->setPosition(Vector3(0, 0, 0)); for(int i=0; i<sceneMgr->getRootSceneNode()->numChildren(); i++) { Node* node = sceneMgr->getRootSceneNode()->getChild(i); node->setScale(0.05f, 0.05f, 0.05f); } }
//------------------------------------------------------------------------------ void PlayScene::create() { World& world = getSceneManager().getWorld(); // Camera Transform* transCamera = DG_NEW(Transform, world.getLinearArena()); transCamera->position = vmVector3(0.0f, 3.4f, 0.0f); Camera* camera = DG_NEW(Camera, world.getLinearArena()); camera->fov = 0.9f; world.getEntity(0).addComponent(transCamera); world.getEntity(0).addComponent(camera); // Light Transform* transLight = DG_NEW(Transform, world.getLinearArena()); transLight->position = vmVector3(0, 10, 0); Light* light = DG_NEW(Light, world.getLinearArena())(0); light->lightType = LT_DIRECTIONAL; light->direction = vmVector3(0.0f, 0.9f, 1.0f); //Material matCube; //matCube.ambient = vmVector4(0.7f, 0.7f, 0.7f, 1.f); //matCube.diffuse = vmVector4(0.7f, 0.7f, 0.7f, 1.f); //matCube.textureFiles.push_back("tiles.png"); //Mesh* meshCube = DG_NEW(Mesh, world.getLinearArena()); //meshCube->file = "../media/cube.x"; //meshCube->materials.push_back(matCube); world.getEntity(1).addComponent(transLight); world.getEntity(1).addComponent(light); //world.getEntity(1).addComponent(meshCube); // Set active camera and light world.getSystemManager().getSystem<MeshSystem>()->setCamera(camera); world.getSystemManager().getSystem<MeshSystem>()->setLight(light); // Sky Transform* transSky = DG_NEW(Transform, world.getLinearArena()); transSky->position = vmVector3(0, 0, 0); Material matSky; matSky.textureFiles.push_back("NoiseVolume.dds"); Mesh* meshSky = DG_NEW(Mesh, world.getLinearArena()); meshSky->file = "../media/sphere_inverted.x"; meshSky->effectFile = "../media/sky.cg"; meshSky->materials.push_back(matSky); world.getEntity(2).addComponent(transSky); world.getEntity(2).addComponent(meshSky); // Terrain Transform* transTerrain = DG_NEW(Transform, world.getLinearArena()); transTerrain->position = vmVector3(0, 0, 0); Material matTerrain; matTerrain.ambient = vmVector4(0.2f, 0.2f, 0.2f, 1.f); matTerrain.diffuse = vmVector4(0.7f, 0.7f, 0.7f, 1.f); matTerrain.textureFiles.push_back("grass.jpg"); Mesh* meshTerrain = DG_NEW(Mesh, world.getLinearArena()); meshTerrain->file = "../media/TerrainTextured.x"; meshTerrain->effectFile = "../media/terrain.cg"; meshTerrain->materials.push_back(matTerrain); world.getEntity(3).addComponent(transTerrain); world.getEntity(3).addComponent(meshTerrain); // Water Transform* transWater = DG_NEW(Transform, world.getLinearArena()); transWater->position = vmVector3(0, -2, 0); transWater->scale = vmVector3(130, 1, 130); Material matWater; matWater.ambient = vmVector4(0.0f, 0.5459f, 0.8496f, 1.f); matWater.diffuse = vmVector4(0.0f, 0.5459f, 0.8496f, 0.5f); Mesh* meshWater = DG_NEW(Mesh, world.getLinearArena()); meshWater->file = "../media/quad.x"; meshWater->effectFile = "../media/water.cg"; meshWater->materials.push_back(matWater); world.getEntity(4).addComponent(transWater); world.getEntity(4).addComponent(meshWater); // Copter Transform* transCopter = DG_NEW(Transform, world.getLinearArena()); transCopter->position = vmVector3(0, 0, 0); Material matCopter; Material matCopter2; matCopter2.ambient = vmVector4(0.2f, 0.2f, 0.2f, 1.f); matCopter2.diffuse = vmVector4(0.7f, 0.7f, 0.7f, 1.f); matCopter2.textureFiles.push_back("copter_diffuse.png"); matCopter2.textureFiles.push_back("copter_normal.png"); //matCopter2.textureFiles.push_back("tiles.png"); //matCopter2.textureFiles.push_back("tiles_normal.png"); Mesh* meshCopter = DG_NEW(Mesh, world.getLinearArena()); meshCopter->file = "../media/copter.x"; meshCopter->effectFile = "../media/copter.cg"; meshCopter->materials.push_back(matCopter); meshCopter->materials.push_back(matCopter2); world.getEntity(5).addComponent(transCopter); world.getEntity(5).addComponent(meshCopter); // Initialise all systems world.getSystemManager().initialiseAll(); // Test physics PxMaterial* material = &mPhysXWorld.getDefaultMaterial(); material->setRestitution(0.5f); material->setStaticFriction(1.0f); material->setDynamicFriction(1.0f); //mActor = mPhysXWorld.getScene("Main")->createRigidDynamic( //physx::PxConvexMeshGeometry(PhysXCooker::createPxConvexMesh(*mPhysXWorld.getPxPhysics(), *mPhysXWorld.getCookingInterface(), //world.getSystemManager().getSystem<MeshSystem>()->getVertices(world.getEntity(3)))), 20.0f, *material); /*mActor = mPhysXWorld.getScene("Main")->createRigidDynamic( PhysXGeometry::boxGeometry(world.getEntity(2), *world.getSystemManager().getSystem<MeshSystem>()), 10.0f, *material); mPhysXWorld.getScene("Main")->createRenderedActorBinding(mActor, DG_NEW(PhysXEntityRenderable, world.getLinearArena())(&world.getEntity(2))); mActor.setGlobalPosition(vmVector3(0.0f, 20.0, 0.0f));*/ //PhysXActor<PxRigidDynamic> actor1 = mPhysXWorld.getScene("Main")->createRigidDynamic( //physx::PxConvexMeshGeometry(PhysXCooker::createPxConvexMesh(*mPhysXWorld.getPxPhysics(), *mPhysXWorld.getCookingInterface(), //world.getSystemManager().getSystem<MeshSystem>()->getVertices(world.getEntity(4)))), 20.0f, *material); mActor = mPhysXWorld.getScene("Main")->createRigidDynamic( PhysXGeometry::boxGeometry(world.getEntity(5), *world.getSystemManager().getSystem<MeshSystem>()), 1.f, *material); mPhysXWorld.getScene("Main")->createRenderedActorBinding(mActor, DG_NEW(PhysXEntityRenderable, world.getLinearArena())(&world.getEntity(5))); mActor.setGlobalPosition(vmVector3(-3.0f, 0.0f, 0.0f)); mActor.getPxActor()->setLinearDamping(0.8f); mActor.getPxActor()->setAngularDamping(1.0f); PhysXActor<PxRigidStatic> actor2 = mPhysXWorld.getScene("Main")->createRigidStatic( physx::PxTriangleMeshGeometry(PhysXCooker::createPxTriangleMesh(*mPhysXWorld.getPxPhysics(), *mPhysXWorld.getCookingInterface(), world.getSystemManager().getSystem<MeshSystem>()->getIndices(world.getEntity(3)), world.getSystemManager().getSystem<MeshSystem>()->getVertices(world.getEntity(3)))), *material); mInput.subscribeKeyboard(*this); mInput.subscribeMouse(*this); }
void Portal::_updateConnectivity() { SceneZoneSpaceManager* zoneManager = getSceneManager()->getZoneManager(); if( !zoneManager ) return; // Find out where our connected zones are in respect to the portal // plane. bool haveInteriorZonesOnFrontSide = false; bool haveInteriorZonesOnBackSide = false; bool isConnectedToRootZone = ( mClassification == ExteriorPortal ); for( ZoneSpaceRef* ref = mConnectedZoneSpaces; ref != NULL; ref = ref->mNext ) { SceneZoneSpace* zone = dynamic_cast< SceneZoneSpace* >( ref->mZoneSpace ); if( !zone || zone->isRootZone() ) continue; if( getSideRelativeToPortalPlane( zone->getPosition() ) == FrontSide ) haveInteriorZonesOnFrontSide = true; else haveInteriorZonesOnBackSide = true; } // If we have zones connected to us on only one side, we are an exterior // portal. Otherwise, we're an interior portal. SceneRootZone* rootZone = zoneManager->getRootZone(); if( haveInteriorZonesOnFrontSide && haveInteriorZonesOnBackSide ) { mClassification = InteriorPortal; } else if( haveInteriorZonesOnFrontSide || haveInteriorZonesOnBackSide ) { mClassification = ExteriorPortal; // Remember where our interior zones are. if( haveInteriorZonesOnBackSide ) mInteriorSide = BackSide; else mInteriorSide = FrontSide; // If we aren't currently connected to the root zone, // establish the connection now. if( !isConnectedToRootZone ) { Parent::connectZoneSpace( rootZone ); rootZone->connectZoneSpace( this ); } } else mClassification = InvalidPortal; // If we have been connected to the outdoor zone already but the // portal got classified as invalid or interior now, break the // connection to the outdoor zone. if( isConnectedToRootZone && ( mClassification == InvalidPortal || mClassification == InteriorPortal ) ) { Parent::disconnectZoneSpace( rootZone ); rootZone->disconnectZoneSpace( this ); } }
void LightManager::registerGlobalLights( const Frustum *frustum, bool staticLighting ) { PROFILE_SCOPE( LightManager_RegisterGlobalLights ); // TODO: We need to work this out... // // 1. Why do we register and unregister lights on every // render when they don't often change... shouldn't we // just register once and keep them? // // 2. If we do culling of lights should this happen as part // of registration or somewhere else? // // Grab the lights to process. Vector<SceneObject*> activeLights; const U32 lightMask = LightObjectType; if ( staticLighting || !frustum ) { // We're processing static lighting or want all the lights // in the container registerd... so no culling. getSceneManager()->getContainer()->findObjectList( lightMask, &activeLights ); } else { // Cull the lights using the frustum. getSceneManager()->getContainer()->findObjectList( *frustum, lightMask, &activeLights ); for (U32 i = 0; i < activeLights.size(); ++i) { if (!getSceneManager()->mRenderedObjectsList.contains(activeLights[i])) { activeLights.erase(i); --i; } } // Store the culling position for sun placement // later... see setSpecialLight. mCullPos = frustum->getPosition(); // HACK: Make sure the control object always gets // processed as lights mounted to it don't change // the shape bounds and can often get culled. GameConnection *conn = GameConnection::getConnectionToServer(); if ( conn->getControlObject() ) { GameBase *conObject = conn->getControlObject(); activeLights.push_back_unique( conObject ); } } // Let the lights register themselves. for ( U32 i = 0; i < activeLights.size(); i++ ) { ISceneLight *lightInterface = dynamic_cast<ISceneLight*>( activeLights[i] ); if ( lightInterface ) lightInterface->submitLights( this, staticLighting ); } }
void Portal::_traverseConnectedZoneSpaces( SceneTraversalState* state ) { PROFILE_SCOPE( Portal_traverseConnectedZoneSpaces ); // Don't traverse out from the portal if it is invalid. if( mClassification == InvalidPortal ) return; AssertFatal( !mIsGeometryDirty, "Portal::_traverseConnectedZoneSpaces - Geometry not up-to-date!" ); // When starting traversal within a portal zone, we cannot really use the portal // plane itself to direct our visibility queries. For example, the camera might // actually be located in front of the portal plane and thus cannot actually look // through the portal, though it will still see what lies on front of where the // portal leads. // // So if we're the start of the traversal chain, i.e. the traversal has started // out in the portal zone, then just put the traversal through to SceneZoneSpace // so it can hand it over to all connected zone managers. // // Otherwise, just do a normal traversal by stepping through the portal. if( state->getTraversalDepth() == 1 ) { Parent::_traverseConnectedZoneSpaces( state ); return; } SceneCullingState* cullingState = state->getCullingState(); const SceneCameraState& cameraState = cullingState->getCameraState(); // Get the data of the zone we're coming from. Note that at this point // the portal zone itself is already on top of the traversal stack, so // we skip over the bottom-most entry. const U32 sourceZoneId = state->getZoneIdFromStack( 1 ); const SceneZoneSpace* sourceZoneSpace = state->getZoneFromStack( 1 ); // Find out which side of the portal we are on given the // source zone. const Portal::Side currentZoneSide = sourceZoneId == SceneZoneSpaceManager::RootZoneId ? ( getInteriorSideOfExteriorPortal() == FrontSide ? BackSide : FrontSide ) : getSideRelativeToPortalPlane( sourceZoneSpace->getPosition() ); // Don't step through portal if the side we're interested in isn't passable. if( !isSidePassable( currentZoneSide ) ) return; // If the viewpoint isn't on the same side of the portal as the source zone, // then stepping through the portal would mean we are stepping back towards // the viewpoint which doesn't make sense; so, skip the portal. const Point3F& viewPos = cameraState.getViewPosition(); const F32 viewPosDistToPortal = mFabs( getPortalPlane().distToPlane( viewPos ) ); if( !mIsZero( viewPosDistToPortal ) && getSideRelativeToPortalPlane( viewPos ) != currentZoneSide ) return; // Before we go ahead and do the real work, try to find out whether // the portal is at a perpendicular or near-perpendicular angle to the view // direction. If so, there's no point in going further since we can't really // see much through the portal anyway. It also prevents us from stepping // over front/back side ambiguities. Point3F viewDirection = cameraState.getViewDirection(); const F32 dotProduct = mDot( viewDirection, getPortalPlane() ); if( mIsZero( dotProduct ) ) return; // Finally, if we have come through a portal to the current zone, check if the target // portal we are trying to step through now completely lies on the "backside"--i.e. // the side of portal on which our current zone lies--of the source portal. If so, // we can be sure this portal leads us in the wrong direction. This prevents the // outdoor zone from having just arrived through a window on one side of a house just // to go round the house and re-enter it from the other side. Portal* sourcePortal = state->getTraversalDepth() > 2 ? dynamic_cast< Portal* >( state->getZoneFromStack( 2 ) ) : NULL; if( sourcePortal != NULL ) { const Side sourcePortalFrontSide = sourceZoneId == SceneZoneSpaceManager::RootZoneId ? sourcePortal->getInteriorSideOfExteriorPortal() : sourcePortal->getSideRelativeToPortalPlane( sourceZoneSpace->getPosition() ); const PlaneF::Side sourcePortalPlaneFrontSide = sourcePortalFrontSide == FrontSide ? PlaneF::Front : PlaneF::Back; bool allPortalVerticesOnBackside = true; const U32 numVertices = mPortalPolygonWS.size(); for( U32 i = 0; i < numVertices; ++ i ) { // Not using getSideRelativeToPortalPlane here since we want PlaneF::On to be // counted as backside here. if( sourcePortal->mPortalPlane.whichSide( mPortalPolygonWS[ i ] ) == sourcePortalPlaneFrontSide ) { allPortalVerticesOnBackside = false; break; } } if( allPortalVerticesOnBackside ) return; } // If we come from the outdoor zone, then we don't want to step through any portal // where the interior zones are actually on the same side as our camera since that // would mean we are stepping into an interior through the backside of a portal. if( sourceZoneId == SceneZoneSpaceManager::RootZoneId ) { const Portal::Side cameraSide = getSideRelativeToPortalPlane( viewPos ); if( cameraSide == getInteriorSideOfExteriorPortal() ) return; } // Clip the current culling volume against the portal's polygon. If the polygon // lies completely outside the volume or for some other reason there's no good resulting // volume, _generateCullingVolume() will return false and we terminate this portal sequence // here. // // However, don't attempt to clip the portal if we are standing really close to or // even below the near distance away from the portal plane. In that case, trying to // clip the portal will only result in trouble so we stick to the original culling volume // in that case. bool haveClipped = false; if( viewPosDistToPortal > ( cameraState.getFrustum().getNearDist() + 0.1f ) ) { SceneCullingVolume volume; if( !_generateCullingVolume( state, volume ) ) return; state->pushCullingVolume( volume ); haveClipped = true; } // Short-circuit things if we are stepping from an interior zone outside. In this // case we know that the only zone we care about is the outdoor zone so head straight // into it. if( isExteriorPortal() && sourceZoneId != SceneZoneSpaceManager::RootZoneId ) getSceneManager()->getZoneManager()->getRootZone()->traverseZones( state ); else { // Go through the zones that the portal connects to and // traverse into them. for( ZoneSpaceRef* ref = mConnectedZoneSpaces; ref != NULL; ref = ref->mNext ) { SceneZoneSpace* targetSpace = ref->mZoneSpace; if( targetSpace == sourceZoneSpace ) continue; // Skip space we originated from. // We have handled the case of stepping into the outdoor zone above and // by skipping the zone we originated from, we have implicitly handled the // case of stepping out of the outdoor zone. Thus, we should not see the // outdoor zone here. Important as getPosition() is meaningless for it. AssertFatal( targetSpace->getZoneRangeStart() != SceneZoneSpaceManager::RootZoneId, "Portal::_traverseConnectedZoneSpaces - Outdoor zone must have been handled already" ); // Skip zones that lie on the same side as the zone // we originated from. if( getSideRelativeToPortalPlane( targetSpace->getPosition() ) == currentZoneSide ) continue; // Traverse into the space. targetSpace->traverseZones( state ); } } // If we have pushed our own clipping volume, // remove that from the stack now. if( haveClipped ) state->popCullingVolume(); }
void ViewWindow::onIdle() { if (NULL == getRenderContex()) { return; } // if (!getRenderContex()->isInitialized()) { getRenderContex()->setWaitForVBL(false); getRenderContex()->createDevice(m_hWnd, 0, 0, true, true, Vector2::Zero); createAfterD3DDevice(); camera_.speed(1.0f); camera_.turboSpeed(2.0f); Vector3 minBound = -Vector3( 100.5f, 0.f, 100.5f ); Vector3 maxBound = Vector3(10000, 5000.0f, 10000.0f); camera_.limit_ = BoundingBox( minBound, maxBound ); Matrix gViewMatrix; Vector3 gEye(0,150,-10); Vector3 gLookAt(0, 0, 0); Vector3 gUp(0, 1, 0); D3DXMatrixLookAtLH(&gViewMatrix, &gEye, &gLookAt, &gUp); camera_.view(gViewMatrix); // Camera c = getRenderContex()->getCamera(); c.setFarPlane(10000.0f); getRenderContex()->setCamera(c); getRenderContex()->updateProjectionMatrix(); getSceneManager()->setRunType(eRunType_Editor); getSceneManager()->setAllChunksVisible(false); } if (NULL == getRenderContex()->getDxDevice()) { return; } // static float lastTick = GetTickCount(); float currentTick = GetTickCount(); float delta = currentTick - lastTick; camera_.update(delta); getSceneManager()->update(); { // const Matrix* pmatProj = &getRenderContex()->getProjectionMatrix(); POINT ptCursor; GetCursorPos( &ptCursor ); ::ScreenToClient( m_hWnd, &ptCursor ); // Compute the vector of the pick ray in screen space D3DXVECTOR3 v; v.x = ( ( ( 2.0f * ptCursor.x ) / getRenderContex()->getScreenWidth() ) - 1 ) / pmatProj->_11; v.y = -( ( ( 2.0f * ptCursor.y ) / getRenderContex()->getScreenHeight() ) - 1 ) / pmatProj->_22; v.z = 1.0f; // Get the inverse view matrix const Matrix matView = getRenderContex()->getViewMatrix(); const Matrix matWorld = Matrix::Identity; Matrix mWorldView = matWorld; mWorldView.postMultiply(matView); Matrix m; m.invert(mWorldView); // Transform the screen space pick ray into 3D space Vector3 vPickRayDir, vPickRayOrig; vPickRayDir.x = v.x * m._11 + v.y * m._21 + v.z * m._31; vPickRayDir.y = v.x * m._12 + v.y * m._22 + v.z * m._32; vPickRayDir.z = v.x * m._13 + v.y * m._23 + v.z * m._33; vPickRayOrig.x = m._41; vPickRayOrig.y = m._42; vPickRayOrig.z = m._43; float t = -vPickRayOrig.y / vPickRayDir.y; float x = vPickRayOrig.x + t * vPickRayDir.x; float z = vPickRayOrig.z + t * vPickRayDir.z; if (getSceneManager()->getTerrain()) { getSceneManager()->getTerrain()->updateVisibleChunks(x, z); } } // getRenderContex()->setViewMatrix(camera_.view_); // uint32 clearFlags = D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER; if ( getRenderContex()->isStencilAvailable() ) clearFlags |= D3DCLEAR_STENCIL; getRenderContex()->getDxDevice()->Clear( 0, NULL, clearFlags, 0, 1, 0 ); getRenderContex()->beginScene(); if (getSceneManager()) { getSceneManager()->render(); } getRenderContex()->endScene(); getRenderContex()->present(); }
void Forest::prepRenderImage( SceneRenderState *state ) { PROFILE_SCOPE(Forest_RenderCells); // TODO: Fix stats. /* ForestCellVector &theCells = mData->getCells(); smTotalCells += theCells.size(); // Don't render if we don't have a grid! if ( theCells.empty() ) return false; */ // Prepare to render. GFXTransformSaver saver; // Figure out the grid range in the viewing area. const bool isReflectPass = state->isReflectPass(); const F32 cullScale = isReflectPass ? mReflectionLodScalar : 1.0f; // If we need to update our cached // zone state then do it now. if ( mZoningDirty ) { mZoningDirty = false; Vector<ForestCell*> cells; mData->getCells( &cells ); for ( U32 i=0; i < cells.size(); i++ ) cells[i]->_updateZoning( getSceneManager()->getZoneManager() ); } // TODO: Move these into the TSForestItemData as something we // setup once and don't do per-instance. // Set up the TS render state. TSRenderState rdata; rdata.setSceneState( state ); // Use origin sort on all forest elements as // its alot cheaper than the bounds sort. rdata.setOriginSort( true ); // We may have some forward lit materials in // the forest, so pass down a LightQuery for it. LightQuery lightQuery; rdata.setLightQuery( &lightQuery ); Frustum culler = state->getFrustum(); // Adjust the far distance if the cull scale has changed. if ( !mIsEqual( cullScale, 1.0f ) ) { const F32 visFarDist = culler.getFarDist() * cullScale; culler.setFarDist( visFarDist ); } Box3F worldBox; // Used for debug drawing. GFXDrawUtil* drawer = GFX->getDrawUtil(); drawer->clearBitmapModulation(); // Go thru the visible cells. const Box3F &cullerBounds = culler.getBounds(); const Point3F &camPos = state->getDiffuseCameraPosition(); U32 clipMask; smAverageItemsPerCell = 0.0f; U32 cellsProcessed = 0; ForestCell *cell; // First get all the top level cells which // intersect the frustum. Vector<ForestCell*> cellStack; mData->getCells( culler, &cellStack ); // Get the culling zone state. const BitVector &zoneState = state->getCullingState().getZoneVisibilityFlags(); // Now loop till we run out of cells. while ( !cellStack.empty() ) { // Pop off the next cell. cell = cellStack.last(); cellStack.pop_back(); const Box3F &cellBounds = cell->getBounds(); // If the cell is empty or its bounds is outside the frustum // bounds then we have nothing nothing more to do. if ( cell->isEmpty() || !cullerBounds.isOverlapped( cellBounds ) ) continue; // Can we cull this cell entirely? clipMask = culler.testPlanes( cellBounds, Frustum::PlaneMaskAll ); if ( clipMask == -1 ) continue; // Test cell visibility for interior zones. const bool visibleInside = !cell->getZoneOverlap().empty() ? zoneState.testAny( cell->getZoneOverlap() ) : false; // Test cell visibility for outdoor zone, but only // if we need to. bool visibleOutside = false; if( !cell->mIsInteriorOnly && !visibleInside ) { U32 outdoorZone = SceneZoneSpaceManager::RootZoneId; visibleOutside = !state->getCullingState().isCulled( cellBounds, &outdoorZone, 1 ); } // Skip cell if neither visible indoors nor outdoors. if( !visibleInside && !visibleOutside ) continue; // Update the stats. smAverageItemsPerCell += cell->getItems().size(); ++cellsProcessed; //if ( cell->isLeaf() ) //++leafCellsProcessed; // Get the distance from the camera to the cell bounds. F32 dist = cellBounds.getDistanceToPoint( camPos ); // If the largest item in the cell can be billboarded // at the cell distance to the camera... then the whole // cell can be billboarded. // if ( smForceImposters || ( dist > 0.0f && cell->getLargestItem().canBillboard( state, dist ) ) ) { // If imposters are disabled then skip out. if ( smDisableImposters ) continue; PROFILE_SCOPE(Forest_RenderBatches); // Keep track of how many cells were batched. ++smCellsBatched; // Ok... everything in this cell should be batched. First // create the batches if we don't have any. if ( !cell->hasBatches() ) cell->buildBatches(); //if ( drawCells ) //mCellRenderFlag[ cellIter - theCells.begin() ] = 1; // TODO: Light queries for batches? // Now render the batches... we pass the culler if the // cell wasn't fully visible so that each batch can be culled. smCellItemsBatched += cell->renderBatches( state, clipMask != 0 ? &culler : NULL ); continue; } // If this isn't a leaf then recurse. if ( !cell->isLeaf() ) { cell->getChildren( &cellStack ); continue; } // This cell has mixed billboards and mesh based items. ++smCellsRendered; PROFILE_SCOPE(Forest_RenderItems); //if ( drawCells ) //mCellRenderFlag[ cellIter - theCells.begin() ] = 2; // Use the cell bounds as the light query volume. // // This means all forward lit items in this cell will // get the same lights, but it performs much better. lightQuery.init( cellBounds ); // This cell is visible... have it render its items. smCellItemsRendered += cell->render( &rdata, clipMask != 0 ? &culler : NULL ); } // Keep track of the average items per cell. if ( cellsProcessed > 0 ) smAverageItemsPerCell /= (F32)cellsProcessed; // Got debug drawing to do? if ( smDrawCells && state->isDiffusePass() ) { ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>(); ri->renderDelegate.bind( this, &Forest::_renderCellBounds ); ri->type = RenderPassManager::RIT_Editor; state->getRenderPass()->addInst( ri ); } }
void ViewWindow::onIdle(const float delta) { if (NULL == getRenderContex()) { return; } // if (!getRenderContex()->isInitialized()) { getRenderContex()->setWaitForVBL(false); int index = 0; bool pf = false; for (int i = 0; i != getRenderContex()->getDevicesNumber(); ++i) { DeviceInfo di = getRenderContex()->getDeviceInfo(i); std::string dp(di.identifier_.Description); if (dp.find("PerfHUD") != std::string::npos) { index = i; pf = true; break; } } getRenderContex()->createDevice(m_hWnd, index, 0, true, true, Vector2::Zero); getGlobal()->create(); camera_.setSpeed(5.0f); Vector3 minBound = -Vector3( 100.5f, 0.f, 100.5f ); Vector3 maxBound = Vector3(10000, 5000.0f, 10000.0f); camera_.limit_ = BoundingBox( minBound, maxBound ); camera_.create(30, MATH_PI*0.75f, MATH_PI_Half*0.5f); // Camera c = getRenderContex()->getCamera(); c.setFarPlane(10000.0f); getRenderContex()->setCamera(c); getRenderContex()->updateProjectionMatrix(); getSceneManager()->setRunType(eRunType_Editor); getSceneManager()->setAllChunksVisible(true); // { font_ = FontManager::getPointer()->createFont(std::string("freetype\\LuYaHeiMb.TTF"), 18, eFontProperty_Normal, "freeNormal"); } } // camera_.update(delta, 0.0f); getSceneManager()->update(delta); { getGlobal()->update(delta); } // getRenderContex()->setViewMatrix(camera_.view_); // u32 clearFlags = D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER; if ( getRenderContex()->isStencilAvailable() ) clearFlags |= D3DCLEAR_STENCIL; static Vector4 scc(0.5f,0.5f,0.5f, 0.5f); getRenderContex()->getDxDevice()->Clear( 0, NULL, clearFlags, scc.getARGB(), 1, 0 ); getRenderContex()->beginScene(); //plane renderPlane(); //axis renderAxisXYZ(); // if (getSceneManager()) { getSceneManager()->render(); getGlobal()->render(); } //屏幕字,最后画 { std::ostringstream ss; ss<<"FPS = "<<_fps; font_->render(Vector2(10, 10), Vector4(1, 0, 0, 1), ss.str()); } font_->render(); getRenderContex()->endScene(); getRenderContex()->present(); }
void JumpTape::onInitialize() { auto scene = addScene(new dt::Scene("JumpTape_scene")); OgreProcedural::Root::getInstance()->sceneManager = scene->getSceneManager(); dt::ResourceManager::get()->addResourceLocation("", "FileSystem", true); Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); Ogre::FontManager::getSingleton().load("DejaVuSans", "General"); auto camnode = scene->addChildNode(new dt::Node("camnode")); camnode->setPosition(Ogre::Vector3(0, 0, 40)); camnode->addComponent(new dt::CameraComponent("cam"))->lookAt(Ogre::Vector3(0, 0, 0)); auto background = scene->addChildNode(new dt::Node("background")); background->setPosition(Ogre::Vector3(0, 0, -1)); auto background_billboard = background->addComponent( new dt::BillboardSetComponent( "background_billboard", 1, "jumptape-background.jpg")); background_billboard->getOgreBillboardSet()->setDefaultDimensions(50, 34); mField = scene->addChildNode(new dt::Node("field_node")); mField->setPosition(Ogre::Vector3(0, 0, 0)); auto billboard = mField->addComponent(new dt::BillboardSetComponent("tiles", TILES)); billboard->setTextureFromFile("jumptape-tiles.png"); mTiles = billboard->getOgreBillboardSet(); mTiles->setTextureStacksAndSlices(1, 2); mTiles->setDefaultDimensions(TILE_X, TILE_Y); mTiles->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY); // Always visible for(uint8_t i=0; i<TILES; ++i) { // Consecutive blank tiles, must be under MAX_BLANK_TILE, // otherwise the player can't reach the other tile. bool blank; if(i<5) { // Plain start. blank = false; } else { blank = _GetTileType(); } mTiles->setBillboardOrigin(Ogre::BBO_CENTER); Ogre::Billboard* tile = mTiles->createBillboard((-GAME_WITDH/2)+(TILE_X*i), 0, 0); tile->setTexcoordIndex(blank); } auto player = scene->addChildNode(new dt::Node("player")); player->setPosition(Ogre::Vector3(0, 0, 0)); auto billboard_component = player->addComponent(new dt::BillboardSetComponent("player", 1, "jumptape-jumper.png")); Ogre::BillboardSet* player_billboard = billboard_component->getOgreBillboardSet(); player_billboard->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY); player_billboard->setTextureStacksAndSlices(1, 12); player_billboard->setDefaultDimensions(2, 2); mPlayer = player_billboard->getBillboard(0); mPlayer->setPosition(mTiles->getBillboard(2)->getPosition().x-1.6, // Match edges of image. mTiles->getBillboard(2)->getPosition().y+9, 0); auto info_node = scene->addChildNode(new dt::Node("info")); info_node->setPosition(Ogre::Vector3(0, (-GAME_HEIGHT/2)+5, 2)); mGameInfo = info_node->addComponent(new dt::TextComponent("")); mGameInfo->setFont("DejaVuSans"); mGameInfo->setFontSize(20); mGameInfo->setColor(Ogre::ColourValue::White); }
//------------------------------------------------------------------------------ void PlayScene::update() { World& world = getSceneManager().getWorld(); Real speed = 2000.0f; // Lock orientation mActor.setGlobalOrientation(vmQuat(0.0f, 0.0f, 0.0f, 1.0f)); if (mInput.getKeyboard()->isKeyDown(OIS::KC_UP)) { mActor.getPxActor()->addForce(PxVec3(0.0f, 0.0f , speed)); } else if (mInput.getKeyboard()->isKeyDown(OIS::KC_DOWN)) { mActor.getPxActor()->addForce(PxVec3(0.0f, 0.0f , -speed)); } if (mInput.getKeyboard()->isKeyDown(OIS::KC_LEFT)) { mActor.getPxActor()->addForce(PxVec3(-speed, 0.0f , 0.0f)); } else if (mInput.getKeyboard()->isKeyDown(OIS::KC_RIGHT)) { mActor.getPxActor()->addForce(PxVec3(speed, 0.0f , 0.0f)); } if (mInput.getKeyboard()->isKeyDown(OIS::KC_SPACE)) { mActor.getPxActor()->addForce(PxVec3(0.0f, speed / 2, 0.0f)); } if (mInput.getKeyboard()->isKeyDown(OIS::KC_H)) { mActor.setGlobalPosition(vmVector3(-3.0f, 0.0, 0.0f)); mActor.getPxActor()->setLinearVelocity(PxVec3(0)); } // TODO: Day/night cycle vmVector3 centre = vmVector3(0.0f, 0.0f, 0.0f); vmVector3 point = vmVector3(10.0f, 0.0f, 0.0f); vmVector3 axis = vmVector3(0.0f, 1.0f, 0.0f); //mAngle += 0.1f; Real mAngle = 45.0f; vmVector3 pos = centre - point; Real cosTheta = cos(mAngle * D3DX_PI / Real(180.0)); Real sinTheta = sin(mAngle * D3DX_PI / Real(180.0)); vmVector3 newPos; // Find the new x position for the new rotated point. newPos.setX((cosTheta + (1 - cosTheta) * axis.getX() * axis.getX()) * pos.getX()); newPos.setX(newPos.getX() + ((1 - cosTheta) * axis.getX() * axis.getY() - axis.getZ() * sinTheta) * pos.getY()); newPos.setX(newPos.getX() + ((1 - cosTheta) * axis.getX() * axis.getZ() + axis.getY() * sinTheta) * pos.getZ()); // Find the new y position for the new rotated point. newPos.setY(((1 - cosTheta) * axis.getX() * axis.getY() + axis.getZ() * sinTheta) * pos.getX()); newPos.setY(newPos.getY() + (cosTheta + (1 - cosTheta) * axis.getY() * axis.getY()) * pos.getY()); newPos.setY(newPos.getY() + ((1 - cosTheta) * axis.getY() * axis.getZ() - axis.getX() * sinTheta) * pos.getZ()); // Find the new z position for the new rotated point. newPos.setZ(((1 - cosTheta) * axis.getZ() * axis.getZ() - axis.getY() * sinTheta) * pos.getX()); newPos.setZ(newPos.getZ() + ((1 - cosTheta) * axis.getY() * axis.getZ() + axis.getX() * sinTheta) * pos.getY()); newPos.setZ(newPos.getZ() + (cosTheta + (1 - cosTheta) * axis.getZ() * axis.getZ()) * pos.getZ()); //world.getEntity(1).getComponent<Transform>()->position = newPos + point; //world.getEntity(1).getComponent<Light>()->direction = normalize(centre - world.getEntity(1).getComponent<Transform>()->position); // Camera translation float moveSpeed = 0.1f; if (mInput.getKeyboard()->isKeyDown(OIS::KC_A)) { world.getSystemManager().getSystem<CameraSystem>()->moveRight(world.getEntity(0), -(moveSpeed / 2)); } else if (mInput.getKeyboard()->isKeyDown(OIS::KC_D)) { world.getSystemManager().getSystem<CameraSystem>()->moveRight(world.getEntity(0), (moveSpeed / 2)); } if (mInput.getKeyboard()->isKeyDown(OIS::KC_S)) { world.getSystemManager().getSystem<CameraSystem>()->moveForward(world.getEntity(0), -moveSpeed); } else if (mInput.getKeyboard()->isKeyDown(OIS::KC_W)) { world.getSystemManager().getSystem<CameraSystem>()->moveForward(world.getEntity(0), moveSpeed); } else if (mInput.getKeyboard()->isKeyDown(OIS::KC_R)) { world.getEntity(1).getComponent<Light>()->direction += vmVector3(0.0f, 0.001f, 0.0f); } else if (mInput.getKeyboard()->isKeyDown(OIS::KC_E)) { world.getEntity(1).getComponent<Light>()->direction += vmVector3(0.0f, -0.001f, 0.0f); } }
void TerrainHeightState::update() { if (getSceneManager() && getSceneManager()->getTerrain() && SculptorDecal_) { Vector2 pp = getSceneManager()->getPickingPoint(); SculptorDecal_->setCenter(Vector4(pp.x, 0, pp.y, 1)); } if (isKeyDown(VK_LBUTTON)) { if (getSceneManager() && getSceneManager()->getTerrain()) { Terrain* t = getSceneManager()->getTerrain(); Vector4 center = SculptorDecal_->getCenter(); LOD* d = getSceneManager()->getLOD(); int n = d->getVerticesNumberOneSide(); float radius = SculptorDecal_->getRadius(); RectangleT rc; rc.left_ = center.x - radius; rc.right_ = center.x + radius; rc.bottom_ = center.z - radius; rc.top_ = center.z + radius; ChunkVec cs; getSceneManager()->getChunks(cs, getSceneManager()->getTerrainQuadTreeRoot(), rc); float radius2 = radius * radius; bool dirty = false; for (size_t i = 0; i != cs.size(); ++i) { Chunk* c0 = cs[i]; c0->setSelected(true); for (int x = 0; x != n; ++x) for (int z = 0; z != n; ++z) { Vector2 p = c0->getWorldCoordination(x, z); float distance2 = (p.x - center.x)*(p.x - center.x) + (p.y - center.z)*(p.y - center.z); if (distance2 <= radius2) { dirty = true; float h = 0; if (getGlobal()->isSmoothAverage()) { float left = c0->getHeightFromTopology(x - 1, z); float right = c0->getHeightFromTopology(x + 1, z); float bottom = c0->getHeightFromTopology(x, z - 1); float top = c0->getHeightFromTopology(x, z + 1); h = (c0->getHeightFromTopology(x, z) + left + right + bottom + top) / 5; // } else { if (getGlobal()->isAbosoluteHeight()) { h = getGlobal()->getAbsoluteHeight(); } else { float r = cos(MATH_PI_Half * distance2/radius2); r = 1 - distance2/radius2; h = c0->getHeightFromTopology(x, z) + r * getSculptorStrength(); } // if(0){ float left = c0->getHeightFromTopology(x - 1, z); float right = c0->getHeightFromTopology(x + 1, z); float bottom = c0->getHeightFromTopology(x, z - 1); float top = c0->getHeightFromTopology(x, z + 1); h = (h + left + right + bottom + top) / 5; } } // if (h > 255) { h = 255; } // c0->setHeightFromTopology(x, z, h); } } // c0->refreshHeight(); } if (dirty) { QuadNode::calculateBoundingBox(getSceneManager()->getTerrainQuadTreeRoot()); } } } }
void DemoKeeper::destroyEntities() { #ifdef MYGUI_OGRE_PLATFORM getSceneManager()->destroyQuery(gRaySceneQuery); #endif }
Ogre::Camera* SceneObject::getCamera() const { return getSceneManager()->getCamera(mCamera); }