// render a single node void BSPTree::RenderNode(BSP_node* node,BoundingBox box,float &boxTimes,int depth) { BSP_node* left = node->left; BSP_node* right = node->right; if (node->is_leaf){ //box.RenderGL(); return; } // getting min max Vector3 belowMax(box.Max()); Vector3 aboveMin(box.Min()); // getting split plane belowMax[node->axis] = node->plane_pos; aboveMin[node->axis] = node->plane_pos; // get bounding boxes BoundingBox below(box.Min(),belowMax); BoundingBox above(aboveMin,box.Max()); // render this split plane RenderSplitPlane(node->axis,aboveMin,belowMax); RenderNode(left,below,boxTimes,depth+1); RenderNode(right,above,boxTimes,depth+1); }
void ModelBrowserTool::SetCameraFocus() { BoundingBox boundingBox = mModel->GetBoundingBox(); Vector3f boxCenter = boundingBox.GetCenter(); // Cubify the bounding box. BoundingBox boundingCube = boundingBox; Float maxValue = Maths::Max(boundingCube.Max().x, Maths::Max(boundingCube.Max().y, boundingCube.Max().z)); Float minValue = Maths::Min(boundingCube.Min().x, Maths::Min(boundingCube.Min().y, boundingCube.Min().z)); boundingCube.SetMax( Vector3f(maxValue, maxValue, maxValue) ); boundingCube.SetMin( Vector3f(minValue, minValue, minValue) ); // Recenter Vector3f cubeCenter = boundingCube.GetCenter(); Vector3f offset = cubeCenter - boxCenter; cubeCenter -= offset; boundingCube(0) -= offset; boundingCube(1) -= offset; Float fovAngle = Maths::ToRadians(mCamera.GetFovAngle()); Float halfFov = fovAngle / 2.0f; Float sin = Maths::Sin(halfFov); Float cos = Maths::Cos(halfFov); // Compute the camera position and viewing position. Float halfPos = cubeCenter.y - boundingCube.Min().y; Float zPos = boundingBox.Max().z + (cos * halfPos / sin); mCamera.SetPosition(Vector3f(boxCenter.x, boxCenter.y, zPos)); mObjectCenter = Vector3f(boxCenter.x, boxCenter.y, boxCenter.z); }
// get the bounding box Above BoundingBox BSPTree::getAboveBoundingBox(BoundingBox box, int axis, float split_pos) { // finding min vector Vector3 aboveMin(box.Min()); // splitting positions at split plane aboveMin[axis] = split_pos; // creating the above bounding box after splitting BoundingBox above(aboveMin,box.Max()); return above; }
// get the bounding box below BoundingBox BSPTree::getBelowBoundingBox(BoundingBox box, int axis, float split_pos) { // finding max position Vector3 belowMax(box.Max()); // splitting positions at split plane belowMax[axis] = split_pos; // creating the below box after splitting BoundingBox below(box.Min(),belowMax); return below; }
// get the best cut possible for this bounding box Plane_Cut BSPTree::getBestCut(ObjectList objects, BoundingBox box) { // initialize struct Plane_Cut bestCut; bool random_cut = false; int cost_per_object = 8; int cost_per_plane = 1; // cost of the total float cost_no_split = cost_per_object * objects.size(); // get random cut if (random_cut){ bestCut.axis = std::rand()%3; float dist = (box.Max())[bestCut.axis]- (box.Min())[bestCut.axis]; bestCut.pos = (box.Min())[bestCut.axis] + dist/2; } // other wise else{ // implementing hueristics int lowestCost = std::numeric_limits<int>::max(); // if too many objects, check few splits // if (objects.size()>500){ // nSplits = 1; // } // check along all three axis for (int i=0;i<3;i++){ // generate checking positions for (int j=1;j<=nSplits;j++){ // generate splitting positions float dist = (box.Max())[i] - (box.Min())[i]; float splitPos = box.Min()[i] + (j*(1.0/(nSplits+1.0)))*dist; // find bounding boxes at these split pos BoundingBox below = getBelowBoundingBox(box,i,splitPos); BoundingBox above = getAboveBoundingBox(box,i,splitPos); // find objects in the box ObjectList objsAbove = objsInBox(objects,above); ObjectList objsBelow = objsInBox(objects,below); // find the difference int diff = std::abs( (int) (objsAbove.size()-objsBelow.size()) ); // find the probability of hitting float pBelow = below.Area()/box.Area(); float pAbove = above.Area()/box.Area(); // find the cost float cost_split = 2*cost_per_plane + pBelow * objsBelow.size() * cost_per_object + pAbove * objsAbove.size() * cost_per_object; // // if lower save if (cost_split < lowestCost){ lowestCost = cost_split; bestCut.axis = i; bestCut.pos = splitPos; // noObjsAbove = objsAbove.size(); // noObjsBelow = objsBelow.size(); } // clear both lists objsAbove.clear(); objsBelow.clear(); } } if (lowestCost >= cost_no_split){ bestCut.axis = -1; } } return bestCut; }
void World::Render() { if( !mWorldInitialized ) return; Renderer* renderer = GraphicSubsystem::Instance()->GetRenderer(); GD_ASSERT(renderer); UInt32 viewWidth = renderer->GetRenderTarget()->GetWidth(); UInt32 viewHeight = renderer->GetRenderTarget()->GetHeight(); // Init. //renderer->BeginScene( Renderer::PointList ); renderer->SetViewport( 0, 0, viewWidth, viewHeight ); renderer->SetClearColor(Color4f(0.0f, 0.0f, 0.0f, 1.0f)); renderer->SetRenderState( Renderer::Texture2D, false ); renderer->SetRenderState( Renderer::DepthTest, true ); //renderer->SetRenderState( Renderer::Lighting, true ); //renderer->SetCulling( Renderer::CullBackFace ); // Render. renderer->Clear( Renderer::ColorBuffer | Renderer::DepthBuffer ); renderer->SetMatrixMode(Renderer::ProjectionMatrix); renderer->LoadIdentity(); Camera* currentCamera = GetCurrentCamera(); renderer->Perspective(currentCamera->GetFovAngle(), viewWidth / static_cast<Float>(viewHeight), currentCamera->GetNearView(), currentCamera->GetFarView()); renderer->SetMatrixMode(Renderer::ModelViewMatrix); renderer->LoadIdentity(); currentCamera->ApplyViewMatrix(); /* Light light; light.mPosition = Vector3f( 4.32f, -3.0f, -3.4f ).Normalize(); light.mAmbient = Color4f(1.0f,1.0f, 1.0f,1.0f); light.mDiffuse = Color4f(1.0f,1.0f, 1.0f,1.0f); light.mSpecular = Color4f(1.0f,1.0f, 1.0f,1.0f); light.mType = Renderer::LightDirectional; renderer->SetRenderState( Renderer::Light_i, true, 0 ); renderer->SetLight( 0, light );*/ #if 0 Matrix4d modelView; renderer->GetModelViewMatrix( modelView ); Vector3f vRight( modelView[0], modelView[4], modelView[8] ); Vector3f vUp( modelView[1], modelView[5], modelView[9] ); Vector3f vBottomLeft = light.mPosition + (-vRight - vUp).Normalize() * 2; Vector3f vBottomRight = light.mPosition + ( vRight - vUp).Normalize() * 2; Vector3f vTopRight = light.mPosition + ( vRight + vUp).Normalize() * 2; Vector3f vTopLeft = light.mPosition + (-vRight + vUp).Normalize() * 2; /*renderer->SetRenderState( Renderer::DepthMask, false ); renderer->SetRenderState( Renderer::Lighting, false ); renderer->SetRenderState( Renderer::Blend, true ); renderer->SetBlendFunc( Renderer::BlendSrcAlpha, Renderer::BlendOne );*/ renderer->SetRenderState( Renderer::Lighting, false ); renderer->DrawQuad( vBottomLeft, vBottomRight, vTopRight, vTopLeft, false ); renderer->SetRenderState( Renderer::Lighting, true ); #endif renderer->SetAmbiantColor( Color4f(1.0f, 1.0f, 1.0f, 1.0f) ); /*Light lightPoint; lightPoint.mPosition = currentCamera->GetPosition(); lightPoint.mAmbient = Color4f(0.00f,0.00f, 0.00f,1.0f); lightPoint.mDiffuse = Color4f(1.0f,1.0f, 1.0f,1.0f); lightPoint.mSpecular = Color4f(1.0f,1.0f, 1.0f,1.0f); lightPoint.mType = Renderer::LightPoint; lightPoint.mAttenuationConstant = 0; lightPoint.mAttenuationLinear = 0; lightPoint.mAttenuationQuadratic = 0.01f; renderer->SetRenderState( Renderer::Light_i, true, 0 ); renderer->SetLight( 0, lightPoint );*/ // Get the frustum. Matrix4f modelViewMatrix; Matrix4f projectionMatrix; Frustum frustum; renderer->GetModelViewMatrix(modelViewMatrix); renderer->GetProjectionMatrix(projectionMatrix); frustum.CalculateFrustum(projectionMatrix, modelViewMatrix); mNbRenderedEntities = 0; // Render the objects in the world. /* List<Entity*> visibleEntities; mSpacePartition->Query(frustum, visibleEntities); */ List<Entity*>::const_iterator itEntity; for( itEntity = mEntities.begin(); itEntity != mEntities.end(); ++itEntity ) { if( *itEntity != currentCamera ) { // Do frustum culling. if((*itEntity)->GetClass() != Terrain::StaticClass() && (*itEntity)->GetClass() != SkyDome::StaticClass()) { BoundingBox boundingBox = (*itEntity)->GetBoundingBox(); if( (*itEntity)->GetClass() != ParticleEmitter::StaticClass() ) { Matrix4f translation = Matrix4f::Translation((*itEntity)->GetPosition()); Matrix4f rotation; (*itEntity)->GetOrientation().ToMatrix(rotation); Matrix4f trsMatrix = rotation * translation; boundingBox.SetMin( boundingBox.Min() * trsMatrix ); boundingBox.SetMax( boundingBox.Max() * trsMatrix ); } if( frustum.BoxInFrustum(boundingBox) ) { mNbRenderedEntities++; } else { continue; } } renderer->PushMatrix(); if( String((*itEntity)->GetClass()->GetName()) == "SkyDome" ) renderer->Translate(currentCamera->GetPosition()-Vector3f(0,100,0) ); else renderer->Translate((*itEntity)->GetPosition()); renderer->Rotate((*itEntity)->GetOrientation()); if( (*itEntity)->IsSelected() ) (*itEntity)->RenderSelected(); (*itEntity)->Render(); renderer->PopMatrix(); } } renderer->SetMatrixMode(Renderer::ModelViewMatrix); renderer->LoadIdentity(); currentCamera->ApplyViewMatrix(); //renderer->EndScene(); }