Example #1
0
void mbChargeLattice::genEdge(mbLatticeCube *cube, int edgeIndex, int pointIndex, int pointIndex2)
{
	mbLatticeEdge *edge = cube->edges[edgeIndex];
	mbVector3D interpolationResult, normalResult;
	float *position = edge->position;
	if (edge->lastFrameVisited != currentFrame)
	{
		edge->lastFrameVisited = currentFrame;
		interpolationResult = interpolateEdge(cube->points[pointIndex], cube->points[pointIndex2], edge->axis);
		position[0] = interpolationResult.x;
		position[1] = interpolationResult.y;
		position[2] = interpolationResult.z;
		edge->vertexIndex = vertexCount;
		normalResult = calcNormal(interpolationResult);
		int realLocation = 3 * vertexCount;
		meshNormals[realLocation] = normalResult.x;
		meshVertices[realLocation] = interpolationResult.x;
		meshNormals[realLocation+1] = normalResult.y;
		meshVertices[realLocation+1] = interpolationResult.y;
		meshNormals[realLocation+2] = normalResult.z;
		meshVertices[realLocation+2] = interpolationResult.z;
		vertexCount++;
	}
};
Example #2
0
void ScanConverter::operator()(const acl::Object<> &object,
        const acl::Triangle<> &triangle) {
    // get triangle vertex positions
    const acl::Vertex<> &v1 = triangle.getVertex(object.getMesh(), 0);
    const acl::Vertex<> &v2 = triangle.getVertex(object.getMesh(), 1);
    const acl::Vertex<> &v3 = triangle.getVertex(object.getMesh(), 2);
    acl::Matrix<1, 4> vpos[] = {
        v1.getPositionInScreen(),
        v2.getPositionInScreen(),
        v3.getPositionInScreen()
    };

    // clip triangle if behind the camera
    if(clip && (vpos[0][2] >= 0 || vpos[1][2] >= 0 || vpos[2][2] >= 0))
        return;

    // perform perspective divide
    for(int i = 0; i < 3; i++) {
        vpos[i][0] /= vpos[i][3];
        vpos[i][1] /= vpos[i][3];
    }

    // sort vertices from lowest to highest by y coordinate
    int index[] = {0, 1, 2};
    if(vpos[index[0]][1] > vpos[index[1]][1]) {std::swap(index[0], index[1]);}
    if(vpos[index[1]][1] > vpos[index[2]][1]) {std::swap(index[1], index[2]);}
    if(vpos[index[0]][1] > vpos[index[1]][1]) {std::swap(index[0], index[1]);}

    // clip triangle if less than one pixel tall
    const int yminscreen = std::max(static_cast<int>(vpos[index[0]][1]), 0);
    const int ymaxscreen = std::min(static_cast<int>(vpos[index[2]][1]), frameBuffer.height());

    if(ymaxscreen <= yminscreen)
        return;

    // calculate triangle vertex lighting and set pixel properties
    acl::Color<> vertexColors[3];
    calculateVertexLighting(object, triangle, vertexColors);

    const Pixel pixels[] = {
        {vpos[0], v1.getPositionInWorld(), v1.getNormalInWorld(),
        triangle.getVertexMaterial(object, 0), vertexColors[0]},
        {vpos[1], v2.getPositionInWorld(), v2.getNormalInWorld(),
        triangle.getVertexMaterial(object, 1), vertexColors[1]},
        {vpos[2], v3.getPositionInWorld(), v3.getNormalInWorld(),
        triangle.getVertexMaterial(object, 2), vertexColors[2]}
    };

    // interpolate along edges
    edgePairs.resize(frameBuffer.height());
    interpolateEdge(pixels[index[0]], pixels[index[2]], true);
    interpolateEdge(pixels[index[0]], pixels[index[1]], false);
    interpolateEdge(pixels[index[1]], pixels[index[2]], false);

    // scan convert and interpolate between x coordinate pairs
    for(int y = yminscreen; y < ymaxscreen; y++) {
        const EdgePair &edgePair = edgePairs[y];
        const int xleft = static_cast<int>(edgePair.left.positionInScreen[0]);
        const int xright = static_cast<int>(edgePair.right.positionInScreen[0]);
        const int xleftscreen = std::max(xleft, 0);
        const int xrightscreen = std::min(xright, frameBuffer.width());

        for(int x = xleftscreen; x < xrightscreen; x++) {
            const double t = static_cast<double>(x - xleft) / (xright - xleft);
            const Pixel interpPixel = edgePair.left.interpolate(edgePair.right, t, shading);
            const acl::Color<> color = (shading == Shading::Phong) ?
                calculateLighting(interpPixel) : interpPixel.color;
            frameBuffer.blendPixel(x, y, interpPixel.positionInScreen[2], color.alpha(), color);
        }
    }
}