[ create a new paste ] login | about

Link: http://codepad.org/ewDy31UH    [ raw code | fork ]

D, pasted on Aug 3:
import tango.stdc.stdio, tango.stdc.time;


struct CalVector4 {
    float X, Y, Z, W=0.0;
}


struct BoneTransform {
    CalVector4 RowX, RowY, RowZ;

    void scale(inout BoneTransform result, float s) {
        result.RowX.X = RowX.X * s;
        result.RowX.Y = RowX.Y * s;
        result.RowX.Z = RowX.Z * s;
        result.RowX.W = RowX.W * s;

        result.RowY.X = RowY.X * s;
        result.RowY.Y = RowY.Y * s;
        result.RowY.Z = RowY.Z * s;
        result.RowY.W = RowY.W * s;

        result.RowZ.X = RowZ.X * s;
        result.RowZ.Y = RowZ.Y * s;
        result.RowZ.Z = RowZ.Z * s;
        result.RowZ.W = RowZ.W * s;
    }

    void addScaled(inout BoneTransform mutate, float s) {
        mutate.RowX.X += RowX.X * s;
        mutate.RowX.Y += RowX.Y * s;
        mutate.RowX.Z += RowX.Z * s;
        mutate.RowX.W += RowX.W * s;

        mutate.RowY.X += RowY.X * s;
        mutate.RowY.Y += RowY.Y * s;
        mutate.RowY.Z += RowY.Z * s;
        mutate.RowY.W += RowY.W * s;

        mutate.RowZ.X += RowZ.X * s;
        mutate.RowZ.Y += RowZ.Y * s;
        mutate.RowZ.Z += RowZ.Z * s;
        mutate.RowZ.W += RowZ.W * s;
    }

    void transformPoint(inout CalVector4 result, inout CalVector4 point) {
        result = CalVector4(
            (RowX.X * point.X) + (RowX.Y * point.Y) + (RowX.Z * point.Z) + RowX.W,
            (RowY.X * point.X) + (RowY.Y * point.Y) + (RowY.Z * point.Z) + RowY.W,
            (RowZ.X * point.X) + (RowZ.Y * point.Y) + (RowZ.Z * point.Z) + RowZ.W
        );
    }

    void transformVector(inout CalVector4 result, inout CalVector4 vector) {
        result = CalVector4(
            (RowX.X * vector.X) + (RowX.Y * vector.Y) + (RowX.Z * vector.Z),
            (RowY.X * vector.X) + (RowY.Y * vector.Y) + (RowY.Z * vector.Z),
            (RowZ.X * vector.X) + (RowZ.Y * vector.Y) + (RowZ.Z * vector.Z)
        );
    }
}


struct Influence {
    int BoneId;
    float Weight;
    bool LastInfluenceForThisVertex;
}


struct Vertex {
    CalVector4 Position, Normal;
}


void calculateVerticesAndNormals(BoneTransform[] boneTransforms,
                                 int vertexCount,
                                 Vertex[] vertices,
                                 Influence[] influences,
                                 CalVector4[] output) {
    assert(output.length == vertices.length * 2);
    BoneTransform totalTransform;

    for (int sourceVertex, sourceInfluence, outputVertex;
         sourceVertex < vertices.length;
         sourceVertex++, sourceInfluence++, outputVertex += 2) {
        auto influence = influences[sourceInfluence];

        boneTransforms[influence.BoneId].scale(totalTransform, influence.Weight);

        while (!influence.LastInfluenceForThisVertex) {
            sourceInfluence += 1;
            influence = influences[sourceInfluence];

            boneTransforms[influence.BoneId].addScaled(totalTransform, influence.Weight);
        }

        totalTransform.transformPoint(output[outputVertex], vertices[sourceVertex].Position);
        totalTransform.transformVector(output[outputVertex + 1], vertices[sourceVertex].Normal);
    }
}

void main() {
    const int N = 10_000;

    Vertex[N] vertices;
    Influence[N] influences;

    for (int i = 0; i < N; i++) {
        vertices[i] = Vertex(CalVector4(1, 2, 3), CalVector4(0, 0, 1));
        influences[i] = Influence(0, 1.0f, true);
    }

    auto boneTransforms = new BoneTransform[1];
    auto output = new CalVector4[N * 2];

    for (int i = 0; i < 100; i++) {
        long verticesSkinned = 0;
        clock_t start = clock();

        while (clock() < start + CLOCKS_PER_SEC) {
            calculateVerticesAndNormals(boneTransforms, N, vertices, influences, output);
            verticesSkinned += N;
        }

        clock_t elapsed = clock() - start;
        printf("Skinned vertices per second: %d\n",
                cast(int)(verticesSkinned * CLOCKS_PER_SEC / elapsed));
    }
}


Create a new paste based on this one


Comments: