Exemplo n.º 1
0
// Mesh the area into nodes and elements or return error message if fails
// assumes edges already oriented correctly
const char *Area::MeshElements(void)
{
	// exactly 2 paths will be for an interface
	if(numPaths==2)
		return MeshInterface();
		
	// Must be 4-sided area. In future should support more
	if(numPaths!=4)
		return "Code can only mesh quadrilateral areas (4 paths) or interfaces (2 paths).";
	
	// cannot be interface elements
	if(theElems->InterfaceElements())
		return "Areas cannot be meshed into interface elements.";
	
	// must be connected
	if(edges[numPaths-1]->LastKeypoint()!=edges[0]->FirstKeypoint())
		return "Area does not define enclosed area.";
	
	// is element provided
	if(theElems->CurrentElemID()<0)
		return "No element type defined for area.";
	
	// Check intervals
	if(!CheckIntervals())
		return "Number of intervals on sides of the area are not valid";
	
	// Check path usage
	if(!PathsAvailable())
		return "Paths cannot be meshed into more than 2 areas";
	
	// Check ccw
	if(SignedArea()<0.)
		return "The paths must circumnavigate the area in a counter-clockwise direction";
	
	// create function if being used
	if(angleExpr!=NULL)
	{	if(!CreateFunction(angleExpr))
			return "The expression for material angle is not a valid function";
	}
	
	// mesh the error
	return MeshArea();
}
void OcclusionBuffer::DrawTriangle(Vector4* vertices)
{
    unsigned clipMask = 0;
    unsigned andClipMask = 0;
    bool drawOk = false;
    Vector3 projected[3];
    
    // Build the clip plane mask for the triangle
    for (unsigned i = 0; i < 3; ++i)
    {
        unsigned vertexClipMask = 0;
        
        if (vertices[i].x_ > vertices[i].w_)
            vertexClipMask |= CLIPMASK_X_POS;
        if (vertices[i].x_ < -vertices[i].w_)
            vertexClipMask |= CLIPMASK_X_NEG;
        if (vertices[i].y_ > vertices[i].w_)
            vertexClipMask |= CLIPMASK_Y_POS;
        if (vertices[i].y_ < -vertices[i].w_)
            vertexClipMask |= CLIPMASK_Y_NEG;
        if (vertices[i].z_ > vertices[i].w_)
            vertexClipMask |= CLIPMASK_Z_POS;
        if (vertices[i].z_ < 0.0f)
            vertexClipMask |= CLIPMASK_Z_NEG;
        
        clipMask |= vertexClipMask;
        
        if (!i)
            andClipMask = vertexClipMask;
        else
            andClipMask &= vertexClipMask;
    }
    
    // If triangle is fully behind any clip plane, can reject quickly
    if (andClipMask)
        return;
    
    // Check if triangle is fully inside
    if (!clipMask)
    {
        projected[0] = ViewportTransform(vertices[0]);
        projected[1] = ViewportTransform(vertices[1]);
        projected[2] = ViewportTransform(vertices[2]);
        
        bool clockwise = SignedArea(projected[0], projected[1], projected[2]) < 0.0f;
        if (cullMode_ == CULL_NONE || (cullMode_ == CULL_CCW && clockwise) || (cullMode_ == CULL_CW && !clockwise))
        {
            DrawTriangle2D(projected, clockwise);
            drawOk = true;
        }
    }
    else
    {
        bool triangles[64];
        
        // Initial triangle
        triangles[0] = true;
        unsigned numTriangles = 1;
        
        if (clipMask & CLIPMASK_X_POS)
            ClipVertices(Vector4(-1.0f, 0.0f, 0.0f, 1.0f), vertices, triangles, numTriangles);
        if (clipMask & CLIPMASK_X_NEG)
            ClipVertices(Vector4(1.0f, 0.0f, 0.0f, 1.0f), vertices, triangles, numTriangles);
        if (clipMask & CLIPMASK_Y_POS)
            ClipVertices(Vector4(0.0f, -1.0f, 0.0f, 1.0f), vertices, triangles, numTriangles);
        if (clipMask & CLIPMASK_Y_NEG)
            ClipVertices(Vector4(0.0f, 1.0f, 0.0f, 1.0f), vertices, triangles, numTriangles);
        if (clipMask & CLIPMASK_Z_POS)
            ClipVertices(Vector4(0.0f, 0.0f, -1.0f, 1.0f), vertices, triangles, numTriangles);
        if (clipMask & CLIPMASK_Z_NEG)
            ClipVertices(Vector4(0.0f, 0.0f, 1.0f, 0.0f), vertices, triangles, numTriangles);
        
        // Draw each accepted triangle
        for (unsigned i = 0; i < numTriangles; ++i)
        {
            if (triangles[i])
            {
                unsigned index = i * 3;
                projected[0] = ViewportTransform(vertices[index]);
                projected[1] = ViewportTransform(vertices[index + 1]);
                projected[2] = ViewportTransform(vertices[index + 2]);
                
                bool clockwise = SignedArea(projected[0], projected[1], projected[2]) < 0.0f;
                if (cullMode_ == CULL_NONE || (cullMode_ == CULL_CCW && clockwise) || (cullMode_ == CULL_CW && !clockwise))
                {
                    DrawTriangle2D(projected, clockwise);
                    drawOk = true;
                }
            }
        }
    }
    
    if (drawOk)
        ++numTriangles_;
}