protected void SetPointsImpl(List <Vector3> points, List <ColorEx> colors, List <List <VertexBoneAssignment> > boneAssignments)
{
if (colors != null && points.Count != colors.Count)
{
throw new Exception("Invalid parameters to SetPoints. Point list length does not match colors list length");
}
Vector3 min = Vector3.Zero;
Vector3 max = Vector3.Zero;
// set up vertex data
vertexData = new VertexData();
// set up vertex declaration
VertexDeclaration vertexDeclaration = vertexData.vertexDeclaration;
int currentOffset = 0;
// always need positions
vertexDeclaration.AddElement(0, currentOffset, VertexElementType.Float3, VertexElementSemantic.Position);
currentOffset += VertexElement.GetTypeSize(VertexElementType.Float3);
int colorOffset = currentOffset / sizeof(float);
if (colors != null)
{
vertexDeclaration.AddElement(0, currentOffset, VertexElementType.Color, VertexElementSemantic.Diffuse);
currentOffset += VertexElement.GetTypeSize(VertexElementType.Color);
}
int boneIndexOffset = currentOffset / sizeof(float);
if (boneAssignments != null)
{
vertexDeclaration.AddElement(0, currentOffset, VertexElementType.UByte4, VertexElementSemantic.BlendIndices);
currentOffset += VertexElement.GetTypeSize(VertexElementType.UByte4);
}
int boneWeightOffset = currentOffset / sizeof(float);
if (boneAssignments != null)
{
vertexDeclaration.AddElement(0, currentOffset, VertexElementType.Float4, VertexElementSemantic.BlendWeights);
currentOffset += VertexElement.GetTypeSize(VertexElementType.Float4);
}
int stride = currentOffset / sizeof(float);
vertexData.vertexCount = points.Count;
// allocate vertex buffer
HardwareVertexBuffer vertexBuffer = HardwareBufferManager.Instance.CreateVertexBuffer(vertexDeclaration.GetVertexSize(0), vertexData.vertexCount, BufferUsage.StaticWriteOnly);
// set up the binding, one source only
VertexBufferBinding binding = vertexData.vertexBufferBinding;
binding.SetBinding(0, vertexBuffer);
// Generate vertex data
unsafe {
// lock the vertex buffer
IntPtr data = vertexBuffer.Lock(BufferLocking.Discard);
byte * pData = (byte *)data.ToPointer();
float *pFloat = (float *)pData;
uint * pInt = (uint *)pData;
for (int i = 0; i < points.Count; ++i)
{
Vector3 vec = points[i];
// assign to geometry
pFloat[stride * i] = vec.x;
pFloat[stride * i + 1] = vec.y;
pFloat[stride * i + 2] = vec.z;
if (colors != null)
{
// assign to diffuse
pInt[stride * i + colorOffset] = Root.Instance.RenderSystem.ConvertColor(colors[i]);
}
if (boneAssignments != null)
{
for (int j = 0; j < 4; ++j)
{
pData[4 * (stride * i + boneIndexOffset) + j] = (byte)(boneAssignments[i][j].boneIndex);
pFloat[stride * i + boneWeightOffset + j] = boneAssignments[i][j].weight;
}
}
}
// unlock the buffer
vertexBuffer.Unlock();
} // unsafe
for (int i = 0; i < points.Count; ++i)
{
Vector3 vec = points[i];
// Also update the bounding sphere radius
float len = vec.Length;
if (len > boundingSphereRadius)
{
boundingSphereRadius = len;
}
// Also update the bounding box
if (vec.x < min.x)
{
min.x = vec.x;
}
if (vec.y < min.y)
{
min.y = vec.y;
}
if (vec.z < min.z)
{
min.z = vec.z;
}
if (vec.x > max.x)
{
max.x = vec.x;
}
if (vec.y > max.y)
{
max.y = vec.y;
}
if (vec.z > max.z)
{
max.z = vec.z;
}
}
// Set the SimpleRenderable bounding box
box = new AxisAlignedBox(min, max);
}