Beispiel #1
0
// ------------------------------------------------------------------------------------------------
// Build a hexahedron with points.magnitude == 1
unsigned int StandardShapes::MakeHexahedron(std::vector<aiVector3D>& positions,
	bool polygons /*= false*/)
{
	positions.reserve(positions.size()+36);
	const float length = 1.f/1.73205080f;

	const aiVector3D v0  = aiVector3D(-1.f,-1.f,-1.f)*length;
	const aiVector3D v1  = aiVector3D(1.f,-1.f,-1.f)*length;
	const aiVector3D v2  = aiVector3D(1.f,1.f,-1.f)*length;
	const aiVector3D v3  = aiVector3D(-1.f,1.f,-1.f)*length;
	const aiVector3D v4  = aiVector3D(-1.f,-1.f,1.f)*length;
	const aiVector3D v5  = aiVector3D(1.f,-1.f,1.f)*length;
	const aiVector3D v6  = aiVector3D(1.f,1.f,1.f)*length;
	const aiVector3D v7  = aiVector3D(-1.f,1.f,1.f)*length;

	ADD_QUAD(v0,v3,v2,v1);
	ADD_QUAD(v0,v1,v5,v4);
	ADD_QUAD(v0,v4,v7,v3);
	ADD_QUAD(v6,v5,v1,v2);
	ADD_QUAD(v6,v2,v3,v7);
	ADD_QUAD(v6,v7,v4,v5);
	return (polygons ? 4 : 3);
}
Beispiel #2
0
RES Camera::_get_gizmo_geometry() const {


	Ref<SurfaceTool> surface_tool( memnew( SurfaceTool ));

	Ref<FixedMaterial> mat( memnew( FixedMaterial ));

	mat->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(1.0,0.5,1.0,0.5) );
	mat->set_line_width(4);
	mat->set_flag(Material::FLAG_DOUBLE_SIDED,true);
	mat->set_flag(Material::FLAG_UNSHADED,true);
	//mat->set_hint(Material::HINT_NO_DEPTH_DRAW,true);

	surface_tool->begin(Mesh::PRIMITIVE_LINES);
	surface_tool->set_material(mat);

	switch(mode) {

		case PROJECTION_PERSPECTIVE: {



			Vector3 side=Vector3( Math::sin(Math::deg2rad(fov)), 0, -Math::cos(Math::deg2rad(fov)) );
			Vector3 nside=side;
			nside.x=-nside.x;
			Vector3 up=Vector3(0,side.x,0);


#define ADD_TRIANGLE( m_a, m_b, m_c)\
{\
	surface_tool->add_vertex(m_a);\
	surface_tool->add_vertex(m_b);\
	surface_tool->add_vertex(m_b);\
	surface_tool->add_vertex(m_c);\
	surface_tool->add_vertex(m_c);\
	surface_tool->add_vertex(m_a);\
}

			ADD_TRIANGLE( Vector3(), side+up, side-up );
			ADD_TRIANGLE( Vector3(), nside+up, nside-up );
			ADD_TRIANGLE( Vector3(), side+up, nside+up );
			ADD_TRIANGLE( Vector3(), side-up, nside-up );

			side.x*=0.25;
			nside.x*=0.25;
			Vector3 tup( 0, up.y*3/2,side.z);
			ADD_TRIANGLE( tup, side+up, nside+up );

		} break;
		case PROJECTION_ORTHOGONAL: {

#define ADD_QUAD( m_a, m_b, m_c, m_d)\
{\
	surface_tool->add_vertex(m_a);\
	surface_tool->add_vertex(m_b);\
	surface_tool->add_vertex(m_b);\
	surface_tool->add_vertex(m_c);\
	surface_tool->add_vertex(m_c);\
	surface_tool->add_vertex(m_d);\
	surface_tool->add_vertex(m_d);\
	surface_tool->add_vertex(m_a);\
}

			float hsize=size*0.5;
			Vector3 right(hsize,0,0);
			Vector3 up(0,hsize,0);
			Vector3 back(0,0,-1.0);
			Vector3 front(0,0,0);

			ADD_QUAD( -up-right,-up+right,up+right,up-right);
			ADD_QUAD( -up-right+back,-up+right+back,up+right+back,up-right+back);
			ADD_QUAD( up+right,up+right+back,up-right+back,up-right);
			ADD_QUAD( -up+right,-up+right+back,-up-right+back,-up-right);

			right.x*=0.25;
			Vector3 tup( 0, up.y*3/2,back.z );
			ADD_TRIANGLE( tup, right+up+back, -right+up+back );

		} break;

	}

	return surface_tool->commit();

}
void
addWindowGeometry (CompWindow *w,
		   CompMatrix *matrix,
		   int	      nMatrix,
		   Region     region,
		   Region     clip)
{
    BoxRec full;

    w->texUnits = nMatrix;

    full = clip->extents;
    if (region->extents.x1 > full.x1)
	full.x1 = region->extents.x1;
    if (region->extents.y1 > full.y1)
	full.y1 = region->extents.y1;
    if (region->extents.x2 < full.x2)
	full.x2 = region->extents.x2;
    if (region->extents.y2 < full.y2)
	full.y2 = region->extents.y2;

    if (full.x1 < full.x2 && full.y1 < full.y2)
    {
	BoxPtr  pBox;
	int     nBox;
	BoxPtr  pClip;
	int     nClip;
	BoxRec  cbox;
	int     vSize;
	int     n, it, x1, y1, x2, y2;
	GLfloat *d;
	Bool    rect = TRUE;

	for (it = 0; it < nMatrix; it++)
	{
	    if (matrix[it].xy != 0.0f || matrix[it].yx != 0.0f)
	    {
		rect = FALSE;
		break;
	    }
	}

	pBox = region->rects;
	nBox = region->numRects;

	vSize = 3 + nMatrix * 2;

	n = w->vCount / 4;

	if ((n + nBox) * vSize * 4 > w->vertexSize)
	{
	    if (!moreWindowVertices (w, (n + nBox) * vSize * 4))
		return;
	}

	d = w->vertices + (w->vCount * vSize);

	while (nBox--)
	{
	    x1 = pBox->x1;
	    y1 = pBox->y1;
	    x2 = pBox->x2;
	    y2 = pBox->y2;

	    pBox++;

	    if (x1 < full.x1)
		x1 = full.x1;
	    if (y1 < full.y1)
		y1 = full.y1;
	    if (x2 > full.x2)
		x2 = full.x2;
	    if (y2 > full.y2)
		y2 = full.y2;

	    if (x1 < x2 && y1 < y2)
	    {
		nClip = clip->numRects;

		if (nClip == 1)
		{
		    if (rect)
		    {
			ADD_RECT (d, matrix, nMatrix, x1, y1, x2, y2);
		    }
		    else
		    {
			ADD_QUAD (d, matrix, nMatrix, x1, y1, x2, y2);
		    }

		    n++;
		}
		else
		{
		    pClip = clip->rects;

		    if (((n + nClip) * vSize * 4) > w->vertexSize)
		    {
			if (!moreWindowVertices (w, (n + nClip) * vSize * 4))
			    return;

			d = w->vertices + (n * vSize * 4);
		    }

		    while (nClip--)
		    {
			cbox = *pClip;

			pClip++;

			if (cbox.x1 < x1)
			    cbox.x1 = x1;
			if (cbox.y1 < y1)
			    cbox.y1 = y1;
			if (cbox.x2 > x2)
			    cbox.x2 = x2;
			if (cbox.y2 > y2)
			    cbox.y2 = y2;

			if (cbox.x1 < cbox.x2 && cbox.y1 < cbox.y2)
			{
			    if (rect)
			    {
				ADD_RECT (d, matrix, nMatrix,
					  cbox.x1, cbox.y1, cbox.x2, cbox.y2);
			    }
			    else
			    {
				ADD_QUAD (d, matrix, nMatrix,
					  cbox.x1, cbox.y1, cbox.x2, cbox.y2);
			    }

			    n++;
			}
		    }
		}
	    }
	}

	w->vCount	      = n * 4;
	w->vertexStride       = vSize;
	w->texCoordSize       = 2;
	w->drawWindowGeometry = drawWindowGeometry;
    }
}
void rIndexedShadowVolume_c::addDirectionalIndexedVertexList( const rIndexBuffer_c& oIndices, const rVertexBuffer_c& oVerts, const vec3_c& lightDir, const class planeArray_c* extraPlanesArray, float lightInfinity, const class aabb* bounds )
{
#if 1
	// for a single triangle, in worst case we might need to create:
	// front cap + end cap + 3 edge quads
	// 1 + 1 + 3 * 2 = 2 + 6 = 8 triangles
	indices.ensureAllocated_indices( indices.getNumIndices() + oIndices.getNumTriangles() * 8 * 3 );
	points.ensureAllocated( points.size() + oVerts.size() * 2 );
#endif
#ifdef OPTIMIZE_SLOW_ADDTRIANGLE
	if ( indices.getU16Ptr() == 0 )
		return;
	u16* pFirstIndex = ( ( u16* )indices.getU16Ptr() ) + indices.getNumIndices();
	u16* pNextIndex = pFirstIndex;
#endif
	vec3_c delta = lightDir * lightInfinity;
	//if(rf_ssv_algorithm.getInt() == 0) {
	//  for(u32 i = 0; i < oIndices.getNumIndices(); i+=3){
	//      u32 i0 = oIndices[i+0];
	//      u32 i1 = oIndices[i+1];
	//      u32 i2 = oIndices[i+2];
	//      const vec3_c &v0 = oVerts[i0].xyz;
	//      const vec3_c &v1 = oVerts[i1].xyz;
	//      const vec3_c &v2 = oVerts[i2].xyz;
	//      addTriangle(v0,v1,v2,light);
	//  }
	//} else
	{
		//bool bMeshFullyInsideLight;
		//if(bounds) {
		//  bMeshFullyInsideLight = IsAABBInsideSphere(*bounds,light,lightRadius);
		//} else {
		//  bMeshFullyInsideLight = false;
		//}
		// do the same thing as above, but a little faster way
		static arraySTD_c<byte> bPointTransformed;
		if ( bPointTransformed.size() < oVerts.size() )
		{
			bPointTransformed.resize( oVerts.size() );
		}
		bPointTransformed.nullMemory();
		static arraySTD_c<vec3_c> pointsTransformed;
		if ( pointsTransformed.size() < oVerts.size() )
		{
			pointsTransformed.resize( oVerts.size() );
		}
		
		u32 tri = 0;
		for ( u32 i = 0; i < oIndices.getNumIndices(); i += 3, tri++ )
		{
			u32 vi0 = oIndices[i + 0];
			u32 vi1 = oIndices[i + 1];
			u32 vi2 = oIndices[i + 2];
			const vec3_c& p0 = oVerts[vi0].xyz;
			const vec3_c& p1 = oVerts[vi1].xyz;
			const vec3_c& p2 = oVerts[vi2].xyz;
			
			// cull triangles that are outside light radius
			// This is a good optimisation for very large models intersecting very small lights
			//if(rf_ssv_cullTrianglesOutSideLightSpheres.getInt()) {
			//  // we can't cull that way any triangles if mesh bounds are entirely inside light sphere
			//  if(bMeshFullyInsideLight == false) {
			//      if(CU_IntersectSphereTriangle(light,lightRadius,p0,p1,p2) == false) {
			//          continue;
			//      }
			//  }
			//}
			float d;
			if ( extraPlanesArray == 0 )
			{
				plane_c triPlane;
				triPlane.fromThreePoints( p2, p1, p0 );
				d = triPlane.norm.dotProduct( lightDir );
			}
			else
			{
				d = extraPlanesArray->getArray()[tri].norm.dotProduct( lightDir );
			}
			if ( d > 0 )
			{
				continue;
			}
			vec3_c& p0Projected = pointsTransformed[vi0];
			if ( bPointTransformed[vi0] == 0 )
			{
				bPointTransformed[vi0] = 1;
				p0Projected = p0 - delta;
			}
			vec3_c& p1Projected = pointsTransformed[vi1];
			if ( bPointTransformed[vi1] == 0 )
			{
				bPointTransformed[vi1] = 1;
				p1Projected = p1 - delta;
			}
			vec3_c& p2Projected = pointsTransformed[vi2];
			if ( bPointTransformed[vi2] == 0 )
			{
				bPointTransformed[vi2] = 1;
				p2Projected = p2 - delta;
			}
			u32 i0 = this->registerPoint( p0 );
			u32 i1 = this->registerPoint( p1 );
			u32 i2 = this->registerPoint( p2 );
			u32 pi0 = this->registerPoint( p0Projected );
			u32 pi1 = this->registerPoint( p1Projected );
			u32 pi2 = this->registerPoint( p2Projected );
#ifdef OPTIMIZE_SLOW_ADDTRIANGLE
			ADD_TRIANGLE( pNextIndex, i2, i1, i0 );
			ADD_TRIANGLE( pNextIndex, pi0, pi1, pi2 );
			ADD_QUAD( pNextIndex, i0, i1, pi0, pi1 );
			ADD_QUAD( pNextIndex, i1, i2, pi1, pi2 );
			ADD_QUAD( pNextIndex, i2, i0, pi2, pi0 );
#else
			indices.addTriangle( i2, i1, i0 );
			indices.addTriangle( pi0, pi1, pi2 );
			c_capTriPairsAdded++;
			indices.addQuad( i0, i1, pi0, pi1 );
			c_edgeQuadsAdded++;
			indices.addQuad( i1, i2, pi1, pi2 );
			c_edgeQuadsAdded++;
			indices.addQuad( i2, i0, pi2, pi0 );
			c_edgeQuadsAdded++;
#endif
		}
	}
#ifdef OPTIMIZE_SLOW_ADDTRIANGLE
	u32 numAddedIndices = pNextIndex - pFirstIndex;
	indices.forceSetIndexCount( indices.getNumIndices() + numAddedIndices );
#endif
}