예제 #1
0
void SWDynamicTree2D::query( tarray<tuint>& result, const taabb2d& aabb ) const
{
	result.clear();

	tlist<tuint> suspects;
	suspects.push_back( m_rootID );

	while ( suspects.size() > 0 )
	{
		tuint nodeID = suspects.front();
		suspects.pop_front();

		if ( nodeID == nullID ) continue;

		const TreeNode& node = m_nodes[ nodeID ];
		if ( node.aabb.collide( aabb ) )
		{
			if ( node.isLeaf() )
			{
				result.push_back( nodeID );
			}
			else
			{
				suspects.push_back( node.childID[0] );
				suspects.push_back( node.childID[1] );
			}
		}
	}
}
예제 #2
0
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();
}
예제 #3
0
void addDynamicOccluder(ZTransform* aTransform) 
{
	int i;

	FOccluderBox	obox;
    tvector3		extend(1,1,1);
	const tmatrix& boxmat = aTransform->GetWorldMatrix();

	for (i=0; i<8; i++)
	{
        tvector3 bvt(BoxCorners[i].x, BoxCorners[i].y, BoxCorners[i].z),bvt2;
		bvt2.TransformPoint((bvt*extend), boxmat);
        obox.mVertex[i] = vector4(bvt2.x, bvt2.y, bvt2.z, 0);
	}

	for (i=0; i<6; i++)
	{
		tvector3 cross = obox.mVertex[FaceVertexIndex[i][1]];
		cross -= obox.mVertex[FaceVertexIndex[i][0]];
		tvector3 cr2 = obox.mVertex[FaceVertexIndex[i][2]];
		cr2 -= obox.mVertex[FaceVertexIndex[i][0]];

        cross.Cross(cr2);
		obox.mPlanes[i] = vector4(cross.x, cross.y, cross.z, 0);
        obox.mPlanes[i].Normalize();
		obox.mPlanes[i].w = -DotProduct(obox.mPlanes[i], obox.mVertex[FaceVertexIndex[i][0]]);
		obox.mVertex[i].w = fabs(obox.mPlanes[i].Dot( cross));		// save area in vertex w component
	}
    obox.mCenter = vector4(boxmat.m16[12], boxmat.m16[13], boxmat.m16[14], 0);
	obox.mCenter.w = Distance(obox.mCenter, obox.mVertex[0]);
	gOccluderBoxes.push_back(obox);

}
예제 #4
0
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 );
}
예제 #5
0
inline T RayTesselatedTimeSampledTrianglePrimitive::_InterpolateFaceAttrib(float time, const tarray<T>& f) {
    return f.interpolate(idx, time);
}
예제 #6
0
inline void RayTesselatedTimeSampledTrianglePrimitive::_InterpolateVertexAttrib(T& v0, T& v1, T& v2, float time, const tarray<T>& v) {
    v0 = v.interpolate(triangles->triangles[idx][0], time);
    v1 = v.interpolate(triangles->triangles[idx][1], time);
    v2 = v.interpolate(triangles->triangles[idx][2], time);
}
예제 #7
0
inline void RayTesselatedTimeSampledTrianglePrimitive::_ResolveVertexAttrib(T& v0, T& v1, T& v2, int timeIdx, const tarray<T>& v) {
    v0 = v.at(triangles->triangles[idx][0], timeIdx);
    v1 = v.at(triangles->triangles[idx][1], timeIdx);
    v2 = v.at(triangles->triangles[idx][2], timeIdx);
}
예제 #8
0
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;
}