codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
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)); } }
Private
[
?
]
Run code
Submit