We can now export and import collision meshes :D
This commit is contained in:
@@ -18,8 +18,14 @@ public:
|
|||||||
~Model();
|
~Model();
|
||||||
const std::vector<RawModel::MaterialProperties>& MaterialGroups() const { return m_RawModel->m_Materials; }
|
const std::vector<RawModel::MaterialProperties>& MaterialGroups() const { return m_RawModel->m_Materials; }
|
||||||
const glm::mat4& Matrix() const { return m_RawModel->m_Matrix; }
|
const glm::mat4& Matrix() const { return m_RawModel->m_Matrix; }
|
||||||
const RawModel::Vertex* Vertices() const { return m_RawModel->Vertices(); }
|
|
||||||
unsigned int NumberOfVertices() const { return m_RawModel->NumVertices(); }
|
const RawModel::RenderVertex* Vertices() const { return m_RawModel->Vertices(); }
|
||||||
|
size_t NumberOfVertices() const { return m_RawModel->NumVertices(); }
|
||||||
|
const std::vector<unsigned int>& Indices() const { return m_RawModel->Indices(); }
|
||||||
|
|
||||||
|
const RawModel::Vertex* CollisionVertices() const { return m_RawModel->CollisionVertices(); }
|
||||||
|
const std::vector<unsigned int>& CollisionIndices() const { return m_RawModel->CollisionIndices(); }
|
||||||
|
|
||||||
const AABB& Box() const { return m_Box; }
|
const AABB& Box() const { return m_Box; }
|
||||||
bool IsSkinned() const { return m_RawModel->IsSkinned(); }
|
bool IsSkinned() const { return m_RawModel->IsSkinned(); }
|
||||||
GLuint VAO;
|
GLuint VAO;
|
||||||
|
|||||||
@@ -32,9 +32,11 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
~RawModelCustom();
|
~RawModelCustom();
|
||||||
|
struct Vertex {
|
||||||
struct Vertex
|
glm::vec3 Position;
|
||||||
{
|
};
|
||||||
|
|
||||||
|
struct RenderVertex {
|
||||||
glm::vec3 Position;
|
glm::vec3 Position;
|
||||||
glm::vec3 Normal;
|
glm::vec3 Normal;
|
||||||
glm::vec3 Tangent;
|
glm::vec3 Tangent;
|
||||||
@@ -42,7 +44,7 @@ public:
|
|||||||
glm::vec2 TextureCoords;
|
glm::vec2 TextureCoords;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SkinedVertex : public Vertex {
|
struct SkinedVertex : public RenderVertex {
|
||||||
glm::vec4 BoneIndices;
|
glm::vec4 BoneIndices;
|
||||||
glm::vec4 BoneWeights;
|
glm::vec4 BoneWeights;
|
||||||
};
|
};
|
||||||
@@ -89,7 +91,7 @@ public:
|
|||||||
MaterialBasic* material;
|
MaterialBasic* material;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Vertex* Vertices() const {
|
const RenderVertex* Vertices() const {
|
||||||
if (hasSkin) {
|
if (hasSkin) {
|
||||||
return m_SkinedVertices.data();
|
return m_SkinedVertices.data();
|
||||||
} else {
|
} else {
|
||||||
@@ -97,16 +99,16 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned int VertexSize() const {
|
unsigned int VertexSize() const {
|
||||||
if (hasSkin) {
|
if (hasSkin) {
|
||||||
return sizeof(SkinedVertex);
|
return sizeof(SkinedVertex);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return sizeof(Vertex);
|
return sizeof(RenderVertex);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned int NumVertices() const {
|
size_t NumVertices() const {
|
||||||
if (hasSkin) {
|
if (hasSkin) {
|
||||||
return m_SkinedVertices.size();
|
return m_SkinedVertices.size();
|
||||||
} else {
|
} else {
|
||||||
@@ -114,17 +116,39 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const std::vector<unsigned int>& Indices() const {
|
||||||
|
return m_Indices;
|
||||||
|
}
|
||||||
|
|
||||||
bool IsSkinned() const { return hasSkin; };
|
bool IsSkinned() const { return hasSkin; };
|
||||||
|
|
||||||
|
const Vertex* CollisionVertices();
|
||||||
|
|
||||||
|
size_t NumCollisionVertices() const {
|
||||||
|
return m_CollisionVertices.size();
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::vector<unsigned int>& CollisionIndices() const {
|
||||||
|
if (hasCollisionMesh) {
|
||||||
|
return m_CollisionIndices;
|
||||||
|
} else {
|
||||||
|
return m_Indices;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
std::vector<MaterialProperties> m_Materials;
|
std::vector<MaterialProperties> m_Materials;
|
||||||
|
|
||||||
std::vector<unsigned int> m_Indices;
|
|
||||||
Skeleton* m_Skeleton = nullptr;
|
Skeleton* m_Skeleton = nullptr;
|
||||||
glm::mat4 m_Matrix;
|
glm::mat4 m_Matrix;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool hasSkin;
|
bool hasSkin;
|
||||||
std::vector<Vertex> m_Vertices;
|
bool hasCollisionMesh = false;
|
||||||
|
std::vector<unsigned int> m_Indices;
|
||||||
|
std::vector<unsigned int> m_CollisionIndices;
|
||||||
|
std::vector<Vertex> m_CollisionVertices;
|
||||||
|
std::vector<RenderVertex> m_Vertices;
|
||||||
std::vector<SkinedVertex> m_SkinedVertices;
|
std::vector<SkinedVertex> m_SkinedVertices;
|
||||||
|
|
||||||
void ReadMeshFile(std::string filePath);
|
void ReadMeshFile(std::string filePath);
|
||||||
@@ -147,7 +171,12 @@ private:
|
|||||||
void ReadAnimationClips(std::size_t& offset, char* fileData, const unsigned int& fileByteSize, unsigned int numberOfClips);
|
void ReadAnimationClips(std::size_t& offset, char* fileData, const unsigned int& fileByteSize, unsigned int numberOfClips);
|
||||||
void ReadAnimationClipSingle(std::size_t& offset, char* fileData, const unsigned int& fileByteSize, unsigned int clipIndex);
|
void ReadAnimationClipSingle(std::size_t& offset, char* fileData, const unsigned int& fileByteSize, unsigned int clipIndex);
|
||||||
void ReadAnimationKeyFrame(std::size_t& offset, char* fileData, const unsigned int& fileByteSize, std::vector<Skeleton::Animation::Keyframe>& animation);
|
void ReadAnimationKeyFrame(std::size_t& offset, char* fileData, const unsigned int& fileByteSize, std::vector<Skeleton::Animation::Keyframe>& animation);
|
||||||
|
|
||||||
|
|
||||||
|
void ReadCollisionFile(std::string filePath);
|
||||||
|
void ReadCollisionFileData(std::size_t& offset, char* fileData, const unsigned int& fileByteSize);
|
||||||
|
|
||||||
|
const Vertex* ConstructCollisionList();
|
||||||
//void CreateSkeleton(std::vector<std::tuple<std::string, glm::mat4>> &boneInfo, std::map<std::string, int> &boneNameMapping, aiNode* node, int parentID);
|
//void CreateSkeleton(std::vector<std::tuple<std::string, glm::mat4>> &boneInfo, std::map<std::string, int> &boneNameMapping, aiNode* node, int parentID);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,7 @@
|
|||||||
<c:DashAbility/>
|
<c:DashAbility/>
|
||||||
<c:Health/>
|
<c:Health/>
|
||||||
<c:Physics>
|
<c:Physics>
|
||||||
<PrevOrigin X="0" Y="0.772000015" Z="0"/>
|
<Velocity X="0" Y="0" Z="0"/>
|
||||||
<Velocity X="2.30999646e-23" Y="0" Z="1.05272533e-23"/>
|
|
||||||
</c:Physics>
|
</c:Physics>
|
||||||
<c:Player>
|
<c:Player>
|
||||||
<MovementSpeed>5</MovementSpeed>
|
<MovementSpeed>5</MovementSpeed>
|
||||||
|
|||||||
@@ -150,6 +150,10 @@ bool RayVsModel(const Ray& ray,
|
|||||||
const std::vector<unsigned int>& modelIndices,
|
const std::vector<unsigned int>& modelIndices,
|
||||||
const glm::mat4& modelMatrix)
|
const glm::mat4& modelMatrix)
|
||||||
{
|
{
|
||||||
|
if (!modelVertices) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < modelIndices.size();) {
|
for (int i = 0; i < modelIndices.size();) {
|
||||||
glm::vec3 v0 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix);
|
glm::vec3 v0 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix);
|
||||||
glm::vec3 v1 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix);
|
glm::vec3 v1 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix);
|
||||||
@@ -201,6 +205,10 @@ bool RayVsModel(const Ray& ray,
|
|||||||
float& outUCoord,
|
float& outUCoord,
|
||||||
float& outVCoord)
|
float& outVCoord)
|
||||||
{
|
{
|
||||||
|
if (!modelVertices) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
outDistance = INFINITY;
|
outDistance = INFINITY;
|
||||||
bool hit = false;
|
bool hit = false;
|
||||||
for (int i = 0; i < modelIndices.size();) {
|
for (int i = 0; i < modelIndices.size();) {
|
||||||
@@ -226,6 +234,10 @@ bool RayVsModel(const Ray& ray,
|
|||||||
const glm::mat4& modelMatrix,
|
const glm::mat4& modelMatrix,
|
||||||
glm::vec3& outHitPosition)
|
glm::vec3& outHitPosition)
|
||||||
{
|
{
|
||||||
|
if (!modelVertices) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
float u;
|
float u;
|
||||||
float v;
|
float v;
|
||||||
float dist;
|
float dist;
|
||||||
@@ -546,6 +558,10 @@ bool AABBvsTriangles(const AABB& box,
|
|||||||
glm::vec3& outResolutionVector,
|
glm::vec3& outResolutionVector,
|
||||||
bool resolveCollision)
|
bool resolveCollision)
|
||||||
{
|
{
|
||||||
|
if (!modelVertices) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool hit = false;
|
bool hit = false;
|
||||||
|
|
||||||
bool everHitTheGround = false;
|
bool everHitTheGround = false;
|
||||||
@@ -705,7 +721,7 @@ boost::optional<EntityAABB> EntityFirstHitByRay(const Ray& ray, std::vector<Enti
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
float u, v;
|
float u, v;
|
||||||
if (RayVsModel(ray, model->Vertices(), model->m_RawModel->m_Indices, Transform::ModelMatrix(entityBox.Entity), outDistance, u, v)) {
|
if (RayVsModel(ray, model->CollisionVertices(), model->CollisionIndices(), Transform::ModelMatrix(entityBox.Entity), outDistance, u, v)) {
|
||||||
outIntersectPos = ray.Origin() + outDistance * ray.Direction();
|
outIntersectPos = ray.Origin() + outDistance * ray.Direction();
|
||||||
return entityBox;
|
return entityBox;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
float u, v;
|
float u, v;
|
||||||
hit = Collision::RayVsModel(ray, model->Vertices(), model->m_Indices, Transform::ModelMatrix(boxB.Entity), dist, u, v);
|
hit = Collision::RayVsModel(ray, model->CollisionVertices(), model->CollisionIndices(), Transform::ModelMatrix(boxB.Entity), dist, u, v);
|
||||||
} else {
|
} else {
|
||||||
hit = Collision::RayVsAABB(ray, boxB, dist);
|
hit = Collision::RayVsAABB(ray, boxB, dist);
|
||||||
}
|
}
|
||||||
@@ -88,7 +88,7 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
|
|||||||
glm::vec3 inOutVelocity = (glm::vec3)cPhysics["Velocity"];
|
glm::vec3 inOutVelocity = (glm::vec3)cPhysics["Velocity"];
|
||||||
bool isOnGround = (bool)cPhysics["IsOnGround"];
|
bool isOnGround = (bool)cPhysics["IsOnGround"];
|
||||||
float verticalStepHeight = (float)(double)cPhysics["VerticalStepHeight"];
|
float verticalStepHeight = (float)(double)cPhysics["VerticalStepHeight"];
|
||||||
if (Collision::AABBvsTriangles(boxA, model->Vertices(), model->m_Indices, modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) {
|
if (Collision::AABBvsTriangles(boxA, model->CollisionVertices(), model->CollisionIndices(), modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) {
|
||||||
(glm::vec3&)cTransform["Position"] += resolutionVector;
|
(glm::vec3&)cTransform["Position"] += resolutionVector;
|
||||||
cPhysics["Velocity"] = inOutVelocity;
|
cPhysics["Velocity"] = inOutVelocity;
|
||||||
if (isOnGround) {
|
if (isOnGround) {
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ Model::Model(std::string fileName)
|
|||||||
|
|
||||||
glGenBuffers(1, &ElementBuffer);
|
glGenBuffers(1, &ElementBuffer);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ElementBuffer);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ElementBuffer);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_RawModel->m_Indices.size() * sizeof(unsigned int), &m_RawModel->m_Indices[0], GL_STATIC_DRAW);
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_RawModel->Indices().size() * sizeof(unsigned int), m_RawModel->Indices().data(), GL_STATIC_DRAW);
|
||||||
|
|
||||||
glGenVertexArrays(1, &VAO);
|
glGenVertexArrays(1, &VAO);
|
||||||
glBindVertexArray(VAO);
|
glBindVertexArray(VAO);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ RawModelCustom::RawModelCustom(std::string fileName)
|
|||||||
ReadMeshFile(fileName);
|
ReadMeshFile(fileName);
|
||||||
ReadMaterialFile(fileName);
|
ReadMaterialFile(fileName);
|
||||||
ReadAnimationFile(fileName);
|
ReadAnimationFile(fileName);
|
||||||
|
ReadCollisionFile(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RawModelCustom::ReadMeshFile(std::string filePath)
|
void RawModelCustom::ReadMeshFile(std::string filePath)
|
||||||
@@ -71,11 +72,11 @@ void RawModelCustom::ReadVertices(std::size_t& offset, char* fileData, const uns
|
|||||||
memcpy(&m_SkinedVertices[0], fileData + offset, m_SkinedVertices.size() * sizeof(SkinedVertex));
|
memcpy(&m_SkinedVertices[0], fileData + offset, m_SkinedVertices.size() * sizeof(SkinedVertex));
|
||||||
offset += m_SkinedVertices.size() * sizeof(SkinedVertex);
|
offset += m_SkinedVertices.size() * sizeof(SkinedVertex);
|
||||||
} else {
|
} else {
|
||||||
if (offset + m_Vertices.size() * sizeof(Vertex) > fileByteSize) {
|
if (offset + m_Vertices.size() * sizeof(RenderVertex) > fileByteSize) {
|
||||||
throw Resource::FailedLoadingException("Reading vertices failed");
|
throw Resource::FailedLoadingException("Reading vertices failed");
|
||||||
}
|
}
|
||||||
memcpy(&m_Vertices[0], fileData + offset, m_Vertices.size() * sizeof(Vertex));
|
memcpy(&m_Vertices[0], fileData + offset, m_Vertices.size() * sizeof(RenderVertex));
|
||||||
offset += m_Vertices.size() * sizeof(Vertex);
|
offset += m_Vertices.size() * sizeof(RenderVertex);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
@@ -476,6 +477,84 @@ void RawModelCustom::ReadAnimationKeyFrame(std::size_t& offset, char* fileData,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RawModelCustom::ReadCollisionFile(std::string filePath) {
|
||||||
|
char* fileData;
|
||||||
|
filePath += ".colli";
|
||||||
|
std::ifstream in(filePath.c_str(), std::ios_base::binary | std::ios_base::ate);
|
||||||
|
|
||||||
|
if (!in.is_open()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unsigned int fileByteSize = static_cast<unsigned int>(in.tellg());
|
||||||
|
in.seekg(0, std::ios_base::beg);
|
||||||
|
|
||||||
|
fileData = new char[fileByteSize];
|
||||||
|
in.read(fileData, fileByteSize);
|
||||||
|
in.close();
|
||||||
|
|
||||||
|
std::size_t offset = 0;
|
||||||
|
if (fileByteSize > 0) {
|
||||||
|
ReadCollisionFileData(offset, fileData, fileByteSize);
|
||||||
|
}
|
||||||
|
hasCollisionMesh = true;
|
||||||
|
delete[] fileData;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RawModelCustom::Vertex* RawModelCustom::CollisionVertices() {
|
||||||
|
if (hasCollisionMesh) {
|
||||||
|
return m_CollisionVertices.data();
|
||||||
|
}
|
||||||
|
else if (hasSkin) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return ConstructCollisionList();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void RawModelCustom::ReadCollisionFileData(std::size_t& offset, char* fileData, const unsigned int& fileByteSize){
|
||||||
|
m_CollisionVertices.resize(static_cast<std::size_t>(*(unsigned int*)(fileData + offset)));
|
||||||
|
offset += sizeof(unsigned int);
|
||||||
|
m_CollisionIndices.resize(static_cast<std::size_t>(*(unsigned int*)(fileData + offset)));
|
||||||
|
offset += sizeof(unsigned int);
|
||||||
|
|
||||||
|
if (offset + m_CollisionVertices.size() * sizeof(Vertex) > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading collision vertices failed");
|
||||||
|
}
|
||||||
|
memcpy(&m_CollisionVertices[0], fileData + offset, m_CollisionVertices.size() * sizeof(Vertex));
|
||||||
|
offset += m_CollisionVertices.size() * sizeof(Vertex);
|
||||||
|
|
||||||
|
if (offset + m_CollisionIndices.size() * sizeof(unsigned int) > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading collision indices failed");
|
||||||
|
}
|
||||||
|
memcpy(&m_CollisionIndices[0], fileData + offset, m_CollisionIndices.size() * sizeof(unsigned int));
|
||||||
|
offset += m_CollisionIndices.size() * sizeof(unsigned int);
|
||||||
|
}
|
||||||
|
|
||||||
|
const RawModelCustom::Vertex* RawModelCustom::ConstructCollisionList()
|
||||||
|
{
|
||||||
|
if (!hasCollisionMesh && m_CollisionVertices.size() == 0) {
|
||||||
|
if (hasSkin)
|
||||||
|
{
|
||||||
|
m_CollisionVertices.reserve(m_SkinedVertices.size());
|
||||||
|
for (auto vertex : m_SkinedVertices) {
|
||||||
|
Vertex tmp;
|
||||||
|
tmp.Position = vertex.Position;
|
||||||
|
m_CollisionVertices.push_back(tmp);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_CollisionVertices.reserve(m_Vertices.size());
|
||||||
|
for (auto vertex : m_Vertices) {
|
||||||
|
Vertex tmp;
|
||||||
|
tmp.Position = vertex.Position;
|
||||||
|
m_CollisionVertices.push_back(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_CollisionVertices.data();
|
||||||
|
}
|
||||||
|
|
||||||
RawModelCustom::~RawModelCustom()
|
RawModelCustom::~RawModelCustom()
|
||||||
{
|
{
|
||||||
if (m_Skeleton != nullptr) {
|
if (m_Skeleton != nullptr) {
|
||||||
|
|||||||
@@ -109,8 +109,8 @@ bool SpawnerSystem::spawnedEntityIsColliding(EntityWrapper spawnedEntity, Entity
|
|||||||
|
|
||||||
if (model != nullptr && Collision::AABBvsTriangles(
|
if (model != nullptr && Collision::AABBvsTriangles(
|
||||||
spawnedBox,
|
spawnedBox,
|
||||||
model->Vertices(),
|
model->CollisionVertices(),
|
||||||
model->m_Indices,
|
model->CollisionIndices(),
|
||||||
Transform::ModelMatrix(otherEntity))) {
|
Transform::ModelMatrix(otherEntity))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user