Skip to content

Instantly share code, notes, and snippets.

@victorholt
Last active November 27, 2017 00:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save victorholt/926bdb48f40bb8a27cd613ed8e94fc99 to your computer and use it in GitHub Desktop.
Save victorholt/926bdb48f40bb8a27cd613ed8e94fc99 to your computer and use it in GitHub Desktop.
CustomMesh Header
//
// Created by Victor Holt on 3/18/2017.
// Reference: (rbnpontes) http://discourse.urho3d.io/t/a-mesh-generator/2361
//
#pragma once
#include <GameSencha/Common/GameSenchaBasePCH.h>
gs_nsstart
#define CM_MAX_FACES_PER_GEOM_SM 500
#define CM_MAX_FACES_PER_GEOM_LG 25000
enum class MeshUVType {
UV_XY = 0,
UV_XZ,
UV_YZ,
UV_ZY
};
struct GAMESENCHA_API MeshVertex {
Vector3 vertex_;
Vector3 normal_;
Vector2 uv_;
Vector2 uv2_;
Vector4 tangent_;
Color color_;
MeshUVType uvType_;
};
struct GAMESENCHA_API MeshFace {
unsigned vertIndexStart_;
MeshVertex* v0_;
MeshVertex* v1_;
MeshVertex* v2_;
};
struct GAMESENCHA_API MeshGeomData {
/// Geometry index in the mesh.
uint32_t geomIndex_;
/// Check if this geometry data is dirty.
bool isDirty_ = false;
/// Faces for the mesh.
PODVector<MeshFace*> faces_;
/// Vertex data of the mesh.
PODVector<MeshVertex*> meshVertexList_;
/// Vertex data of the mesh.
PODVector<float> vertexData_;
/// Index data of the mesh.
PODVector<uint16_t> indexData_;
/// Large index data.
PODVector<uint32_t> largeIndexData_;
/// Geometry of the mesh.
SharedPtr<Geometry> geometry_;
/// Vertex buffer of the mesh.
SharedPtr<VertexBuffer> vertexBuffer_;
/// Index buffer of the mesh.
SharedPtr<IndexBuffer> indexBuffer_;
MeshGeomData(uint32_t geomIndex) {
geomIndex_ = geomIndex;
geometry_ = nullptr;
vertexBuffer_ = nullptr;
indexBuffer_ = nullptr;
}
~MeshGeomData() {
// Delete the faces.
for (auto face : faces_) {
delete face;
}
faces_.Clear();
for (auto vert : meshVertexList_) {
delete vert;
}
meshVertexList_.Clear();
vertexData_.Clear();
indexData_.Clear();
}
};
class GAMESENCHA_API CustomMesh : public Object
{
URHO3D_OBJECT(CustomMesh, Object);
public:
//! Constructor.
//! \param context
//! \param isDynamic
CustomMesh(Context* context, bool isDynamic);
//! Destructor.
virtual ~CustomMesh();
//! Adds a face to the mesh.
//! \param v0
//! \param v1
//! \param v2
//! \param uvType
MeshFace* AddFace(const Vector3& v0, const Vector3& v1, const Vector3& v2, const MeshUVType& uvType = MeshUVType::UV_XZ);
//! Adds an index.
//! \param index
void AddIndex(uint16_t index);
//! Adds an index.
//! \param index
void AddLargeIndex(uint32_t index);
//! Commits changes to the mesh.
//! \param updateNormals
//! \param updateTangents
void Commit(bool updateNormals = false, bool updateTangents = false, bool updateMesh = true);
//! Calculates the mesh normals.
//! \param check
void CalculateNormals(bool check = true);
//! Calculates the mesh tangents.
//! \param check
void CalculateTangents(bool check = true);
//! Updates the texture coordinates.
void UpdateTexCoords();
//! Updates the bounding box for the mesh.
void UpdateBoundingBox();
//! Clears all vertex data of the mesh.
void Clear();
//! Saves the mesh to a file.
//! \param path
void Save(const String& path);
//! Save the lightmap for this mesh.
//! \param path
void SaveLightmapTexture(const String& path);
//! Returns the mesh geometry.
//! \return
Geometry* GetGeometry(uint32_t index);
//! Returns the mesh model.
//! \return
Model* GetModel();
//! Returns a face at the given index.
//! \param geomIndex
//! \param faceIndex
//! \return
MeshFace* GetFace(uint32_t geomIndex, uint32_t faceIndex);
//! Pushes a new geometry object onto the mesh.
void PushGeometry();
//! Sets the scale of the mesh.
//! \param scale
inline void SetScale(float scale) {
scale_ = scale;
}
//! Returns the scale of the mesh.
//! \return
inline float GetScale() const {
return scale_;
}
//! Flag to use large indices.
//! \param useLargeIndices
inline void SetUseLargeIndices(bool useLargeIndices) {
maxFaceCount_ = useLargeIndices ? CM_MAX_FACES_PER_GEOM_LG : CM_MAX_FACES_PER_GEOM_SM;
useLargeIndices_ = useLargeIndices;
}
//! Sets the max face count.
//! \param maxFaceCount
inline void SetMaxFaceCount(uint32_t maxFaceCount) {
maxFaceCount_ = maxFaceCount;
}
//! Rotates a mesh face.
//! \param face
//! \param rot
void RotateFace(MeshFace* face, const Quaternion& rot);
//! Rotates a mesh face.
//! \param geomIndex
//! \param faceIndex
//! \param rot
void RotateFaceByIndex(uint32_t geomIndex, unsigned faceIndex, const Quaternion& rot);
//! Rotates the mesh by the given rotation.
//! \param rot
void Rotate(const Quaternion& rot);
//! Returns the bounding box.
//! \return
inline const BoundingBox& GetBoundingBox() const { return boundingBox_; }
//! Returns the number of faces.
//! \return
inline unsigned GetNumFaces() const { return faceCount_; }
//! Returns the number of vertices.
//! \return
inline unsigned GetNumVerts() const { return vertexCount_; }
//! Returns the number of indices.
//! \return
inline unsigned GetNumIndices() const { return indexCount_; }
//! Adds a variable.
//! \param name
//! \param value
inline void AddVar(const String& name, const Variant& value) {
vars_.Populate(name, value);
}
//! Returns a variable.
//! \param name
//! \param dest
inline void GetVar(const String& name, Variant& dest) {
auto var = vars_.Find(name);
if (var != vars_.End()) {
dest = var->second_;
}
}
//! Use the uv2 coords.
//! \param useUV2
inline void SetUseUV2(bool useUV2) {
useUV2_ = useUV2;
}
protected:
//! Adds a vertex.
//! \param v
//! \param uvType
MeshVertex* AddVertex(const Vector3& v, const MeshUVType& uvType = MeshUVType::UV_XZ);
//! Builds the mesh.
//! \param geomData
//! \param updateNormals
//! \param updateTangents
//! \param updateMesh
void CreateMesh(MeshGeomData* geomData, bool updateNormals, bool updateTangents, bool updateMesh = true);
//! Generates the vertex data.
void GenerateVertexData(MeshGeomData* geomData);
//! Updates the vertex data.
void UpdateVertexData(MeshGeomData* geomData);
//! Creates a new face.
//! \param v0
//! \param v1
//! \param v2
//! \return
MeshFace* CreateFace(MeshVertex* v0, MeshVertex* v1, MeshVertex* v2);
//! Updates the mesh.
//! \param geomData
//! \param updateNormals
//! \param updateTangents
//! \param updateMesh
void UpdateMesh(MeshGeomData* geomData, bool updateNormals, bool updateTangents, bool updateMesh = true);
//! Calculates the mesh normals.
//! \param check
void CalculateNormals(MeshGeomData* geomData, bool check);
//! Calculates the mesh tangents.
//! \param check
void CalculateTangents(MeshGeomData* geomData, bool check);
protected:
/// Number of faces created.
uint32_t faceCount_ = 0;
/// Relative face count when create geometry data.
uint32_t relFaceCount_ = 0;
/// Number of vertices created.
uint32_t vertexCount_ = 0;
/// Number of indices created.
uint32_t indexCount_ = 0;
/// Current geometry index.
uint32_t currentGeomIndex_ = 0;
/// Max face count for the mesh.
uint32_t maxFaceCount_;
/// The scale of the mesh.
float scale_;
/// Flag for if this is a dynamic mesh.
bool isDynamic_;
/// Flag to calculate the normals.
bool calcNormals_;
/// Flag to calculate the tangents.
bool calcTangents_;
/// Flag to use large indices.
bool useLargeIndices_;
/// Flag to manually add indices.
bool manualAddIndex_;
/// Flag to use uv2 coords.
bool useUV2_ = false;
/// Model of the mesh.
SharedPtr<Model> model_;
/// Geometry data.
PODVector<MeshGeomData*> geomData_;
/// Reference to the bounding box.
BoundingBox boundingBox_;
/// Mutex for the mesh.
Mutex meshLock_;
/// Mutex for calculations.
Mutex calcMeshLock_;
/// Variables associated with the mesh.
HashMap<String, Variant> vars_;
/// Transform for the mesh.
Matrix3x4 transform_;
};
gs_nsend
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment