| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418 |
- #include "BsDrawHelper3D.h"
- #include "BsRectF.h"
- #include "BsMesh.h"
- #include "BsTime.h"
- #include "BsVector2.h"
- #include "BsMaterial.h"
- #include "BsPass.h"
- #include "BsCoreApplication.h"
- #include "BsRenderQueue.h"
- #include "BsException.h"
- #include "BsCamera.h"
- #include "BsBuiltinResources.h"
- #include "BsVertexDataDesc.h"
- namespace BansheeEngine
- {
- DrawHelper3D::DrawHelper3D()
- {
- mVertexDesc = bs_shared_ptr<VertexDataDesc>();
- mVertexDesc->addVertElem(VET_FLOAT2, VES_POSITION);
- mVertexDesc->addVertElem(VET_COLOR, VES_COLOR);
- }
- void DrawHelper3D::aabox(const AABox& box, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
- {
- UINT32* indexData = meshData->getIndices32();
- UINT8* positionData = meshData->getElementData(VES_POSITION);
- assert((vertexOffset + 8) <= meshData->getNumVertices());
- assert((indexOffset + 36) <= meshData->getNumIndices());
- aabox(box, positionData, vertexOffset, meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset);
- }
- void DrawHelper3D::line_Pixel(const Vector3& a, const Vector3& b, const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
- {
- DrawHelperTemplate<Vector3>::line_Pixel(a, b, color, meshData, vertexOffset, indexOffset);
- }
- void DrawHelper3D::line_AA(const Vector3& a, const Vector3& b, const Vector3& up, float width, float borderWidth,
- const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
- {
- DrawHelperTemplate<Vector3>::line_AA(a, b, up, width, borderWidth, color, meshData, vertexOffset, indexOffset);
- }
- void DrawHelper3D::lineList_Pixel(const Vector<Vector3>& linePoints, const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
- {
- DrawHelperTemplate<Vector3>::lineList_Pixel(linePoints, color, meshData, vertexOffset, indexOffset);
- }
- void DrawHelper3D::lineList_AA(const Vector<Vector3>& linePoints, const Vector3& up, float width, float borderWidth,
- const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
- {
- DrawHelperTemplate<Vector3>::lineList_AA(linePoints, up, width, borderWidth, color, meshData, vertexOffset, indexOffset);
- }
- /************************************************************************/
- /* DRAW */
- /************************************************************************/
- void DrawHelper3D::drawLine_Pixel(const HCamera& camera, const Vector3& a, const Vector3& b, const Color& color, float timeout)
- {
- const Viewport* viewport = camera->getViewport().get();
- Vector<DebugDrawCommand>& commands = mCommandsPerViewport[viewport];
- commands.push_back(DebugDrawCommand());
- DebugDrawCommand& dbgCmd = commands.back();
- dbgCmd.endTime = gTime().getTime() + timeout;
- MeshDataPtr meshData = bs_shared_ptr<MeshData, ScratchAlloc>(2, 2, mVertexDesc);
- line_Pixel(a, b, color, meshData, 0, 0);
- UINT8* positionData = meshData->getElementData(VES_POSITION);
- dbgCmd.worldCenter = calcCenter(positionData, meshData->getNumVertices(), mVertexDesc->getVertexStride());
- HMesh mesh = Mesh::create(meshData, MeshBufferType::Static, DOT_LINE_LIST);
- dbgCmd.mesh = mesh;
- dbgCmd.type = DebugDrawType::WorldSpace;
- dbgCmd.matInfo3D = BuiltinResources::instance().createDebugDraw3DMaterial();
- }
- void DrawHelper3D::drawLine_AA(const HCamera& camera, const Vector3& a, const Vector3& b, const Vector3& up, float width, float borderWidth, const Color& color, float timeout)
- {
- const Viewport* viewport = camera->getViewport().get();
- Vector<DebugDrawCommand>& commands = mCommandsPerViewport[viewport];
- commands.push_back(DebugDrawCommand());
- DebugDrawCommand& dbgCmd = commands.back();
- dbgCmd.endTime = gTime().getTime() + timeout;
- MeshDataPtr meshData = bs_shared_ptr<MeshData, ScratchAlloc>(8, 30, mVertexDesc);
- line_AA(a, b, up, width, borderWidth, color, meshData, 0, 0);
- UINT8* positionData = meshData->getElementData(VES_POSITION);
- dbgCmd.worldCenter = calcCenter(positionData, meshData->getNumVertices(), mVertexDesc->getVertexStride());
- HMesh mesh = Mesh::create(meshData);
- dbgCmd.mesh = mesh;
- dbgCmd.type = DebugDrawType::WorldSpace;
- dbgCmd.matInfo3D = BuiltinResources::instance().createDebugDraw3DMaterial();
- }
- void DrawHelper3D::drawLineList_Pixel(const HCamera& camera, const Vector<Vector3>& linePoints, const Color& color, float timeout)
- {
- const Viewport* viewport = camera->getViewport().get();
- Vector<DebugDrawCommand>& commands = mCommandsPerViewport[viewport];
- commands.push_back(DebugDrawCommand());
- DebugDrawCommand& dbgCmd = commands.back();
- dbgCmd.endTime = gTime().getTime() + timeout;
- MeshDataPtr meshData = bs_shared_ptr<MeshData, ScratchAlloc>(
- (UINT32)(linePoints.size() * 2), (UINT32)(linePoints.size() * 2), mVertexDesc);
- lineList_Pixel(linePoints, color, meshData, 0, 0);
- UINT8* positionData = meshData->getElementData(VES_POSITION);
- dbgCmd.worldCenter = calcCenter(positionData, meshData->getNumVertices(), mVertexDesc->getVertexStride());
- HMesh mesh = Mesh::create(meshData, MeshBufferType::Static, DOT_LINE_LIST);
- dbgCmd.mesh = mesh;
- dbgCmd.type = DebugDrawType::WorldSpace;
- dbgCmd.matInfo3D = BuiltinResources::instance().createDebugDraw3DMaterial();
- }
- void DrawHelper3D::drawLineList_AA(const HCamera& camera, const Vector<Vector3>& linePoints, const Vector3& up, float width, float borderWidth,
- const Color& color, float timeout)
- {
- const Viewport* viewport = camera->getViewport().get();
- Vector<DebugDrawCommand>& commands = mCommandsPerViewport[viewport];
- commands.push_back(DebugDrawCommand());
- DebugDrawCommand& dbgCmd = commands.back();
- dbgCmd.endTime = gTime().getTime() + timeout;
- MeshDataPtr meshData = bs_shared_ptr<MeshData, ScratchAlloc>((UINT32)(linePoints.size() * 4), (UINT32)(linePoints.size() * 15), mVertexDesc);
- lineList_AA(linePoints, up, width, borderWidth, color, meshData, 0, 0);
- UINT8* positionData = meshData->getElementData(VES_POSITION);
- dbgCmd.worldCenter = calcCenter(positionData, meshData->getNumVertices(), mVertexDesc->getVertexStride());
- HMesh mesh = Mesh::create(meshData);
- dbgCmd.mesh = mesh;
- dbgCmd.type = DebugDrawType::WorldSpace;
- dbgCmd.matInfo3D = BuiltinResources::instance().createDebugDraw3DMaterial();
- }
- void DrawHelper3D::drawAABox(const HCamera& camera, const AABox& box, const Color& color, float timeout)
- {
- const Viewport* viewport = camera->getViewport().get();
- Vector<DebugDrawCommand>& commands = mCommandsPerViewport[viewport];
- commands.push_back(DebugDrawCommand());
- DebugDrawCommand& dbgCmd = commands.back();
- dbgCmd.endTime = gTime().getTime() + timeout;
- MeshDataPtr meshData = bs_shared_ptr<MeshData, ScratchAlloc>(8, 36, mVertexDesc);
- aabox(box, meshData, 0, 0);
- UINT32 vertexStride = mVertexDesc->getVertexStride();
- UINT8* colorData = meshData->getElementData(VES_COLOR);
- for(UINT32 i = 0; i < meshData->getNumVertices(); i++)
- {
- UINT32* colors = (UINT32*)colorData;
- (*colors) = color.getAsRGBA();
- colorData += vertexStride;
- }
- UINT8* positionData = meshData->getElementData(VES_POSITION);
- dbgCmd.worldCenter = calcCenter(positionData, meshData->getNumVertices(), mVertexDesc->getVertexStride());
- HMesh mesh = Mesh::create(meshData);
- dbgCmd.mesh = mesh;
- dbgCmd.type = DebugDrawType::WorldSpace;
- dbgCmd.matInfo3D = BuiltinResources::instance().createDebugDraw3DMaterial();
- }
- void DrawHelper3D::aabox(const AABox& box, UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
- {
- outVertices += (vertexOffset * vertexStride);
- Vector3 pt;
- pt = box.getCorner(AABox::FAR_LEFT_BOTTOM);
- memcpy(outVertices, &pt, sizeof(pt));
- outVertices += vertexStride;
- pt = box.getCorner(AABox::FAR_RIGHT_BOTTOM);
- memcpy(outVertices, &pt, sizeof(pt));
- outVertices += vertexStride;
- pt = box.getCorner(AABox::FAR_LEFT_TOP);
- memcpy(outVertices, &pt, sizeof(pt));
- outVertices += vertexStride;
- pt = box.getCorner(AABox::FAR_RIGHT_TOP);
- memcpy(outVertices, &pt, sizeof(pt));
- outVertices += vertexStride;
- pt = box.getCorner(AABox::NEAR_LEFT_BOTTOM);
- memcpy(outVertices, &pt, sizeof(pt));
- outVertices += vertexStride;
- pt = box.getCorner(AABox::NEAR_RIGHT_BOTTOM);
- memcpy(outVertices, &pt, sizeof(pt));
- outVertices += vertexStride;
- pt = box.getCorner(AABox::NEAR_LEFT_TOP);
- memcpy(outVertices, &pt, sizeof(pt));
- outVertices += vertexStride;
- pt = box.getCorner(AABox::NEAR_RIGHT_TOP);
- memcpy(outVertices, &pt, sizeof(pt));
- outVertices += vertexStride;
- outIndices += indexOffset;
- // Front
- outIndices[0] = vertexOffset + 6;
- outIndices[1] = vertexOffset + 7;
- outIndices[2] = vertexOffset + 5;
- outIndices[3] = vertexOffset + 6;
- outIndices[4] = vertexOffset + 5;
- outIndices[5] = vertexOffset + 4;
- // Back
- outIndices[6] = vertexOffset + 2;
- outIndices[7] = vertexOffset + 1;
- outIndices[8] = vertexOffset + 3;
- outIndices[9] = vertexOffset + 2;
- outIndices[10] = vertexOffset + 0;
- outIndices[11] = vertexOffset + 1;
- // Left
- outIndices[12] = vertexOffset + 2;
- outIndices[13] = vertexOffset + 6;
- outIndices[14] = vertexOffset + 4;
- outIndices[15] = vertexOffset + 2;
- outIndices[16] = vertexOffset + 4;
- outIndices[17] = vertexOffset + 0;
- // Right
- outIndices[18] = vertexOffset + 7;
- outIndices[19] = vertexOffset + 3;
- outIndices[20] = vertexOffset + 1;
- outIndices[21] = vertexOffset + 7;
- outIndices[22] = vertexOffset + 1;
- outIndices[23] = vertexOffset + 5;
- // Top
- outIndices[24] = vertexOffset + 6;
- outIndices[25] = vertexOffset + 2;
- outIndices[26] = vertexOffset + 3;
- outIndices[27] = vertexOffset + 6;
- outIndices[28] = vertexOffset + 3;
- outIndices[29] = vertexOffset + 7;
- // Bottom
- outIndices[30] = vertexOffset + 5;
- outIndices[31] = vertexOffset + 1;
- outIndices[32] = vertexOffset + 0;
- outIndices[33] = vertexOffset + 5;
- outIndices[34] = vertexOffset + 0;
- outIndices[35] = vertexOffset + 4;
- }
- Vector3 DrawHelper3D::calcCenter(UINT8* vertices, UINT32 numVertices, UINT32 vertexStride)
- {
- Vector3 center = Vector3::ZERO;
- for(UINT32 i = 0; i < numVertices; i++)
- {
- Vector3* curVert = (Vector3*)vertices;
- center += *curVert;
- vertices += vertexStride;
- }
- center /= (float)numVertices;
- return center;
- }
- void DrawHelper3D::line_AA(const Vector3& a, const Vector3& b, const Vector3& up, float width, float borderWidth, const Color& color, UINT8* outVertices, UINT8* outColors,
- UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
- {
- Vector3 dir = b - a;
- dir.normalize();
- Vector3 right = dir.cross(up);
- right.normalize();
- Vector<Vector3> points(4);
- float r = width * 0.5f;
- dir = dir * r;
- right = right * r;
- Vector3 v0 = a - dir - right;
- Vector3 v1 = a - dir + right;
- Vector3 v2 = b + dir + right;
- Vector3 v3 = b + dir - right;
- points[0] = v0;
- points[1] = v1;
- points[2] = v2;
- points[3] = v3;
- polygon_AA(points, up, borderWidth, color, outVertices, outColors, vertexOffset, vertexStride, outIndices, indexOffset);
- }
- void DrawHelper3D::polygon_AA(const Vector<Vector3>& points, const Vector3& up, float borderWidth, const Color& color, UINT8* outVertices, UINT8* outColors,
- UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
- {
- UINT32 numCoords = (UINT32)points.size();
- outVertices += vertexOffset * vertexStride;
- outColors += vertexOffset * vertexStride;
- Vector<Vector3> tempNormals(numCoords);
- for (UINT32 i = 0, j = numCoords - 1; i < numCoords; j = i++)
- {
- const Vector3& v0 = points[j];
- const Vector3& v1 = points[i];
- Vector3 dir = v1 - v0;
- Vector3 right = dir.cross(up);
- right.normalize();
- tempNormals[j] = right;
- // Also start populating the vertex array
- Vector3* vertices = (Vector3*)outVertices;
- *vertices = v1;
- UINT32* colors = (UINT32*)outColors;
- *colors = color.getAsRGBA();
- outVertices += vertexStride;
- outColors += vertexStride;
- }
- Color transparentColor = color;
- transparentColor.a = 0.0f;
- for (UINT32 i = 0, j = numCoords - 1; i < numCoords; j = i++)
- {
- const Vector3& n0 = tempNormals[j];
- const Vector3& n1 = tempNormals[i];
- Vector3 avgNrm = (n0 + n1) * 0.5f;
- float magSqrd = avgNrm.squaredLength();
- if (magSqrd > 0.000001f)
- {
- float scale = 1.0f / magSqrd;
- if (scale > 10.0f)
- scale = 10.0f;
- avgNrm = avgNrm * scale;
- }
- Vector3 tempCoord = points[i] + avgNrm * borderWidth;
- // Move it to the vertex array
- Vector3* vertices = (Vector3*)outVertices;
- *vertices = tempCoord;
- UINT32* colors = (UINT32*)outColors;
- *colors = transparentColor.getAsRGBA();
- outVertices += vertexStride;
- outColors += vertexStride;
- }
- // Populate index buffer
- outIndices += indexOffset;
- UINT32 idxCnt = 0;
- for (UINT32 i = 0, j = numCoords - 1; i < numCoords; j = i++)
- {
- outIndices[idxCnt++] = vertexOffset + i;
- outIndices[idxCnt++] = vertexOffset + j;
- outIndices[idxCnt++] = vertexOffset + numCoords + j;
- outIndices[idxCnt++] = vertexOffset + numCoords + j;
- outIndices[idxCnt++] = vertexOffset + numCoords + i;
- outIndices[idxCnt++] = vertexOffset + i;
- }
- for (UINT32 i = 2; i < numCoords; ++i)
- {
- outIndices[idxCnt++] = vertexOffset + 0;
- outIndices[idxCnt++] = vertexOffset + i - 1;
- outIndices[idxCnt++] = vertexOffset + i;
- }
- }
- }
|