#include "SceneThings.hpp" #include "CommonVertexIndex.hpp" #include "Rect.hpp" #include SimpleGeometryObject::SimpleGeometryObject(GameWorld* world) : GameObject(KD_SimpleGeometry, world) , mRenderObject() , mSize{ 50.0f, 50.0f, 50 } , mXFaceColor(kXAxisColor) , mYFaceColor(kYAxisColor) , mZFaceColor(kZAxisColor) , mNeedsRebuildMesh{ true } { mRenderObject.SetMaterial(gDefaultMaterial.Get()); mRenderObject.SetFormat(gVformatStandard.Get(), Tags::IT_16Bit); mRenderObject.RebuildIfNecessary(); } void SimpleGeometryObject::SetSize(glm::vec3 size) { mSize = size; mNeedsRebuildMesh = true; } void SimpleGeometryObject::SetXFaceColor(RgbaColor color) { mXFaceColor = color; mNeedsRebuildMesh = true; } void SimpleGeometryObject::SetYFaceColor(RgbaColor color) { mYFaceColor = color; mNeedsRebuildMesh = true; } void SimpleGeometryObject::SetZFaceColor(RgbaColor color) { mZFaceColor = color; mNeedsRebuildMesh = true; } std::span SimpleGeometryObject::GetRenderObjects() const { using namespace Tags; if (mNeedsRebuildMesh) { mNeedsRebuildMesh = false; Vertex_PTC vertices[4 /*vertices per face*/ * 6 /*faces*/]; uint16_t indices[3 /*indices per triangle*/ * 2 /*triangles per face*/ * 6 /*faces*/]; auto pos = GetPos(); auto extents = mSize / 2.0f; int faceGenVerticesIdx = 0; int faceGenIndicesIdx = 0; auto GenerateFace = [&](glm::vec3 faceCenter, glm::vec3 firstExtentVec, glm::vec3 secondExtentVec, RgbaColor color) { // Generates (if viewing top down on the face): bottom left, top left, bottom right, top right // (-1, -1) , (-1, 1) , (1, -1) , (1, 1) // idx=0 , idx=1 , idx=2 , idx=3 // These are index offsets, see above comment constexpr int kBottomLeft = 0; constexpr int kTopLeft = 1; constexpr int kBottomRight = 2; constexpr int kTopRight = 3; int startVertIdx = faceGenVerticesIdx; for (float firstDir : { -1, 1 }) { for (float secondDir : { -1, 1 }) { auto vertPos = faceCenter + firstExtentVec * firstDir + secondExtentVec * secondDir; auto& vert = vertices[faceGenVerticesIdx]; vert.x = vertPos.x; vert.y = vertPos.y; vert.z = vertPos.z; vert.r = color.r; vert.g = color.g; vert.b = color.b; vert.a = color.a; faceGenVerticesIdx += 1; } } // Triangle #1 indices[faceGenIndicesIdx++] = startVertIdx + kTopRight; indices[faceGenIndicesIdx++] = startVertIdx + kTopLeft; indices[faceGenIndicesIdx++] = startVertIdx + kBottomLeft; // Triangle #2 indices[faceGenIndicesIdx++] = startVertIdx + kTopRight; indices[faceGenIndicesIdx++] = startVertIdx + kBottomLeft; indices[faceGenIndicesIdx++] = startVertIdx + kBottomRight; }; for (int xDir : { -1, 1 }) { float x = pos.x + xDir * extents.x; GenerateFace(glm::vec3(x, pos.y, pos.z), glm::vec3(0, 0, extents.z), glm::vec3(0, extents.y, 0), mXFaceColor); } for (int yDir : { -1, 1 }) { float y = pos.y + yDir * extents.y; GenerateFace(glm::vec3(pos.x, y, pos.z), glm::vec3(extents.x, 0, 0), glm::vec3(0, 0, extents.z), mYFaceColor); } for (int zDir : { -1, 1 }) { float z = pos.z + zDir * extents.z; GenerateFace(glm::vec3(pos.x, pos.y, z), glm::vec3(extents.x, 0, 0), glm::vec3(0, extents.y, 0), mZFaceColor); } for (auto& vert : vertices) { vert.u = 0.0f; vert.v = 0.0f; } mRenderObject.GetVertexBufferBindings().bindings[0]->Upload((const std::byte*)vertices, sizeof(vertices)); mRenderObject.GetIndexBuffer()->Upload((const std::byte*)indices, IT_16Bit, std::size(indices)); } return { &mRenderObject, 1 }; } BuildingObject::BuildingObject(GameWorld* world) : GameObject(KD_Building, world) { mRenderObject.SetMaterial(gDefaultMaterial.Get()); mRenderObject.SetFormat(gVformatStandard.Get(), Tags::IT_32Bit); mRenderObject.RebuildIfNecessary(); } // void BuildingObject::SetMeshMaterial(Material* material) { // mMaterial.Attach(material); // // TODO update render // } // const Material* BuildingObject::GetMeshMaterial() const { // return mMaterial.Get(); // } // void BuildingObject::SetMesh(GpuMesh* mesh) { // mMesh.Attach(mesh); // // TODO update render // } // const GpuMesh* BuildingObject::GetMesh() const { // return mMesh.Get(); // } std::span BuildingObject::GetRenderObjects() const { return { &mRenderObject, 1 }; }