Esempio n. 1
0
//--------------------------------------------------------------------------
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 );
      }

}
Esempio n. 2
0
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);
}
Esempio n. 6
0
//-----------------------------------------------------------------------------------------
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);
            }
Esempio n. 7
0
	//-----------------------------------------------------------------------
	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);
        }
	}
Esempio n. 8
0
//------------------------------------------------------------------------------
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);
}
Esempio n. 9
0
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 );
   }
}
Esempio n. 10
0
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 );
   }
}
Esempio n. 11
0
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();
}
Esempio n. 12
0
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();
}
Esempio n. 13
0
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 );
    }
}
Esempio n. 14
0
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();
}
Esempio n. 15
0
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);
}
Esempio n. 16
0
//------------------------------------------------------------------------------
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);
	}
}
Esempio n. 17
0
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());
			}
		}
	}
}
Esempio n. 18
0
	void DemoKeeper::destroyEntities()
	{
#ifdef MYGUI_OGRE_PLATFORM
		getSceneManager()->destroyQuery(gRaySceneQuery);
#endif
	}
Esempio n. 19
0
	Ogre::Camera* SceneObject::getCamera() const
	{
		return getSceneManager()->getCamera(mCamera);
	}