|
|
@@ -12,8 +12,6 @@ namespace BansheeEngine
|
|
|
const UINT32 DrawHelper::INDEX_BUFFER_GROWTH = 4096 * 2;
|
|
|
|
|
|
DrawHelper::DrawHelper()
|
|
|
- : mTotalRequiredSolidVertices(0), mTotalRequiredSolidIndices(0),
|
|
|
- mTotalRequiredWireVertices(0), mTotalRequiredWireIndices(0)
|
|
|
{
|
|
|
mTransform = Matrix4::IDENTITY;
|
|
|
|
|
|
@@ -32,7 +30,7 @@ namespace BansheeEngine
|
|
|
|
|
|
DrawHelper::~DrawHelper()
|
|
|
{
|
|
|
-
|
|
|
+ clearMeshes();
|
|
|
}
|
|
|
|
|
|
void DrawHelper::setColor(const Color& color)
|
|
|
@@ -54,9 +52,7 @@ namespace BansheeEngine
|
|
|
cubeData.extents = extents;
|
|
|
cubeData.color = mColor;
|
|
|
cubeData.transform = mTransform;
|
|
|
-
|
|
|
- mTotalRequiredSolidVertices += 24;
|
|
|
- mTotalRequiredSolidIndices += 36;
|
|
|
+ cubeData.center = mTransform.multiply3x4(position);
|
|
|
}
|
|
|
|
|
|
void DrawHelper::sphere(const Vector3& position, float radius, UINT32 quality)
|
|
|
@@ -69,12 +65,7 @@ namespace BansheeEngine
|
|
|
sphereData.quality = quality;
|
|
|
sphereData.color = mColor;
|
|
|
sphereData.transform = mTransform;
|
|
|
-
|
|
|
- UINT32 numVertices, numIndices;
|
|
|
- ShapeMeshes3D::getNumElementsSphere(quality, numVertices, numIndices);
|
|
|
-
|
|
|
- mTotalRequiredSolidVertices += numVertices;
|
|
|
- mTotalRequiredSolidIndices += numIndices;
|
|
|
+ sphereData.center = mTransform.multiply3x4(position);
|
|
|
}
|
|
|
|
|
|
void DrawHelper::wireCube(const Vector3& position, const Vector3& extents)
|
|
|
@@ -86,9 +77,7 @@ namespace BansheeEngine
|
|
|
cubeData.extents = extents;
|
|
|
cubeData.color = mColor;
|
|
|
cubeData.transform = mTransform;
|
|
|
-
|
|
|
- mTotalRequiredWireVertices += 8;
|
|
|
- mTotalRequiredWireIndices += 24;
|
|
|
+ cubeData.center = mTransform.multiply3x4(position);
|
|
|
}
|
|
|
|
|
|
void DrawHelper::wireSphere(const Vector3& position, float radius, UINT32 quality)
|
|
|
@@ -101,12 +90,7 @@ namespace BansheeEngine
|
|
|
sphereData.quality = quality;
|
|
|
sphereData.color = mColor;
|
|
|
sphereData.transform = mTransform;
|
|
|
-
|
|
|
- UINT32 numVertices, numIndices;
|
|
|
- ShapeMeshes3D::getNumElementsWireSphere(quality, numVertices, numIndices);
|
|
|
-
|
|
|
- mTotalRequiredWireVertices += numVertices;
|
|
|
- mTotalRequiredWireIndices += numIndices;
|
|
|
+ sphereData.center = mTransform.multiply3x4(position);
|
|
|
}
|
|
|
|
|
|
void DrawHelper::line(const Vector3& start, const Vector3& end)
|
|
|
@@ -118,9 +102,7 @@ namespace BansheeEngine
|
|
|
lineData.end = end;
|
|
|
lineData.color = mColor;
|
|
|
lineData.transform = mTransform;
|
|
|
-
|
|
|
- mTotalRequiredWireVertices += 2;
|
|
|
- mTotalRequiredWireIndices += 2;
|
|
|
+ lineData.center = mTransform.multiply3x4((start + end) * 0.5f);
|
|
|
}
|
|
|
|
|
|
void DrawHelper::frustum(const Vector3& position, float aspect, Degree FOV, float near, float far)
|
|
|
@@ -135,9 +117,7 @@ namespace BansheeEngine
|
|
|
frustumData.far = far;
|
|
|
frustumData.color = mColor;
|
|
|
frustumData.transform = mTransform;
|
|
|
-
|
|
|
- mTotalRequiredWireVertices += 8;
|
|
|
- mTotalRequiredWireIndices += 36;
|
|
|
+ frustumData.center = mTransform.multiply3x4(position);
|
|
|
}
|
|
|
|
|
|
void DrawHelper::cone(const Vector3& base, const Vector3& normal, float height, float radius, UINT32 quality)
|
|
|
@@ -152,12 +132,7 @@ namespace BansheeEngine
|
|
|
coneData.quality = quality;
|
|
|
coneData.color = mColor;
|
|
|
coneData.transform = mTransform;
|
|
|
-
|
|
|
- UINT32 numVertices, numIndices;
|
|
|
- ShapeMeshes3D::getNumElementsCone(quality, numVertices, numIndices);
|
|
|
-
|
|
|
- mTotalRequiredSolidVertices += numVertices;
|
|
|
- mTotalRequiredSolidIndices += numIndices;
|
|
|
+ coneData.center = mTransform.multiply3x4(base + normal * height * 0.5f);
|
|
|
}
|
|
|
|
|
|
void DrawHelper::disc(const Vector3& position, const Vector3& normal, float radius, UINT32 quality)
|
|
|
@@ -171,12 +146,7 @@ namespace BansheeEngine
|
|
|
discData.quality = quality;
|
|
|
discData.color = mColor;
|
|
|
discData.transform = mTransform;
|
|
|
-
|
|
|
- UINT32 numVertices, numIndices;
|
|
|
- ShapeMeshes3D::getNumElementsDisc(quality, numVertices, numIndices);
|
|
|
-
|
|
|
- mTotalRequiredSolidVertices += numVertices;
|
|
|
- mTotalRequiredSolidIndices += numIndices;
|
|
|
+ discData.center = mTransform.multiply3x4(position);
|
|
|
}
|
|
|
|
|
|
void DrawHelper::wireDisc(const Vector3& position, const Vector3& normal, float radius, UINT32 quality)
|
|
|
@@ -190,12 +160,7 @@ namespace BansheeEngine
|
|
|
discData.quality = quality;
|
|
|
discData.color = mColor;
|
|
|
discData.transform = mTransform;
|
|
|
-
|
|
|
- UINT32 numVertices, numIndices;
|
|
|
- ShapeMeshes3D::getNumElementsWireDisc(quality, numVertices, numIndices);
|
|
|
-
|
|
|
- mTotalRequiredWireVertices += numVertices;
|
|
|
- mTotalRequiredWireIndices += numIndices;
|
|
|
+ discData.center = mTransform.multiply3x4(position);
|
|
|
}
|
|
|
|
|
|
void DrawHelper::arc(const Vector3& position, const Vector3& normal, float radius,
|
|
|
@@ -212,12 +177,7 @@ namespace BansheeEngine
|
|
|
arcData.quality = quality;
|
|
|
arcData.color = mColor;
|
|
|
arcData.transform = mTransform;
|
|
|
-
|
|
|
- UINT32 numVertices, numIndices;
|
|
|
- ShapeMeshes3D::getNumElementsArc(quality, numVertices, numIndices);
|
|
|
-
|
|
|
- mTotalRequiredSolidVertices += numVertices;
|
|
|
- mTotalRequiredSolidIndices += numIndices;
|
|
|
+ arcData.center = mTransform.multiply3x4(position);
|
|
|
}
|
|
|
|
|
|
void DrawHelper::wireArc(const Vector3& position, const Vector3& normal, float radius,
|
|
|
@@ -234,12 +194,7 @@ namespace BansheeEngine
|
|
|
arcData.quality = quality;
|
|
|
arcData.color = mColor;
|
|
|
arcData.transform = mTransform;
|
|
|
-
|
|
|
- UINT32 numVertices, numIndices;
|
|
|
- ShapeMeshes3D::getNumElementsWireArc(quality, numVertices, numIndices);
|
|
|
-
|
|
|
- mTotalRequiredWireVertices += numVertices;
|
|
|
- mTotalRequiredWireIndices += numIndices;
|
|
|
+ arcData.center = mTransform.multiply3x4(position);
|
|
|
}
|
|
|
|
|
|
void DrawHelper::rectangle(const Rect3& area)
|
|
|
@@ -250,9 +205,7 @@ namespace BansheeEngine
|
|
|
rectData.area = area;
|
|
|
rectData.color = mColor;
|
|
|
rectData.transform = mTransform;
|
|
|
-
|
|
|
- mTotalRequiredSolidVertices += 4;
|
|
|
- mTotalRequiredSolidIndices += 6;
|
|
|
+ rectData.center = mTransform.multiply3x4(area.getCenter());
|
|
|
}
|
|
|
|
|
|
void DrawHelper::clear()
|
|
|
@@ -270,311 +223,516 @@ namespace BansheeEngine
|
|
|
mArcData.clear();
|
|
|
mWireArcData.clear();
|
|
|
mConeData.clear();
|
|
|
-
|
|
|
- mTotalRequiredSolidVertices = 0;
|
|
|
- mTotalRequiredSolidIndices = 0;
|
|
|
-
|
|
|
- mTotalRequiredWireVertices = 0;
|
|
|
- mTotalRequiredWireIndices = 0;
|
|
|
}
|
|
|
|
|
|
- TransientMeshPtr DrawHelper::buildSolidMesh()
|
|
|
+ void DrawHelper::buildMeshes(SortType sorting, const Vector3& reference)
|
|
|
{
|
|
|
- MeshDataPtr meshData = bs_shared_ptr<MeshData>(mTotalRequiredSolidVertices, mTotalRequiredSolidIndices, mSolidVertexDesc);
|
|
|
-
|
|
|
- UINT32 curVertexOffset = 0;
|
|
|
- UINT32 curIndexOffet = 0;
|
|
|
+ clearMeshes();
|
|
|
|
|
|
- auto positionIter = meshData->getVec3DataIter(VES_POSITION);
|
|
|
- auto normalIter = meshData->getVec3DataIter(VES_NORMAL);
|
|
|
- auto colorIter = meshData->getDWORDDataIter(VES_COLOR);
|
|
|
-
|
|
|
- for (auto& cubeData : mSolidCubeData)
|
|
|
+ enum class ShapeType
|
|
|
{
|
|
|
- AABox box(cubeData.position - cubeData.extents, cubeData.position + cubeData.extents);
|
|
|
- ShapeMeshes3D::solidAABox(box, meshData, curVertexOffset, curIndexOffet);
|
|
|
-
|
|
|
- Matrix4 transformIT = cubeData.transform.inverseAffine().transpose();
|
|
|
- RGBA color = cubeData.color.getAsRGBA();
|
|
|
-
|
|
|
- UINT32 numVertices = 24;
|
|
|
- for (UINT32 i = 0; i < numVertices; i++)
|
|
|
- {
|
|
|
- Vector3 worldPos = cubeData.transform.multiply3x4(positionIter.getValue());
|
|
|
- Vector3 worldNormal = transformIT.multiply3x4(normalIter.getValue());
|
|
|
-
|
|
|
- positionIter.addValue(worldPos);
|
|
|
- normalIter.addValue(worldNormal);
|
|
|
- colorIter.addValue(color);
|
|
|
- }
|
|
|
+ Cube, Sphere, WireCube, WireSphere, Line, Frustum,
|
|
|
+ Cone, Disc, WireDisc, Arc, WireArc, Rectangle
|
|
|
+ };
|
|
|
|
|
|
- curVertexOffset += numVertices;
|
|
|
- curIndexOffet += 36;
|
|
|
+ struct RawData
|
|
|
+ {
|
|
|
+ ShapeType shapeType;
|
|
|
+ MeshType meshType;
|
|
|
+ UINT32 idx;
|
|
|
+ float distance;
|
|
|
+ UINT32 numVertices;
|
|
|
+ UINT32 numIndices;
|
|
|
+ };
|
|
|
+
|
|
|
+ /************************************************************************/
|
|
|
+ /* Sort everything according to specified sorting rule */
|
|
|
+ /************************************************************************/
|
|
|
+
|
|
|
+ UINT32 totalNumShapes = (UINT32)(mSolidCubeData.size() + mSolidSphereData.size() +
|
|
|
+ mWireCubeData.size() + mWireSphereData.size() + mLineData.size() + mFrustumData.size() + mConeData.size() +
|
|
|
+ mDiscData.size() + mWireDiscData.size() + mArcData.size() + mWireArcData.size() + mRect3Data.size());
|
|
|
+
|
|
|
+ UINT32 idx = 0;
|
|
|
+ Vector<RawData> allShapes(totalNumShapes);
|
|
|
+
|
|
|
+ UINT32 localIdx = 0;
|
|
|
+ for (auto& shapeData : mSolidCubeData)
|
|
|
+ {
|
|
|
+ RawData& rawData = allShapes[idx];
|
|
|
+
|
|
|
+ rawData.idx = localIdx++;
|
|
|
+ rawData.meshType = MeshType::Solid;
|
|
|
+ rawData.shapeType = ShapeType::Cube;
|
|
|
+ rawData.distance = shapeData.center.distance(reference);
|
|
|
+ rawData.numVertices = 24;
|
|
|
+ rawData.numIndices = 36;
|
|
|
+ idx++;
|
|
|
}
|
|
|
|
|
|
- for (auto& sphereData : mSolidSphereData)
|
|
|
+ localIdx = 0;
|
|
|
+ for (auto& shapeData : mSolidSphereData)
|
|
|
{
|
|
|
- UINT32 numVertices, numIndices;
|
|
|
- ShapeMeshes3D::getNumElementsSphere(sphereData.quality, numVertices, numIndices);
|
|
|
-
|
|
|
- Sphere sphere(sphereData.position, sphereData.radius);
|
|
|
- ShapeMeshes3D::solidSphere(sphere, meshData, curVertexOffset, curIndexOffet, sphereData.quality);
|
|
|
+ RawData& rawData = allShapes[idx];
|
|
|
|
|
|
- Matrix4 transformIT = sphereData.transform.inverseAffine().transpose();
|
|
|
- RGBA color = sphereData.color.getAsRGBA();
|
|
|
+ rawData.idx = localIdx++;
|
|
|
+ rawData.meshType = MeshType::Solid;
|
|
|
+ rawData.shapeType = ShapeType::Sphere;
|
|
|
+ rawData.distance = shapeData.center.distance(reference);
|
|
|
|
|
|
- for (UINT32 i = 0; i < numVertices; i++)
|
|
|
- {
|
|
|
- Vector3 worldPos = sphereData.transform.multiply3x4(positionIter.getValue());
|
|
|
- Vector3 worldNormal = transformIT.multiply3x4(normalIter.getValue());
|
|
|
-
|
|
|
- positionIter.addValue(worldPos);
|
|
|
- normalIter.addValue(worldNormal);
|
|
|
- colorIter.addValue(color);
|
|
|
- }
|
|
|
+ ShapeMeshes3D::getNumElementsSphere(shapeData.quality,
|
|
|
+ rawData.numVertices, rawData.numIndices);
|
|
|
|
|
|
- curVertexOffset += numVertices;
|
|
|
- curIndexOffet += numIndices;
|
|
|
+ idx++;
|
|
|
}
|
|
|
|
|
|
- for (auto& coneData : mConeData)
|
|
|
+ localIdx = 0;
|
|
|
+ for (auto& shapeData : mConeData)
|
|
|
{
|
|
|
- UINT32 numVertices, numIndices;
|
|
|
- ShapeMeshes3D::getNumElementsCone(coneData.quality, numVertices, numIndices);
|
|
|
+ RawData& rawData = allShapes[idx];
|
|
|
|
|
|
- ShapeMeshes3D::solidCone(coneData.base, coneData.normal, coneData.height, coneData.radius,
|
|
|
- meshData, curVertexOffset, curIndexOffet, coneData.quality);
|
|
|
+ rawData.idx = localIdx++;
|
|
|
+ rawData.meshType = MeshType::Solid;
|
|
|
+ rawData.shapeType = ShapeType::Cone;
|
|
|
+ rawData.distance = shapeData.center.distance(reference);
|
|
|
|
|
|
- Matrix4 transformIT = coneData.transform.inverseAffine().transpose();
|
|
|
- RGBA color = coneData.color.getAsRGBA();
|
|
|
+ ShapeMeshes3D::getNumElementsCone(shapeData.quality,
|
|
|
+ rawData.numVertices, rawData.numIndices);
|
|
|
|
|
|
- for (UINT32 i = 0; i < numVertices; i++)
|
|
|
- {
|
|
|
- Vector3 worldPos = coneData.transform.multiply3x4(positionIter.getValue());
|
|
|
- Vector3 worldNormal = transformIT.multiply3x4(normalIter.getValue());
|
|
|
-
|
|
|
- positionIter.addValue(worldPos);
|
|
|
- normalIter.addValue(worldNormal);
|
|
|
- colorIter.addValue(color);
|
|
|
- }
|
|
|
-
|
|
|
- curVertexOffset += numVertices;
|
|
|
- curIndexOffet += numIndices;
|
|
|
+ idx++;
|
|
|
}
|
|
|
|
|
|
- for (auto& discData : mDiscData)
|
|
|
+ localIdx = 0;
|
|
|
+ for (auto& shapeData : mDiscData)
|
|
|
{
|
|
|
- UINT32 numVertices, numIndices;
|
|
|
- ShapeMeshes3D::getNumElementsDisc(discData.quality, numVertices, numIndices);
|
|
|
-
|
|
|
- ShapeMeshes3D::solidDisc(discData.position, discData.radius, discData.normal,
|
|
|
- meshData, curVertexOffset, curIndexOffet, discData.quality);
|
|
|
+ RawData& rawData = allShapes[idx];
|
|
|
|
|
|
- Matrix4 transformIT = discData.transform.inverseAffine().transpose();
|
|
|
- RGBA color = discData.color.getAsRGBA();
|
|
|
+ rawData.idx = localIdx++;
|
|
|
+ rawData.meshType = MeshType::Solid;
|
|
|
+ rawData.shapeType = ShapeType::Disc;
|
|
|
+ rawData.distance = shapeData.center.distance(reference);
|
|
|
|
|
|
- for (UINT32 i = 0; i < numVertices; i++)
|
|
|
- {
|
|
|
- Vector3 worldPos = discData.transform.multiply3x4(positionIter.getValue());
|
|
|
- Vector3 worldNormal = transformIT.multiply3x4(normalIter.getValue());
|
|
|
+ ShapeMeshes3D::getNumElementsDisc(shapeData.quality,
|
|
|
+ rawData.numVertices, rawData.numIndices);
|
|
|
|
|
|
- positionIter.addValue(worldPos);
|
|
|
- normalIter.addValue(worldNormal);
|
|
|
- colorIter.addValue(color);
|
|
|
- }
|
|
|
-
|
|
|
- curVertexOffset += numVertices;
|
|
|
- curIndexOffet += numIndices;
|
|
|
+ idx++;
|
|
|
}
|
|
|
|
|
|
- for (auto& arcData : mArcData)
|
|
|
+ localIdx = 0;
|
|
|
+ for (auto& shapeData : mArcData)
|
|
|
{
|
|
|
- UINT32 numVertices, numIndices;
|
|
|
- ShapeMeshes3D::getNumElementsArc(arcData.quality, numVertices, numIndices);
|
|
|
+ RawData& rawData = allShapes[idx];
|
|
|
|
|
|
- ShapeMeshes3D::solidArc(arcData.position, arcData.radius, arcData.normal,
|
|
|
- arcData.startAngle, arcData.amountAngle, meshData, curVertexOffset, curIndexOffet, arcData.quality);
|
|
|
+ rawData.idx = localIdx++;
|
|
|
+ rawData.meshType = MeshType::Solid;
|
|
|
+ rawData.shapeType = ShapeType::Arc;
|
|
|
+ rawData.distance = shapeData.center.distance(reference);
|
|
|
|
|
|
- Matrix4 transformIT = arcData.transform.inverseAffine().transpose();
|
|
|
- RGBA color = arcData.color.getAsRGBA();
|
|
|
+ ShapeMeshes3D::getNumElementsArc(shapeData.quality,
|
|
|
+ rawData.numVertices, rawData.numIndices);
|
|
|
|
|
|
- for (UINT32 i = 0; i < numVertices; i++)
|
|
|
- {
|
|
|
- Vector3 worldPos = arcData.transform.multiply3x4(positionIter.getValue());
|
|
|
- Vector3 worldNormal = transformIT.multiply3x4(normalIter.getValue());
|
|
|
-
|
|
|
- positionIter.addValue(worldPos);
|
|
|
- normalIter.addValue(worldNormal);
|
|
|
- colorIter.addValue(color);
|
|
|
- }
|
|
|
+ idx++;
|
|
|
+ }
|
|
|
|
|
|
- curVertexOffset += numVertices;
|
|
|
- curIndexOffet += numIndices;
|
|
|
+ localIdx = 0;
|
|
|
+ for (auto& shapeData : mRect3Data)
|
|
|
+ {
|
|
|
+ RawData& rawData = allShapes[idx];
|
|
|
+
|
|
|
+ rawData.idx = localIdx++;
|
|
|
+ rawData.meshType = MeshType::Solid;
|
|
|
+ rawData.shapeType = ShapeType::Rectangle;
|
|
|
+ rawData.distance = shapeData.center.distance(reference);
|
|
|
+ rawData.numVertices = 4;
|
|
|
+ rawData.numIndices = 6;
|
|
|
+ idx++;
|
|
|
}
|
|
|
|
|
|
- for (auto& rectData : mRect3Data)
|
|
|
+ localIdx = 0;
|
|
|
+ for (auto& shapeData : mWireCubeData)
|
|
|
{
|
|
|
- ShapeMeshes3D::solidQuad(rectData.area, meshData, curVertexOffset, curIndexOffet);
|
|
|
+ RawData& rawData = allShapes[idx];
|
|
|
+
|
|
|
+ rawData.idx = localIdx++;
|
|
|
+ rawData.meshType = MeshType::Wire;
|
|
|
+ rawData.shapeType = ShapeType::WireCube;
|
|
|
+ rawData.distance = shapeData.center.distance(reference);
|
|
|
+ rawData.numVertices = 8;
|
|
|
+ rawData.numIndices = 24;
|
|
|
+ idx++;
|
|
|
+ }
|
|
|
|
|
|
- Matrix4 transformIT = rectData.transform.inverseAffine().transpose();
|
|
|
- RGBA color = rectData.color.getAsRGBA();
|
|
|
+ localIdx = 0;
|
|
|
+ for (auto& shapeData : mWireSphereData)
|
|
|
+ {
|
|
|
+ RawData& rawData = allShapes[idx];
|
|
|
|
|
|
- for (UINT32 i = 0; i < 4; i++)
|
|
|
- {
|
|
|
- Vector3 worldPos = rectData.transform.multiply3x4(positionIter.getValue());
|
|
|
- Vector3 worldNormal = transformIT.multiply3x4(normalIter.getValue());
|
|
|
+ rawData.idx = localIdx++;
|
|
|
+ rawData.meshType = MeshType::Wire;
|
|
|
+ rawData.shapeType = ShapeType::WireSphere;
|
|
|
+ rawData.distance = shapeData.center.distance(reference);
|
|
|
|
|
|
- positionIter.addValue(worldPos);
|
|
|
- normalIter.addValue(worldNormal);
|
|
|
- colorIter.addValue(color);
|
|
|
- }
|
|
|
+ ShapeMeshes3D::getNumElementsWireSphere(shapeData.quality,
|
|
|
+ rawData.numVertices, rawData.numIndices);
|
|
|
|
|
|
- curVertexOffset += 4;
|
|
|
- curIndexOffet += 6;
|
|
|
+ idx++;
|
|
|
}
|
|
|
|
|
|
- return mSolidMeshHeap->alloc(meshData, DOT_TRIANGLE_LIST);
|
|
|
- }
|
|
|
-
|
|
|
- TransientMeshPtr DrawHelper::buildWireMesh()
|
|
|
- {
|
|
|
- MeshDataPtr meshData = bs_shared_ptr<MeshData>(mTotalRequiredWireVertices,
|
|
|
- mTotalRequiredWireIndices, mWireVertexDesc);
|
|
|
-
|
|
|
- UINT32 curVertexOffset = 0;
|
|
|
- UINT32 curIndexOffet = 0;
|
|
|
-
|
|
|
- auto positionIter = meshData->getVec3DataIter(VES_POSITION);
|
|
|
- auto colorIter = meshData->getDWORDDataIter(VES_COLOR);
|
|
|
+ localIdx = 0;
|
|
|
+ for (auto& shapeData : mLineData)
|
|
|
+ {
|
|
|
+ RawData& rawData = allShapes[idx];
|
|
|
+
|
|
|
+ rawData.idx = localIdx++;
|
|
|
+ rawData.meshType = MeshType::Wire;
|
|
|
+ rawData.shapeType = ShapeType::Line;
|
|
|
+ rawData.distance = shapeData.center.distance(reference);
|
|
|
+ rawData.numVertices = 2;
|
|
|
+ rawData.numIndices = 2;
|
|
|
+ idx++;
|
|
|
+ }
|
|
|
|
|
|
- for (auto& cubeData : mWireCubeData)
|
|
|
+ localIdx = 0;
|
|
|
+ for (auto& shapeData : mFrustumData)
|
|
|
{
|
|
|
- AABox box(cubeData.position - cubeData.extents, cubeData.position + cubeData.extents);
|
|
|
- ShapeMeshes3D::wireAABox(box, meshData, curVertexOffset, curIndexOffet);
|
|
|
+ RawData& rawData = allShapes[idx];
|
|
|
+
|
|
|
+ rawData.idx = localIdx++;
|
|
|
+ rawData.meshType = MeshType::Wire;
|
|
|
+ rawData.shapeType = ShapeType::Frustum;
|
|
|
+ rawData.distance = shapeData.center.distance(reference);
|
|
|
+ rawData.numVertices = 8;
|
|
|
+ rawData.numIndices = 36;
|
|
|
+ idx++;
|
|
|
+ }
|
|
|
|
|
|
- RGBA color = cubeData.color.getAsRGBA();
|
|
|
+ localIdx = 0;
|
|
|
+ for (auto& shapeData : mWireDiscData)
|
|
|
+ {
|
|
|
+ RawData& rawData = allShapes[idx];
|
|
|
|
|
|
- UINT32 numVertices = 8;
|
|
|
- for (UINT32 i = 0; i < numVertices; i++)
|
|
|
- {
|
|
|
- Vector3 worldPos = cubeData.transform.multiply3x4(positionIter.getValue());
|
|
|
+ rawData.idx = localIdx++;
|
|
|
+ rawData.meshType = MeshType::Wire;
|
|
|
+ rawData.shapeType = ShapeType::WireDisc;
|
|
|
+ rawData.distance = shapeData.center.distance(reference);
|
|
|
|
|
|
- positionIter.addValue(worldPos);
|
|
|
- colorIter.addValue(color);
|
|
|
- }
|
|
|
+ ShapeMeshes3D::getNumElementsWireDisc(shapeData.quality,
|
|
|
+ rawData.numVertices, rawData.numIndices);
|
|
|
|
|
|
- curVertexOffset += numVertices;
|
|
|
- curIndexOffet += 24;
|
|
|
+ idx++;
|
|
|
}
|
|
|
|
|
|
- for (auto& sphereData : mWireSphereData)
|
|
|
+ localIdx = 0;
|
|
|
+ for (auto& shapeData : mWireArcData)
|
|
|
{
|
|
|
- UINT32 numVertices, numIndices;
|
|
|
- ShapeMeshes3D::getNumElementsWireSphere(sphereData.quality, numVertices, numIndices);
|
|
|
+ RawData& rawData = allShapes[idx];
|
|
|
|
|
|
- Sphere sphere(sphereData.position, sphereData.radius);
|
|
|
- ShapeMeshes3D::wireSphere(sphere, meshData, curVertexOffset, curIndexOffet, sphereData.quality);
|
|
|
+ rawData.idx = localIdx++;
|
|
|
+ rawData.meshType = MeshType::Wire;
|
|
|
+ rawData.shapeType = ShapeType::WireArc;
|
|
|
+ rawData.distance = shapeData.center.distance(reference);
|
|
|
|
|
|
- RGBA color = sphereData.color.getAsRGBA();
|
|
|
- for (UINT32 i = 0; i < numVertices; i++)
|
|
|
- {
|
|
|
- Vector3 worldPos = sphereData.transform.multiply3x4(positionIter.getValue());
|
|
|
+ ShapeMeshes3D::getNumElementsWireArc(shapeData.quality,
|
|
|
+ rawData.numVertices, rawData.numIndices);
|
|
|
|
|
|
- positionIter.addValue(worldPos);
|
|
|
- colorIter.addValue(color);
|
|
|
- }
|
|
|
-
|
|
|
- curVertexOffset += numVertices;
|
|
|
- curIndexOffet += numIndices;
|
|
|
+ idx++;
|
|
|
}
|
|
|
|
|
|
- for (auto& lineData : mLineData)
|
|
|
+ if (sorting == SortType::FrontToBack)
|
|
|
{
|
|
|
- ShapeMeshes3D::pixelLine(lineData.start, lineData.end, meshData, curVertexOffset, curIndexOffet);
|
|
|
-
|
|
|
- RGBA color = lineData.color.getAsRGBA();
|
|
|
- for (UINT32 i = 0; i < 2; i++)
|
|
|
+ std::sort(begin(allShapes), end(allShapes),
|
|
|
+ [&](const RawData& x, const RawData& y)
|
|
|
{
|
|
|
- Vector3 worldPos = lineData.transform.multiply3x4(positionIter.getValue());
|
|
|
-
|
|
|
- positionIter.addValue(worldPos);
|
|
|
- colorIter.addValue(color);
|
|
|
- }
|
|
|
-
|
|
|
- curVertexOffset += 2;
|
|
|
- curIndexOffet += 2;
|
|
|
+ return x.distance < y.distance;
|
|
|
+ });
|
|
|
}
|
|
|
-
|
|
|
- for (auto& frustumData : mFrustumData)
|
|
|
+ else if (sorting == SortType::BackToFront)
|
|
|
{
|
|
|
- ShapeMeshes3D::wireFrustum(frustumData.position, frustumData.aspect, frustumData.FOV, frustumData.near,
|
|
|
- frustumData.far, meshData, curVertexOffset, curIndexOffet);
|
|
|
-
|
|
|
- RGBA color = frustumData.color.getAsRGBA();
|
|
|
- for (UINT32 i = 0; i < 8; i++)
|
|
|
+ std::sort(begin(allShapes), end(allShapes),
|
|
|
+ [&](const RawData& x, const RawData& y)
|
|
|
{
|
|
|
- Vector3 worldPos = frustumData.transform.multiply3x4(positionIter.getValue());
|
|
|
-
|
|
|
- positionIter.addValue(worldPos);
|
|
|
- colorIter.addValue(color);
|
|
|
- }
|
|
|
-
|
|
|
- curVertexOffset += 8;
|
|
|
- curIndexOffet += 24;
|
|
|
+ return y.distance < x.distance;
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
- for (auto& discData : mWireDiscData)
|
|
|
+ /************************************************************************/
|
|
|
+ /* Create batches */
|
|
|
+ /************************************************************************/
|
|
|
+ struct Batch
|
|
|
{
|
|
|
- UINT32 numVertices, numIndices;
|
|
|
- ShapeMeshes3D::getNumElementsDisc(discData.quality, numVertices, numIndices);
|
|
|
-
|
|
|
- ShapeMeshes3D::solidDisc(discData.position, discData.radius, discData.normal,
|
|
|
- meshData, curVertexOffset, curIndexOffet, discData.quality);
|
|
|
+ MeshType type;
|
|
|
+ UINT32 startIdx;
|
|
|
+ UINT32 endIdx;
|
|
|
+ UINT32 numVertices;
|
|
|
+ UINT32 numIndices;
|
|
|
+ };
|
|
|
+
|
|
|
+ Vector<Batch> batches;
|
|
|
+ if (totalNumShapes > 0)
|
|
|
+ {
|
|
|
+ batches.push_back(Batch());
|
|
|
|
|
|
- RGBA color = discData.color.getAsRGBA();
|
|
|
- for (UINT32 i = 0; i < numVertices; i++)
|
|
|
{
|
|
|
- Vector3 worldPos = discData.transform.multiply3x4(positionIter.getValue());
|
|
|
+ Batch& currentBatch = batches.back();
|
|
|
+ currentBatch.startIdx = 0;
|
|
|
+ currentBatch.type = allShapes[0].meshType;
|
|
|
+ currentBatch.numVertices = allShapes[0].numVertices;
|
|
|
+ currentBatch.numIndices = allShapes[0].numIndices;
|
|
|
+ }
|
|
|
|
|
|
- positionIter.addValue(worldPos);
|
|
|
- colorIter.addValue(color);
|
|
|
+ for (UINT32 i = 1; i < totalNumShapes; i++)
|
|
|
+ {
|
|
|
+ Batch& currentBatch = batches.back();
|
|
|
+
|
|
|
+ if (allShapes[i].meshType != currentBatch.type)
|
|
|
+ {
|
|
|
+ currentBatch.endIdx = i - 1;
|
|
|
+
|
|
|
+ batches.push_back(Batch());
|
|
|
+
|
|
|
+ Batch& newBatch = batches.back();
|
|
|
+ newBatch.startIdx = i;
|
|
|
+ newBatch.type = allShapes[i].meshType;
|
|
|
+ newBatch.numVertices = allShapes[i].numVertices;
|
|
|
+ newBatch.numIndices = allShapes[i].numIndices;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ currentBatch.endIdx = i;
|
|
|
+ currentBatch.numVertices += allShapes[i].numVertices;
|
|
|
+ currentBatch.numIndices += allShapes[i].numIndices;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- curVertexOffset += numVertices;
|
|
|
- curIndexOffet += numIndices;
|
|
|
+ {
|
|
|
+ Batch& currentBatch = batches.back();
|
|
|
+ currentBatch.endIdx = totalNumShapes - 1;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- for (auto& arcData : mWireArcData)
|
|
|
+ /************************************************************************/
|
|
|
+ /* Generate geometry for each batch */
|
|
|
+ /************************************************************************/
|
|
|
+ for (auto& batch : batches)
|
|
|
{
|
|
|
- UINT32 numVertices, numIndices;
|
|
|
- ShapeMeshes3D::getNumElementsArc(arcData.quality, numVertices, numIndices);
|
|
|
-
|
|
|
- ShapeMeshes3D::solidArc(arcData.position, arcData.radius, arcData.normal,
|
|
|
- arcData.startAngle, arcData.amountAngle, meshData, curVertexOffset, curIndexOffet, arcData.quality);
|
|
|
-
|
|
|
- RGBA color = arcData.color.getAsRGBA();
|
|
|
- for (UINT32 i = 0; i < numVertices; i++)
|
|
|
+ if (batch.type == MeshType::Solid)
|
|
|
{
|
|
|
- Vector3 worldPos = arcData.transform.multiply3x4(positionIter.getValue());
|
|
|
-
|
|
|
- positionIter.addValue(worldPos);
|
|
|
- colorIter.addValue(color);
|
|
|
+ MeshDataPtr meshData = bs_shared_ptr<MeshData>(batch.numVertices, batch.numIndices, mSolidVertexDesc);
|
|
|
+
|
|
|
+ UINT32 curVertexOffset = 0;
|
|
|
+ UINT32 curIndexOffet = 0;
|
|
|
+
|
|
|
+ auto positionIter = meshData->getVec3DataIter(VES_POSITION);
|
|
|
+ auto normalIter = meshData->getVec3DataIter(VES_NORMAL);
|
|
|
+ auto colorIter = meshData->getDWORDDataIter(VES_COLOR);
|
|
|
+
|
|
|
+ for (UINT32 i = batch.startIdx; i <= batch.endIdx; i++)
|
|
|
+ {
|
|
|
+ RawData& shapeData = allShapes[i];
|
|
|
+
|
|
|
+ Matrix4* transform = nullptr;
|
|
|
+ RGBA color = 0;
|
|
|
+
|
|
|
+ switch (shapeData.shapeType)
|
|
|
+ {
|
|
|
+ case ShapeType::Cube:
|
|
|
+ {
|
|
|
+ CubeData& cubeData = mSolidCubeData[shapeData.idx];
|
|
|
+ AABox box(cubeData.position - cubeData.extents, cubeData.position + cubeData.extents);
|
|
|
+ ShapeMeshes3D::solidAABox(box, meshData, curVertexOffset, curIndexOffet);
|
|
|
+
|
|
|
+ transform = &cubeData.transform;
|
|
|
+ color = cubeData.color.getAsRGBA();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case ShapeType::Sphere:
|
|
|
+ {
|
|
|
+ SphereData& sphereData = mSolidSphereData[shapeData.idx];
|
|
|
+ Sphere sphere(sphereData.position, sphereData.radius);
|
|
|
+ ShapeMeshes3D::solidSphere(sphere, meshData, curVertexOffset, curIndexOffet, sphereData.quality);
|
|
|
+
|
|
|
+ transform = &sphereData.transform;
|
|
|
+ color = sphereData.color.getAsRGBA();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case ShapeType::Cone:
|
|
|
+ {
|
|
|
+ ConeData& coneData = mConeData[shapeData.idx];
|
|
|
+ ShapeMeshes3D::solidCone(coneData.base, coneData.normal, coneData.height, coneData.radius,
|
|
|
+ meshData, curVertexOffset, curIndexOffet, coneData.quality);
|
|
|
+
|
|
|
+ transform = &coneData.transform;
|
|
|
+ color = coneData.color.getAsRGBA();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case ShapeType::Disc:
|
|
|
+ {
|
|
|
+ DiscData& discData = mDiscData[shapeData.idx];
|
|
|
+ ShapeMeshes3D::solidDisc(discData.position, discData.radius, discData.normal,
|
|
|
+ meshData, curVertexOffset, curIndexOffet, discData.quality);
|
|
|
+
|
|
|
+ transform = &discData.transform;
|
|
|
+ color = discData.color.getAsRGBA();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case ShapeType::Arc:
|
|
|
+ {
|
|
|
+ ArcData& arcData = mArcData[shapeData.idx];
|
|
|
+ ShapeMeshes3D::solidArc(arcData.position, arcData.radius, arcData.normal,
|
|
|
+ arcData.startAngle, arcData.amountAngle, meshData, curVertexOffset, curIndexOffet, arcData.quality);
|
|
|
+
|
|
|
+ transform = &arcData.transform;
|
|
|
+ color = arcData.color.getAsRGBA();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case ShapeType::Rectangle:
|
|
|
+ {
|
|
|
+ Rect3Data rectData = mRect3Data[shapeData.idx];
|
|
|
+ ShapeMeshes3D::solidQuad(rectData.area, meshData, curVertexOffset, curIndexOffet);
|
|
|
+
|
|
|
+ transform = &rectData.transform;
|
|
|
+ color = rectData.color.getAsRGBA();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ Matrix4 transformIT = transform->inverseAffine().transpose();
|
|
|
+ for (UINT32 i = 0; i < shapeData.numVertices; i++)
|
|
|
+ {
|
|
|
+ Vector3 worldPos = transform->multiply3x4(positionIter.getValue());
|
|
|
+ Vector3 worldNormal = transformIT.multiply3x4(normalIter.getValue());
|
|
|
+
|
|
|
+ positionIter.addValue(worldPos);
|
|
|
+ normalIter.addValue(worldNormal);
|
|
|
+ colorIter.addValue(color);
|
|
|
+ }
|
|
|
+
|
|
|
+ curVertexOffset += shapeData.numVertices;
|
|
|
+ curIndexOffet += shapeData.numIndices;
|
|
|
+ }
|
|
|
+
|
|
|
+ mMeshes.push_back(ShapeMeshData());
|
|
|
+ ShapeMeshData& newMesh = mMeshes.back();
|
|
|
+ newMesh.mesh = mSolidMeshHeap->alloc(meshData, DOT_TRIANGLE_LIST);
|
|
|
+ newMesh.type = MeshType::Solid;
|
|
|
+ }
|
|
|
+ else // Wire
|
|
|
+ {
|
|
|
+ MeshDataPtr meshData = bs_shared_ptr<MeshData>(batch.numVertices,
|
|
|
+ batch.numIndices, mWireVertexDesc);
|
|
|
+
|
|
|
+ UINT32 curVertexOffset = 0;
|
|
|
+ UINT32 curIndexOffet = 0;
|
|
|
+
|
|
|
+ auto positionIter = meshData->getVec3DataIter(VES_POSITION);
|
|
|
+ auto colorIter = meshData->getDWORDDataIter(VES_COLOR);
|
|
|
+
|
|
|
+ for (UINT32 i = batch.startIdx; i <= batch.endIdx; i++)
|
|
|
+ {
|
|
|
+ RawData& shapeData = allShapes[i];
|
|
|
+
|
|
|
+ Matrix4* transform = nullptr;
|
|
|
+ RGBA color = 0;
|
|
|
+
|
|
|
+ switch (shapeData.shapeType)
|
|
|
+ {
|
|
|
+ case ShapeType::WireCube:
|
|
|
+ {
|
|
|
+ CubeData& cubeData = mWireCubeData[shapeData.idx];
|
|
|
+
|
|
|
+ AABox box(cubeData.position - cubeData.extents, cubeData.position + cubeData.extents);
|
|
|
+ ShapeMeshes3D::wireAABox(box, meshData, curVertexOffset, curIndexOffet);
|
|
|
+
|
|
|
+ transform = &cubeData.transform;
|
|
|
+ color = cubeData.color.getAsRGBA();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case ShapeType::WireSphere:
|
|
|
+ {
|
|
|
+ SphereData& sphereData = mWireSphereData[shapeData.idx];
|
|
|
+
|
|
|
+ Sphere sphere(sphereData.position, sphereData.radius);
|
|
|
+ ShapeMeshes3D::wireSphere(sphere, meshData, curVertexOffset, curIndexOffet, sphereData.quality);
|
|
|
+
|
|
|
+ transform = &sphereData.transform;
|
|
|
+ color = sphereData.color.getAsRGBA();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case ShapeType::Line:
|
|
|
+ {
|
|
|
+ LineData& lineData = mLineData[shapeData.idx];
|
|
|
+
|
|
|
+ ShapeMeshes3D::pixelLine(lineData.start, lineData.end, meshData, curVertexOffset, curIndexOffet);
|
|
|
+
|
|
|
+ transform = &lineData.transform;
|
|
|
+ color = lineData.color.getAsRGBA();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case ShapeType::Frustum:
|
|
|
+ {
|
|
|
+ FrustumData& frustumData = mFrustumData[shapeData.idx];
|
|
|
+
|
|
|
+ ShapeMeshes3D::wireFrustum(frustumData.position, frustumData.aspect, frustumData.FOV, frustumData.near,
|
|
|
+ frustumData.far, meshData, curVertexOffset, curIndexOffet);
|
|
|
+
|
|
|
+ transform = &frustumData.transform;
|
|
|
+ color = frustumData.color.getAsRGBA();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case ShapeType::WireDisc:
|
|
|
+ {
|
|
|
+ DiscData& discData = mWireDiscData[shapeData.idx];
|
|
|
+
|
|
|
+ ShapeMeshes3D::wireDisc(discData.position, discData.radius, discData.normal,
|
|
|
+ meshData, curVertexOffset, curIndexOffet, discData.quality);
|
|
|
+
|
|
|
+ transform = &discData.transform;
|
|
|
+ color = discData.color.getAsRGBA();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case ShapeType::WireArc:
|
|
|
+ {
|
|
|
+ ArcData& arcData = mWireArcData[shapeData.idx];
|
|
|
+
|
|
|
+ ShapeMeshes3D::wireArc(arcData.position, arcData.radius, arcData.normal,
|
|
|
+ arcData.startAngle, arcData.amountAngle, meshData, curVertexOffset, curIndexOffet, arcData.quality);
|
|
|
+
|
|
|
+ transform = &arcData.transform;
|
|
|
+ color = arcData.color.getAsRGBA();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (UINT32 i = 0; i < shapeData.numVertices; i++)
|
|
|
+ {
|
|
|
+ Vector3 worldPos = transform->multiply3x4(positionIter.getValue());
|
|
|
+
|
|
|
+ positionIter.addValue(worldPos);
|
|
|
+ colorIter.addValue(color);
|
|
|
+ }
|
|
|
+
|
|
|
+ curVertexOffset += shapeData.numVertices;
|
|
|
+ curIndexOffet += shapeData.numIndices;
|
|
|
+ }
|
|
|
+
|
|
|
+ mMeshes.push_back(ShapeMeshData());
|
|
|
+ ShapeMeshData& newMesh = mMeshes.back();
|
|
|
+ newMesh.mesh = mWireMeshHeap->alloc(meshData, DOT_LINE_LIST);
|
|
|
+ newMesh.type = MeshType::Wire;
|
|
|
}
|
|
|
-
|
|
|
- curVertexOffset += numVertices;
|
|
|
- curIndexOffet += numIndices;
|
|
|
}
|
|
|
-
|
|
|
- return mWireMeshHeap->alloc(meshData, DOT_LINE_LIST);
|
|
|
}
|
|
|
|
|
|
- void DrawHelper::releaseSolidMesh(const TransientMeshPtr& mesh)
|
|
|
+ void DrawHelper::clearMeshes()
|
|
|
{
|
|
|
- mSolidMeshHeap->dealloc(mesh);
|
|
|
- }
|
|
|
+ for (auto meshData : mMeshes)
|
|
|
+ {
|
|
|
+ if (meshData.type == MeshType::Solid)
|
|
|
+ mSolidMeshHeap->dealloc(meshData.mesh);
|
|
|
+ else
|
|
|
+ mWireMeshHeap->dealloc(meshData.mesh);
|
|
|
+ }
|
|
|
|
|
|
- void DrawHelper::releaseWireMesh(const TransientMeshPtr& mesh)
|
|
|
- {
|
|
|
- mWireMeshHeap->dealloc(mesh);
|
|
|
+ mMeshes.clear();
|
|
|
}
|
|
|
}
|