1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
#include "UnityPrefix.h"
#include "LineBuilder.h"
#include "Runtime/Math/Matrix4x4.h"
#include "Runtime/Geometry/AABB.h"
#include "Runtime/Shaders/GraphicsCaps.h"
#include "Runtime/GfxDevice/GfxDevice.h"
inline Vector2f Calculate2DLineExtrusionAverage (const Vector3f& p0, const Vector3f& delta, const Vector3f& delta2, float halfWidth)
{
Vector2f dif;
dif.x = p0.y * delta.z - p0.z * delta.y;
dif.y = p0.z * delta.x - p0.x * delta.z;
// dif = NormalizeFast(dif);
Vector2f dif2;
dif2.x = p0.y * delta2.z - p0.z * delta2.y;
dif2.y = p0.z * delta2.x - p0.x * delta2.z;
// dif2 = NormalizeFast(dif2);
dif += dif2;
dif = NormalizeFast(dif);
dif.x *= halfWidth;
dif.y *= halfWidth;
return dif;
/* Vector2f dif;
dif.x = p0.y * delta.z - p0.z * delta.y;
dif.y = p0.z * delta.x - p0.x * delta.z;
*/
}
/// \todo have optional input lengths for speed
/// \todo optimize the dif cross product (z is unused)
void Build3DLine( LineParameters *param, const Vector3f *inVertices, int vertexCount )
{
Assert(vertexCount > 1);
Assert(param->outVertices && param->outAABB);
LineVertex *outVertices = param->outVertices;
Matrix4x4f matrix = param->cameraTransform;
// As Gradient->GetFixed() needs an unnormalized position in 16.16 format
// (upper 16 color index, lower 16 - how far between), the max value is
// (nr of gradient colors - 1)*2^16 - 1
float fixedMult = (float)(((k3DLineGradientSize - 1) << 16) - 1);
GfxDevice& device = GetGfxDevice();
// Skip last vertex
Vector3f delta = matrix.MultiplyPoint3 (inVertices[0]) - matrix.MultiplyPoint3 (inVertices[1]);
for (int i=0;i<vertexCount;i++)
{
// Don't accumulate by adding deltaU, as the rounding error accumulates as well.
// Calculate u each time anew instead.
float u = i/(float)(vertexCount - 1);
// Calculate width and figure a cross section that faces the camera
Vector3f p0 = matrix.MultiplyPoint3 (inVertices[i]);
if (i+1 != vertexCount)
{
Vector3f p1 = matrix.MultiplyPoint3 (inVertices[i+1]);
delta = p0 - p1;
}
float width = Lerp(param->startWidth, param->endWidth, u);
Vector2f dif = Calculate2DLineExtrusion (p0, delta, width * 0.5F);
ColorRGBA32 color;
if(param->gradient)
color = param->gradient->GetFixed (UInt32(u*fixedMult));
else
// TODO: rewrite Gradient, so that we can elegantly use it here as well
color = Lerp((ColorRGBAf)param->color1, (ColorRGBAf)param->color2, u);
// Swizzle color of the renderer requires it
color = device.ConvertToDeviceVertexColor(color);
// One vertex
outVertices->vert.Set( p0.x - dif.x, p0.y - dif.y, p0.z );
outVertices->color = color;
outVertices->uv.Set( u, 1.0f );
++outVertices;
// And another vertex
outVertices->vert.Set( p0.x + dif.x, p0.y + dif.y, p0.z );
outVertices->color = color;
outVertices->uv.Set( u, 0.0f );
++outVertices;
param->outAABB->Encapsulate (inVertices[i]);
}
param->outAABB->Encapsulate (inVertices[vertexCount-1]);
}
|