void SWGameScene::draw() { static tarray<tuint> proxyIDs; for ( SWObject::Array::iterator itor = m_renderers.begin() ; itor != m_renderers.end() ; ++itor) { taabb3d aabb; SWRenderer* renderer = (SWRenderer*)((*itor)()); renderer->computeAABB(aabb); m_rendererTree.updateProxy(renderer->getProxyID(), aabb); } /* */ m_cameras.sort( CameraSorter() ); SWObject::List::iterator itor = m_cameras.begin(); for ( ; itor != m_cameras.end() ; ++itor ) { SWCamera* camera = swrtti_cast<SWCamera>( (*itor)() ); tflag32 cullingMask = camera->getCullingMask(); //! get clear mask int clearMask = GL_NONE; int clearFlags = camera->getClearFlags(); if ( clearFlags & SW_Clear_Color ) clearMask |= GL_COLOR_BUFFER_BIT; if ( clearFlags & SW_Clear_Depth ) clearMask |= GL_DEPTH_BUFFER_BIT; //! clear buffer if ( clearMask != GL_NONE ) { tcolor color = camera->getClearColor(); glClearColor( color.r, color.g, color.b, color.a ); glClearDepth( camera->getClearDepth() ); glClear( clearMask ); } taabb3d frustrumAABB; camera->computeFrustrumAABB(frustrumAABB); m_rendererTree.query(proxyIDs, frustrumAABB); for (int i = 0 ; i <proxyIDs.size() ; ++i) { tuint proxyID = proxyIDs[i]; SWRenderer* renderer = (SWRenderer*)m_rendererTree.getUserData(proxyID); tuint layerMask = renderer->gameObject()->getLayer(); if (cullingMask.get(layerMask)) renderer->render(camera); } } onPostDraw(); }
void SWPolygonShape2D::set( const tarray<tvec2>& vertices ) { if ( vertices.size() <= 2 ) return; tuint count = vertices.size(); m_normals.resize( count ); m_vertices.resize( count ); for ( tuint i = 0 ; i < vertices.size() ; ++i ) { tuint i1 = i; tuint i2 = ((i+1)%count); const tvec2& v1 = vertices.at( i1 ); const tvec2& v2 = vertices.at( i2 ); tvec2 edge = v2 - v1; m_vertices[i] = v1; m_normals[i] = edge.cross( 1 ).normal(); } computeLocalOBB( m_localOBB ); }
int PreprocessOccluders(const tmatrix &invCameraMat) { if (!GetInstancesCount(ZOccluderBox)) return 0; PROFILER_START(PreprocessOccluders); tvector3 campos = invCameraMat.V4.position; tvector3 camdir = invCameraMat.V4.dir; FActiveOccluder* pActiveOccluder = &gActiveOccluders[0]; tvector4 viewPoint = vector4(campos.x, campos.y, campos.z, 0); tvector4 viewDir = vector4(camdir.x, camdir.y, camdir.z, 0); float sqrFar = 1000.0f * 1000.0f; float sqrDist; int i; gNbActiveOccluders = 0; gOccluderBoxes.clear(); ZOccluderBox *pocc = (ZOccluderBox*)FirstInstanceOf(ZOccluderBox); while (pocc) { addDynamicOccluder(pocc->GetTransform()); pocc = (ZOccluderBox*)NI(pocc); } for (unsigned int ju = 0;ju<gOccluderBoxes.size(); ju++) { // todo : frustum culling of the occluder (except far plane) // todo : compute solid angle to reorder occluder accordingly FOccluderBox *obox = &gOccluderBoxes[ju]; //= oboxiter.Get(); // check for far plane const tvector3 &oboxcenter = obox->mCenter;//pocc->GetTransform()->GetWorldMatrix().position; sqrDist= SquaredDistance(viewPoint, oboxcenter); if (sqrDist > sqrFar) { continue; } // check for near plane if (DotProduct(tvector3(viewDir), tvector3(oboxcenter - viewPoint)) < 0.0f) { continue; } // select planes of the occluder box that lies on the viewing direction // todo : reduce to 3 planes instead of 6 (due to box symetry) float invSqrDist = 1.0f/sqrDist;//Rcp(sqrDist); pActiveOccluder->mSolidAngle = 0.0f; BoxSilhouette silhouette; silhouette.vertices = &obox->mVertex[0]; for (i=0; i<6; i++) { tvector4 dir= obox->mVertex[FaceVertexIndex[i][0]]; dir -= viewPoint; float vdotp = silhouette.dots[i] = DotProduct(obox->mPlanes[i], dir); // compute the maximum solidAngle of the box : -area * v.p/d.d pActiveOccluder->mSolidAngle = Max(-obox->mVertex[i].w * vdotp * invSqrDist, pActiveOccluder->mSolidAngle); } // exit if the occluder is not relevant enough if (pActiveOccluder->mSolidAngle < gMinSolidAngle) continue; int nPlanes = 0; tvector4* pPlanes = &pActiveOccluder->mPlanes[0]; // find silhouette tvector4 vertices[12]; int nVertices = silhouette.findSilhouette(vertices); // create a plane with a edge of the occluder and the viewpoint for (i=0; i<nVertices; i+=2) { //tplane plan(campos, vertices[i], vertices[i+1]); tvector3 v1 = vertices[i]; v1 -= viewPoint; tvector3 v2 = vertices[i+1]; v2 -= viewPoint; v1.Normalize(); v2.Normalize(); *pPlanes = CrossProduct(v1, v2); pPlanes->Normalize(); pPlanes->w = - DotProduct(*pPlanes, vertices[i]); pPlanes++; nPlanes ++; } if (gAddNearPlane) { for (int i=0; i<6; i++) { if (silhouette.dots[i] < 0.0f) { pActiveOccluder->mPlanes[nPlanes] = obox->mPlanes[i]; nPlanes++; } } } pActiveOccluder->mNbPlanes = nPlanes; pActiveOccluder++; gNbActiveOccluders++; if (gNbActiveOccluders >= gMaxCandidateOccluders) break; } if (gNbActiveOccluders) { qsort(gActiveOccluders, gNbActiveOccluders, sizeof(FActiveOccluder), compareOccluder); if (gNbActiveOccluders > gMaxActiveOccluders) gNbActiveOccluders = gMaxActiveOccluders; } PROFILER_END(); return gNbActiveOccluders; }