mirror of
https://github.com/mwpenny/portal64-still-alive.git
synced 2024-10-20 10:37:37 -04:00
Work on room culling
This commit is contained in:
parent
22995afadf
commit
d1d8ed9b76
Binary file not shown.
|
@ -148,7 +148,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
if (args.mIsLevel) {
|
if (args.mIsLevel) {
|
||||||
std::cout << "Grouping objects by room" << std::endl;
|
std::cout << "Grouping objects by room" << std::endl;
|
||||||
RoomGenerator roomGenerator;
|
RoomGenerator roomGenerator(settings);
|
||||||
roomGenerator.TraverseScene(scene);
|
roomGenerator.TraverseScene(scene);
|
||||||
roomGenerator.GenerateDefinitions(scene, fileDef);
|
roomGenerator.GenerateDefinitions(scene, fileDef);
|
||||||
|
|
||||||
|
|
|
@ -175,6 +175,13 @@ void CFileDefinition::AddDefinition(std::unique_ptr<FileDefinition> definition)
|
||||||
mDefinitions.push_back(std::move(definition));
|
mDefinitions.push_back(std::move(definition));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string CFileDefinition::AddDataDefinition(const std::string& nameHint, const std::string& dataType, bool isArray, const std::string& location, std::unique_ptr<DataChunk> data) {
|
||||||
|
std::string name = GetUniqueName(nameHint);
|
||||||
|
std::unique_ptr<FileDefinition> def(new DataFileDefinition(dataType, name, isArray, location, std::move(data)));
|
||||||
|
AddDefinition(std::move(def));
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
void CFileDefinition::AddMacro(const std::string& name, const std::string& value) {
|
void CFileDefinition::AddMacro(const std::string& name, const std::string& value) {
|
||||||
mMacros.push_back(name + " " + value);
|
mMacros.push_back(name + " " + value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ public:
|
||||||
CFileDefinition(std::string prefix, float modelScale, aiQuaternion modelRotate);
|
CFileDefinition(std::string prefix, float modelScale, aiQuaternion modelRotate);
|
||||||
|
|
||||||
void AddDefinition(std::unique_ptr<FileDefinition> definition);
|
void AddDefinition(std::unique_ptr<FileDefinition> definition);
|
||||||
|
std::string AddDataDefinition(const std::string& nameHint, const std::string& dataType, bool isArray, const std::string& location, std::unique_ptr<DataChunk> data);
|
||||||
void AddMacro(const std::string& name, const std::string& value);
|
void AddMacro(const std::string& name, const std::string& value);
|
||||||
|
|
||||||
std::string GetVertexBuffer(std::shared_ptr<ExtendedMesh> mesh, VertexType vertexType, int textureWidth, int textureHeight, const std::string& modelSuffix);
|
std::string GetVertexBuffer(std::shared_ptr<ExtendedMesh> mesh, VertexType vertexType, int textureWidth, int textureHeight, const std::string& modelSuffix);
|
||||||
|
|
|
@ -4,165 +4,6 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#define SAME_TOLERANCE 0.00001f
|
|
||||||
|
|
||||||
bool bottomRightMost(const aiVector3D& a, const aiVector3D& b) {
|
|
||||||
if (fabs(a.x - b.x) > SAME_TOLERANCE) {
|
|
||||||
return a.x < b.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fabs(a.y - b.y) > SAME_TOLERANCE) {
|
|
||||||
return a.y < b.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.z - b.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
const aiVector3D* findMostOppositeEdge(const aiVector3D& fromEdge, const std::vector<aiVector3D>& edges) {
|
|
||||||
return std::min_element(edges.begin(), edges.end(), [=](const aiVector3D& a, const aiVector3D& b) {
|
|
||||||
return (a * fromEdge) < (b * fromEdge);
|
|
||||||
}).base();
|
|
||||||
}
|
|
||||||
|
|
||||||
CollisionQuad::CollisionQuad(aiMesh* mesh, const aiMatrix4x4& transform) {
|
|
||||||
if (mesh->mVertices) {
|
|
||||||
std::vector<aiVector3D> transformedPoints;
|
|
||||||
|
|
||||||
for (unsigned index = 0; index < mesh->mNumVertices; ++index) {
|
|
||||||
transformedPoints.push_back(transform * mesh->mVertices[index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto cornerPointer = std::min_element(transformedPoints.begin(), transformedPoints.end(), bottomRightMost);
|
|
||||||
unsigned cornerIndex = cornerPointer - transformedPoints.begin();
|
|
||||||
|
|
||||||
corner = *cornerPointer;
|
|
||||||
|
|
||||||
std::set<int> adjacentIndices;
|
|
||||||
findAdjacentVertices(mesh, cornerIndex, adjacentIndices);
|
|
||||||
|
|
||||||
std::vector<aiVector3D> edgesFromCorner;
|
|
||||||
|
|
||||||
for (auto index : adjacentIndices) {
|
|
||||||
edgesFromCorner.push_back(transformedPoints[index] - corner);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto edgeAPoint = findMostOppositeEdge(edgesFromCorner[0], edgesFromCorner);
|
|
||||||
|
|
||||||
edgeA = *edgeAPoint;
|
|
||||||
edgeALength = edgeA.Length();
|
|
||||||
edgeA.Normalize();
|
|
||||||
|
|
||||||
auto edgeBPoint = findMostOppositeEdge(edgeA, edgesFromCorner);
|
|
||||||
|
|
||||||
edgeB = *edgeBPoint;
|
|
||||||
edgeBLength = edgeB.Length();
|
|
||||||
edgeB.Normalize();
|
|
||||||
|
|
||||||
aiMatrix3x3 rotation(transform);
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < mesh->mNumVertices; ++i) {
|
|
||||||
normal += rotation * mesh->mNormals[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
normal.Normalize();
|
|
||||||
|
|
||||||
if ((edgeA ^ edgeB) * normal < 0.0f) {
|
|
||||||
aiVector3D tmpEdge = edgeA;
|
|
||||||
float tmpLength = edgeALength;
|
|
||||||
|
|
||||||
edgeA = edgeB;
|
|
||||||
edgeALength = edgeBLength;
|
|
||||||
|
|
||||||
edgeB = tmpEdge;
|
|
||||||
edgeBLength = tmpLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
corner.x = 0.001f * round(1000.0f * corner.x);
|
|
||||||
corner.y = 0.001f * round(1000.0f * corner.y);
|
|
||||||
corner.z = 0.001f * round(1000.0f * corner.z);
|
|
||||||
|
|
||||||
edgeA.x = 0.001f * round(1000.0f * edgeA.x);
|
|
||||||
edgeA.y = 0.001f * round(1000.0f * edgeA.y);
|
|
||||||
edgeA.z = 0.001f * round(1000.0f * edgeA.z);
|
|
||||||
|
|
||||||
edgeALength = 0.001f * round(1000.0f * edgeALength);
|
|
||||||
|
|
||||||
edgeB.x = 0.001f * round(1000.0f * edgeB.x);
|
|
||||||
edgeB.y = 0.001f * round(1000.0f * edgeB.y);
|
|
||||||
edgeB.z = 0.001f * round(1000.0f * edgeB.z);
|
|
||||||
|
|
||||||
edgeBLength = 0.001f * round(1000.0f * edgeBLength);
|
|
||||||
|
|
||||||
normal.x = 0.001f * round(1000.0f * normal.x);
|
|
||||||
normal.y = 0.001f * round(1000.0f * normal.y);
|
|
||||||
normal.z = 0.001f * round(1000.0f * normal.z);
|
|
||||||
} else {
|
|
||||||
corner = aiVector3D();
|
|
||||||
edgeA = aiVector3D();
|
|
||||||
edgeALength = 0.0f;
|
|
||||||
edgeB = aiVector3D();
|
|
||||||
edgeBLength = 0.0f;
|
|
||||||
normal = aiVector3D();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<DataChunk> CollisionQuad::Generate() {
|
|
||||||
std::unique_ptr<StructureDataChunk> result(new StructureDataChunk());
|
|
||||||
|
|
||||||
result->Add(std::unique_ptr<DataChunk>(new StructureDataChunk(corner)));
|
|
||||||
result->Add(std::unique_ptr<DataChunk>(new StructureDataChunk(edgeA)));
|
|
||||||
result->AddPrimitive(edgeALength);
|
|
||||||
result->Add(std::unique_ptr<DataChunk>(new StructureDataChunk(edgeB)));
|
|
||||||
result->AddPrimitive(edgeBLength);
|
|
||||||
|
|
||||||
std::unique_ptr<StructureDataChunk> plane(new StructureDataChunk());
|
|
||||||
plane->Add(std::unique_ptr<DataChunk>(new StructureDataChunk(normal)));
|
|
||||||
plane->AddPrimitive(-(corner * normal));
|
|
||||||
result->Add(std::move(plane));
|
|
||||||
|
|
||||||
result->AddPrimitive(0xF);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define FIXED_POINT_PRECISION 8
|
|
||||||
#define FIXED_POINT_SCALAR (1 << FIXED_POINT_PRECISION)
|
|
||||||
|
|
||||||
void CollisionQuad::ToLocalCoords(const aiVector3D& input, short& outX, short& outY) {
|
|
||||||
aiVector3D relative = input - corner;
|
|
||||||
|
|
||||||
outX = (short)(relative * edgeA * FIXED_POINT_SCALAR + 0.5f);
|
|
||||||
outY = (short)(relative * edgeB * FIXED_POINT_SCALAR + 0.5f);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define INSIDE_NORMAL_TOLERANCE 0.1f
|
|
||||||
|
|
||||||
bool CollisionQuad::IsCoplanar(ExtendedMesh& mesh, float relativeScale) const {
|
|
||||||
for (unsigned i = 0; i < mesh.mMesh->mNumVertices; ++i) {
|
|
||||||
aiVector3D offset = mesh.mMesh->mVertices[i] * relativeScale - corner;
|
|
||||||
|
|
||||||
float z = offset * normal;
|
|
||||||
|
|
||||||
if (fabs(z) >= INSIDE_NORMAL_TOLERANCE) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
float x = offset * edgeA;
|
|
||||||
|
|
||||||
if (x < -INSIDE_NORMAL_TOLERANCE || x > edgeALength + INSIDE_NORMAL_TOLERANCE) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
float y = offset * edgeB;
|
|
||||||
|
|
||||||
if (y < -INSIDE_NORMAL_TOLERANCE || y > edgeBLength + INSIDE_NORMAL_TOLERANCE) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CollisionGenerator::CollisionGenerator(const DisplayListSettings& settings) :
|
CollisionGenerator::CollisionGenerator(const DisplayListSettings& settings) :
|
||||||
DefinitionGenerator(),
|
DefinitionGenerator(),
|
||||||
mSettings(settings) {}
|
mSettings(settings) {}
|
||||||
|
@ -177,11 +18,7 @@ void CollisionGenerator::GenerateDefinitions(const aiScene* scene, CFileDefiniti
|
||||||
std::unique_ptr<StructureDataChunk> colliderTypeChunk(new StructureDataChunk());
|
std::unique_ptr<StructureDataChunk> colliderTypeChunk(new StructureDataChunk());
|
||||||
std::unique_ptr<StructureDataChunk> collisionObjectChunk(new StructureDataChunk());
|
std::unique_ptr<StructureDataChunk> collisionObjectChunk(new StructureDataChunk());
|
||||||
|
|
||||||
aiMatrix4x4 scale;
|
aiMatrix4x4 globalTransform = mSettings.CreateCollisionTransform();
|
||||||
aiMatrix4x4::Scaling(aiVector3D(1, 1, 1) * mSettings.mCollisionScale, scale);
|
|
||||||
aiMatrix4x4 rotation(mSettings.mRotateModel.GetMatrix());
|
|
||||||
|
|
||||||
aiMatrix4x4 globalTransform = rotation * scale;
|
|
||||||
|
|
||||||
int meshCount = 0;
|
int meshCount = 0;
|
||||||
|
|
||||||
|
|
|
@ -3,23 +3,7 @@
|
||||||
|
|
||||||
#include "DefinitionGenerator.h"
|
#include "DefinitionGenerator.h"
|
||||||
#include "../DisplayListSettings.h"
|
#include "../DisplayListSettings.h"
|
||||||
|
#include "CollisionQuad.h"
|
||||||
struct CollisionQuad {
|
|
||||||
CollisionQuad(aiMesh* mesh, const aiMatrix4x4& transform);
|
|
||||||
|
|
||||||
aiVector3D corner;
|
|
||||||
aiVector3D edgeA;
|
|
||||||
float edgeALength;
|
|
||||||
aiVector3D edgeB;
|
|
||||||
float edgeBLength;
|
|
||||||
aiVector3D normal;
|
|
||||||
|
|
||||||
std::unique_ptr<DataChunk> Generate();
|
|
||||||
|
|
||||||
void ToLocalCoords(const aiVector3D& input, short& outX, short& outY);
|
|
||||||
|
|
||||||
bool IsCoplanar(ExtendedMesh& mesh, float relativeScale) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CollisionGeneratorOutput {
|
struct CollisionGeneratorOutput {
|
||||||
std::string quadsName;
|
std::string quadsName;
|
||||||
|
|
160
skelatool64/src/definition_generator/CollisionQuad.cpp
Normal file
160
skelatool64/src/definition_generator/CollisionQuad.cpp
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
#include "CollisionQuad.h"
|
||||||
|
|
||||||
|
#define SAME_TOLERANCE 0.00001f
|
||||||
|
|
||||||
|
bool bottomRightMost(const aiVector3D& a, const aiVector3D& b) {
|
||||||
|
if (fabs(a.x - b.x) > SAME_TOLERANCE) {
|
||||||
|
return a.x < b.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fabs(a.y - b.y) > SAME_TOLERANCE) {
|
||||||
|
return a.y < b.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a.z - b.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
const aiVector3D* findMostOppositeEdge(const aiVector3D& fromEdge, const std::vector<aiVector3D>& edges) {
|
||||||
|
return std::min_element(edges.begin(), edges.end(), [=](const aiVector3D& a, const aiVector3D& b) {
|
||||||
|
return (a * fromEdge) < (b * fromEdge);
|
||||||
|
}).base();
|
||||||
|
}
|
||||||
|
|
||||||
|
CollisionQuad::CollisionQuad(aiMesh* mesh, const aiMatrix4x4& transform) {
|
||||||
|
if (mesh->mVertices) {
|
||||||
|
std::vector<aiVector3D> transformedPoints;
|
||||||
|
|
||||||
|
for (unsigned index = 0; index < mesh->mNumVertices; ++index) {
|
||||||
|
transformedPoints.push_back(transform * mesh->mVertices[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cornerPointer = std::min_element(transformedPoints.begin(), transformedPoints.end(), bottomRightMost);
|
||||||
|
unsigned cornerIndex = cornerPointer - transformedPoints.begin();
|
||||||
|
|
||||||
|
corner = *cornerPointer;
|
||||||
|
|
||||||
|
std::set<int> adjacentIndices;
|
||||||
|
findAdjacentVertices(mesh, cornerIndex, adjacentIndices);
|
||||||
|
|
||||||
|
std::vector<aiVector3D> edgesFromCorner;
|
||||||
|
|
||||||
|
for (auto index : adjacentIndices) {
|
||||||
|
edgesFromCorner.push_back(transformedPoints[index] - corner);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto edgeAPoint = findMostOppositeEdge(edgesFromCorner[0], edgesFromCorner);
|
||||||
|
|
||||||
|
edgeA = *edgeAPoint;
|
||||||
|
edgeALength = edgeA.Length();
|
||||||
|
edgeA.Normalize();
|
||||||
|
|
||||||
|
auto edgeBPoint = findMostOppositeEdge(edgeA, edgesFromCorner);
|
||||||
|
|
||||||
|
edgeB = *edgeBPoint;
|
||||||
|
edgeBLength = edgeB.Length();
|
||||||
|
edgeB.Normalize();
|
||||||
|
|
||||||
|
aiMatrix3x3 rotation(transform);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < mesh->mNumVertices; ++i) {
|
||||||
|
normal += rotation * mesh->mNormals[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
normal.Normalize();
|
||||||
|
|
||||||
|
if ((edgeA ^ edgeB) * normal < 0.0f) {
|
||||||
|
aiVector3D tmpEdge = edgeA;
|
||||||
|
float tmpLength = edgeALength;
|
||||||
|
|
||||||
|
edgeA = edgeB;
|
||||||
|
edgeALength = edgeBLength;
|
||||||
|
|
||||||
|
edgeB = tmpEdge;
|
||||||
|
edgeBLength = tmpLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
corner.x = 0.001f * round(1000.0f * corner.x);
|
||||||
|
corner.y = 0.001f * round(1000.0f * corner.y);
|
||||||
|
corner.z = 0.001f * round(1000.0f * corner.z);
|
||||||
|
|
||||||
|
edgeA.x = 0.001f * round(1000.0f * edgeA.x);
|
||||||
|
edgeA.y = 0.001f * round(1000.0f * edgeA.y);
|
||||||
|
edgeA.z = 0.001f * round(1000.0f * edgeA.z);
|
||||||
|
|
||||||
|
edgeALength = 0.001f * round(1000.0f * edgeALength);
|
||||||
|
|
||||||
|
edgeB.x = 0.001f * round(1000.0f * edgeB.x);
|
||||||
|
edgeB.y = 0.001f * round(1000.0f * edgeB.y);
|
||||||
|
edgeB.z = 0.001f * round(1000.0f * edgeB.z);
|
||||||
|
|
||||||
|
edgeBLength = 0.001f * round(1000.0f * edgeBLength);
|
||||||
|
|
||||||
|
normal.x = 0.001f * round(1000.0f * normal.x);
|
||||||
|
normal.y = 0.001f * round(1000.0f * normal.y);
|
||||||
|
normal.z = 0.001f * round(1000.0f * normal.z);
|
||||||
|
} else {
|
||||||
|
corner = aiVector3D();
|
||||||
|
edgeA = aiVector3D();
|
||||||
|
edgeALength = 0.0f;
|
||||||
|
edgeB = aiVector3D();
|
||||||
|
edgeBLength = 0.0f;
|
||||||
|
normal = aiVector3D();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<DataChunk> CollisionQuad::Generate() {
|
||||||
|
std::unique_ptr<StructureDataChunk> result(new StructureDataChunk());
|
||||||
|
|
||||||
|
result->Add(std::unique_ptr<DataChunk>(new StructureDataChunk(corner)));
|
||||||
|
result->Add(std::unique_ptr<DataChunk>(new StructureDataChunk(edgeA)));
|
||||||
|
result->AddPrimitive(edgeALength);
|
||||||
|
result->Add(std::unique_ptr<DataChunk>(new StructureDataChunk(edgeB)));
|
||||||
|
result->AddPrimitive(edgeBLength);
|
||||||
|
|
||||||
|
std::unique_ptr<StructureDataChunk> plane(new StructureDataChunk());
|
||||||
|
plane->Add(std::unique_ptr<DataChunk>(new StructureDataChunk(normal)));
|
||||||
|
plane->AddPrimitive(-(corner * normal));
|
||||||
|
result->Add(std::move(plane));
|
||||||
|
|
||||||
|
result->AddPrimitive(0xF);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FIXED_POINT_PRECISION 8
|
||||||
|
#define FIXED_POINT_SCALAR (1 << FIXED_POINT_PRECISION)
|
||||||
|
|
||||||
|
void CollisionQuad::ToLocalCoords(const aiVector3D& input, short& outX, short& outY) {
|
||||||
|
aiVector3D relative = input - corner;
|
||||||
|
|
||||||
|
outX = (short)(relative * edgeA * FIXED_POINT_SCALAR + 0.5f);
|
||||||
|
outY = (short)(relative * edgeB * FIXED_POINT_SCALAR + 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define INSIDE_NORMAL_TOLERANCE 0.1f
|
||||||
|
|
||||||
|
bool CollisionQuad::IsCoplanar(ExtendedMesh& mesh, float relativeScale) const {
|
||||||
|
for (unsigned i = 0; i < mesh.mMesh->mNumVertices; ++i) {
|
||||||
|
aiVector3D offset = mesh.mMesh->mVertices[i] * relativeScale - corner;
|
||||||
|
|
||||||
|
float z = offset * normal;
|
||||||
|
|
||||||
|
if (fabs(z) >= INSIDE_NORMAL_TOLERANCE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float x = offset * edgeA;
|
||||||
|
|
||||||
|
if (x < -INSIDE_NORMAL_TOLERANCE || x > edgeALength + INSIDE_NORMAL_TOLERANCE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float y = offset * edgeB;
|
||||||
|
|
||||||
|
if (y < -INSIDE_NORMAL_TOLERANCE || y > edgeBLength + INSIDE_NORMAL_TOLERANCE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
24
skelatool64/src/definition_generator/CollisionQuad.h
Normal file
24
skelatool64/src/definition_generator/CollisionQuad.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef __COLLISION_QUAD_H__
|
||||||
|
#define __COLLISION_QUAD_H__
|
||||||
|
|
||||||
|
#include <assimp/mesh.h>
|
||||||
|
#include "../ExtendedMesh.h"
|
||||||
|
|
||||||
|
struct CollisionQuad {
|
||||||
|
CollisionQuad(aiMesh* mesh, const aiMatrix4x4& transform);
|
||||||
|
|
||||||
|
aiVector3D corner;
|
||||||
|
aiVector3D edgeA;
|
||||||
|
float edgeALength;
|
||||||
|
aiVector3D edgeB;
|
||||||
|
float edgeBLength;
|
||||||
|
aiVector3D normal;
|
||||||
|
|
||||||
|
std::unique_ptr<DataChunk> Generate();
|
||||||
|
|
||||||
|
void ToLocalCoords(const aiVector3D& input, short& outX, short& outY);
|
||||||
|
|
||||||
|
bool IsCoplanar(ExtendedMesh& mesh, float relativeScale) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -235,6 +235,70 @@ void LevelGenerator::CalculateLocations(const aiScene* scene, CFileDefinition& f
|
||||||
fileDefinition.AddDefinition(std::move(triggersDef));
|
fileDefinition.AddDefinition(std::move(triggersDef));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LevelGenerator::CalculateDoorwaysAndRooms(const aiScene* scene, CFileDefinition& fileDefinition, std::string& doorwaysName, std::string& roomsName) {
|
||||||
|
std::vector<std::vector<int>> roomDoorways;
|
||||||
|
|
||||||
|
for (int i = 0; i < mRoomOutput.roomCount; ++i) {
|
||||||
|
roomDoorways.push_back(std::vector<int>());
|
||||||
|
}
|
||||||
|
|
||||||
|
int doorwayIndex = 0;
|
||||||
|
|
||||||
|
std::unique_ptr<StructureDataChunk> doorways(new StructureDataChunk());
|
||||||
|
|
||||||
|
for (auto& doorway : mRoomOutput.doorways) {
|
||||||
|
roomDoorways[doorway.roomA].push_back(doorwayIndex);
|
||||||
|
roomDoorways[doorway.roomB].push_back(doorwayIndex);
|
||||||
|
|
||||||
|
std::unique_ptr<StructureDataChunk> doorwayData(new StructureDataChunk());
|
||||||
|
doorwayData->Add(std::move(doorway.quad.Generate()));
|
||||||
|
doorwayData->AddPrimitive(doorway.roomA);
|
||||||
|
doorwayData->AddPrimitive(doorway.roomB);
|
||||||
|
doorways->Add(std::move(doorwayData));
|
||||||
|
|
||||||
|
++doorwayIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
doorwaysName = fileDefinition.AddDataDefinition(
|
||||||
|
"doorways",
|
||||||
|
"struct Doorway",
|
||||||
|
true,
|
||||||
|
"_geo",
|
||||||
|
std::move(doorways)
|
||||||
|
);
|
||||||
|
|
||||||
|
std::unique_ptr<StructureDataChunk> rooms(new StructureDataChunk());
|
||||||
|
|
||||||
|
for (int i = 0; i < mRoomOutput.roomCount; ++i) {
|
||||||
|
std::unique_ptr<StructureDataChunk> doorwayList(new StructureDataChunk());
|
||||||
|
|
||||||
|
for (auto doorway : roomDoorways[i]) {
|
||||||
|
doorwayList->AddPrimitive(doorway);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string doorwayListName = fileDefinition.AddDataDefinition(
|
||||||
|
"room_doorways",
|
||||||
|
"short",
|
||||||
|
true,
|
||||||
|
"_geo",
|
||||||
|
std::move(doorwayList)
|
||||||
|
);
|
||||||
|
|
||||||
|
std::unique_ptr<StructureDataChunk> room(new StructureDataChunk());
|
||||||
|
room->AddPrimitive(std::move(doorwayListName));
|
||||||
|
room->AddPrimitive(roomDoorways[i].size());
|
||||||
|
rooms->Add(std::move(room));
|
||||||
|
}
|
||||||
|
|
||||||
|
roomsName = fileDefinition.AddDataDefinition(
|
||||||
|
"rooms",
|
||||||
|
"struct Room",
|
||||||
|
true,
|
||||||
|
"_geo",
|
||||||
|
std::move(rooms)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void LevelGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& fileDefinition) {
|
void LevelGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& fileDefinition) {
|
||||||
std::string portalSurfaces;
|
std::string portalSurfaces;
|
||||||
std::string portalSurfaceMapping;
|
std::string portalSurfaceMapping;
|
||||||
|
@ -248,23 +312,31 @@ void LevelGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition&
|
||||||
|
|
||||||
std::string locations;
|
std::string locations;
|
||||||
CalculateLocations(scene, fileDefinition, locations);
|
CalculateLocations(scene, fileDefinition, locations);
|
||||||
|
|
||||||
|
std::string doorways;
|
||||||
|
std::string rooms;
|
||||||
|
CalculateDoorwaysAndRooms(scene, fileDefinition, doorways, rooms);
|
||||||
|
|
||||||
std::unique_ptr<StructureDataChunk> levelDef(new StructureDataChunk());
|
std::unique_ptr<StructureDataChunk> levelDef(new StructureDataChunk());
|
||||||
|
|
||||||
levelDef->AddPrimitive(mCollisionOutput.quadsName);
|
levelDef->AddPrimitive("collisionQuads", mCollisionOutput.quadsName);
|
||||||
levelDef->AddPrimitive(mStaticOutput.staticContentName);
|
levelDef->AddPrimitive("staticContent", mStaticOutput.staticContentName);
|
||||||
levelDef->AddPrimitive(mStaticOutput.roomMappingName);
|
levelDef->AddPrimitive("roomStaticMapping", mStaticOutput.roomMappingName);
|
||||||
levelDef->AddPrimitive(boundingBoxes);
|
levelDef->AddPrimitive("staticBoundingBoxes", boundingBoxes);
|
||||||
levelDef->AddPrimitive(portalSurfaces);
|
levelDef->AddPrimitive("portalSurfaces", portalSurfaces);
|
||||||
levelDef->AddPrimitive(portalSurfaceMapping);
|
levelDef->AddPrimitive("portalSurfaceMapping", portalSurfaceMapping);
|
||||||
levelDef->AddPrimitive(triggers);
|
levelDef->AddPrimitive("triggers", triggers);
|
||||||
levelDef->AddPrimitive(locations);
|
levelDef->AddPrimitive("locations", locations);
|
||||||
levelDef->AddPrimitive(mCollisionOutput.quads.size());
|
levelDef->AddPrimitive("rooms", rooms);
|
||||||
levelDef->AddPrimitive(mStaticOutput.staticMeshes.size());
|
levelDef->AddPrimitive("doorways", doorways);
|
||||||
levelDef->AddPrimitive(portalSurfacesCount);
|
levelDef->AddPrimitive("collisionQuadCount", mCollisionOutput.quads.size());
|
||||||
levelDef->AddPrimitive(mTriggerOutput.triggers.size());
|
levelDef->AddPrimitive("staticContentCount", mStaticOutput.staticMeshes.size());
|
||||||
levelDef->AddPrimitive(mRoomOutput.namedLocations.size());
|
levelDef->AddPrimitive("portalSurfaceCount", portalSurfacesCount);
|
||||||
levelDef->AddPrimitive(mRoomOutput.FindLocationRoom("start"));
|
levelDef->AddPrimitive("triggerCount", mTriggerOutput.triggers.size());
|
||||||
|
levelDef->AddPrimitive("locationCount", mRoomOutput.namedLocations.size());
|
||||||
|
levelDef->AddPrimitive("roomCount", mRoomOutput.roomCount);
|
||||||
|
levelDef->AddPrimitive("doorwayCount", mRoomOutput.doorways.size());
|
||||||
|
levelDef->AddPrimitive("startLocation", mRoomOutput.FindLocationRoom("start"));
|
||||||
|
|
||||||
fileDefinition.AddDefinition(std::unique_ptr<FileDefinition>(new DataFileDefinition("struct LevelDefinition", fileDefinition.GetUniqueName("level"), false, "_geo", std::move(levelDef))));
|
fileDefinition.AddDefinition(std::unique_ptr<FileDefinition>(new DataFileDefinition("struct LevelDefinition", fileDefinition.GetUniqueName("level"), false, "_geo", std::move(levelDef))));
|
||||||
}
|
}
|
|
@ -34,6 +34,8 @@ private:
|
||||||
void CalculateTriggers(const aiScene* scene, CFileDefinition& fileDefinition, std::string& triggersName);
|
void CalculateTriggers(const aiScene* scene, CFileDefinition& fileDefinition, std::string& triggersName);
|
||||||
|
|
||||||
void CalculateLocations(const aiScene* scene, CFileDefinition& fileDefinition, std::string& locationsName);
|
void CalculateLocations(const aiScene* scene, CFileDefinition& fileDefinition, std::string& locationsName);
|
||||||
|
|
||||||
|
void CalculateDoorwaysAndRooms(const aiScene* scene, CFileDefinition& fileDefinition, std::string& doorwaysName, std::string& roomsName);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -8,6 +8,15 @@
|
||||||
|
|
||||||
#define LOCATION_PREFIX "@location "
|
#define LOCATION_PREFIX "@location "
|
||||||
|
|
||||||
|
#define DOORWAY_PREFIX "@doorway"
|
||||||
|
|
||||||
|
Doorway::Doorway(const aiNode* node, const CollisionQuad& quad):
|
||||||
|
node(node), quad(quad), roomA(0), roomB(0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
RoomGenerator::RoomGenerator(const DisplayListSettings& settings): DefinitionGenerator(), mSettings(settings) {}
|
||||||
|
|
||||||
short RoomGeneratorOutput::FindLocationRoom(const std::string& name) const {
|
short RoomGeneratorOutput::FindLocationRoom(const std::string& name) const {
|
||||||
for (auto& location : namedLocations) {
|
for (auto& location : namedLocations) {
|
||||||
if (location.name == name) {
|
if (location.name == name) {
|
||||||
|
@ -39,9 +48,39 @@ void sortNodesByRoom(std::vector<aiNode*>& nodes, RoomGeneratorOutput& roomOutpu
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int findClosestRoom(const aiNode* node, const aiScene* scene, CFileDefinition& fileDefinition, const std::vector<RoomBlock>& roomBlocks, int ignoreRoom) {
|
||||||
|
float distance = INFINITY;
|
||||||
|
int closestRoom = 0;
|
||||||
|
|
||||||
|
for (auto& roomBlock : roomBlocks) {
|
||||||
|
if (roomBlock.roomIndex == ignoreRoom) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
aiVector3D localCenter;
|
||||||
|
|
||||||
|
if (node->mNumMeshes) {
|
||||||
|
auto mesh = fileDefinition.GetExtendedMesh(scene->mMeshes[node->mMeshes[0]]);
|
||||||
|
|
||||||
|
localCenter = (mesh->bbMax + mesh->bbMin) * 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float roomDistance = distanceToAABB(roomBlock.boundingBox, node->mTransformation * localCenter);
|
||||||
|
|
||||||
|
if (roomDistance < distance) {
|
||||||
|
distance = roomDistance;
|
||||||
|
closestRoom = roomBlock.roomIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return closestRoom;
|
||||||
|
}
|
||||||
|
|
||||||
void RoomGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& fileDefinition) {
|
void RoomGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& fileDefinition) {
|
||||||
std::vector<RoomBlock> roomBlocks;
|
std::vector<RoomBlock> roomBlocks;
|
||||||
|
|
||||||
|
aiMatrix4x4 collisionTransform = mSettings.CreateCollisionTransform();
|
||||||
|
|
||||||
mOutput.roomCount = 0;
|
mOutput.roomCount = 0;
|
||||||
|
|
||||||
for (auto node : mIncludedNodes) {
|
for (auto node : mIncludedNodes) {
|
||||||
|
@ -67,6 +106,13 @@ void RoomGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& f
|
||||||
|
|
||||||
mOutput.namedLocations.push_back(location);
|
mOutput.namedLocations.push_back(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (StartsWith(nodeName, DOORWAY_PREFIX) && node->mNumMeshes) {
|
||||||
|
mOutput.doorways.push_back(Doorway(node, CollisionQuad(
|
||||||
|
scene->mMeshes[node->mMeshes[0]],
|
||||||
|
collisionTransform * node->mTransformation
|
||||||
|
)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (roomBlocks.size() == 0) {
|
if (roomBlocks.size() == 0) {
|
||||||
|
@ -76,29 +122,17 @@ void RoomGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& f
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto node : mIncludedNodes) {
|
for (auto node : mIncludedNodes) {
|
||||||
float distance = INFINITY;
|
int closestRoom = findClosestRoom(node, scene, fileDefinition, roomBlocks, -1);
|
||||||
int closestRoom = 0;
|
|
||||||
|
|
||||||
for (auto& roomBlock : roomBlocks) {
|
|
||||||
aiVector3D localCenter;
|
|
||||||
|
|
||||||
if (node->mNumMeshes) {
|
|
||||||
auto mesh = fileDefinition.GetExtendedMesh(scene->mMeshes[node->mMeshes[0]]);
|
|
||||||
|
|
||||||
localCenter = (mesh->bbMax + mesh->bbMin) * 0.5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
float roomDistance = distanceToAABB(roomBlock.boundingBox, node->mTransformation * localCenter);
|
|
||||||
|
|
||||||
if (roomDistance < distance) {
|
|
||||||
distance = roomDistance;
|
|
||||||
closestRoom = roomBlock.roomIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mOutput.roomIndexMapping[node] = closestRoom;
|
mOutput.roomIndexMapping[node] = closestRoom;
|
||||||
mOutput.roomCount = std::max(mOutput.roomCount, closestRoom + 1);
|
mOutput.roomCount = std::max(mOutput.roomCount, closestRoom + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& doorway : mOutput.doorways) {
|
||||||
|
doorway.roomA = mOutput.roomIndexMapping[doorway.node];
|
||||||
|
doorway.roomB = findClosestRoom(doorway.node, scene, fileDefinition, roomBlocks, doorway.roomA);
|
||||||
|
|
||||||
|
mOutput.roomCount = std::max(mOutput.roomCount, doorway.roomB + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const RoomGeneratorOutput& RoomGenerator::GetOutput() const {
|
const RoomGeneratorOutput& RoomGenerator::GetOutput() const {
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#define __ROOM_GENERATOR_H__
|
#define __ROOM_GENERATOR_H__
|
||||||
|
|
||||||
#include "DefinitionGenerator.h"
|
#include "DefinitionGenerator.h"
|
||||||
|
#include "CollisionQuad.h"
|
||||||
|
#include "../DisplayListSettings.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
@ -11,9 +13,18 @@ struct NamedLocation {
|
||||||
int index;
|
int index;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Doorway {
|
||||||
|
Doorway(const aiNode* node, const CollisionQuad& quad);
|
||||||
|
const aiNode* node;
|
||||||
|
CollisionQuad quad;
|
||||||
|
int roomA;
|
||||||
|
int roomB;
|
||||||
|
};
|
||||||
|
|
||||||
struct RoomGeneratorOutput {
|
struct RoomGeneratorOutput {
|
||||||
std::map<const aiNode*, int> roomIndexMapping;
|
std::map<const aiNode*, int> roomIndexMapping;
|
||||||
std::vector<NamedLocation> namedLocations;
|
std::vector<NamedLocation> namedLocations;
|
||||||
|
std::vector<Doorway> doorways;
|
||||||
int roomCount;
|
int roomCount;
|
||||||
|
|
||||||
short FindLocationRoom(const std::string& name) const;
|
short FindLocationRoom(const std::string& name) const;
|
||||||
|
@ -23,11 +34,14 @@ void sortNodesByRoom(std::vector<aiNode*>& nodes, RoomGeneratorOutput& roomOutpu
|
||||||
|
|
||||||
class RoomGenerator : public DefinitionGenerator {
|
class RoomGenerator : public DefinitionGenerator {
|
||||||
public:
|
public:
|
||||||
|
RoomGenerator(const DisplayListSettings& settings);
|
||||||
|
|
||||||
virtual bool ShouldIncludeNode(aiNode* node);
|
virtual bool ShouldIncludeNode(aiNode* node);
|
||||||
virtual void GenerateDefinitions(const aiScene* scene, CFileDefinition& fileDefinition);
|
virtual void GenerateDefinitions(const aiScene* scene, CFileDefinition& fileDefinition);
|
||||||
|
|
||||||
const RoomGeneratorOutput& GetOutput() const;
|
const RoomGeneratorOutput& GetOutput() const;
|
||||||
private:
|
private:
|
||||||
|
DisplayListSettings mSettings;
|
||||||
RoomGeneratorOutput mOutput;
|
RoomGeneratorOutput mOutput;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,17 @@ struct Location {
|
||||||
short roomIndex;
|
short roomIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Doorway {
|
||||||
|
struct CollisionQuad quad;
|
||||||
|
short roomA;
|
||||||
|
short roomB;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Room {
|
||||||
|
short* doorwayIndices;
|
||||||
|
short doorwayCount;
|
||||||
|
};
|
||||||
|
|
||||||
struct LevelDefinition {
|
struct LevelDefinition {
|
||||||
struct CollisionObject* collisionQuads;
|
struct CollisionObject* collisionQuads;
|
||||||
struct StaticContentElement *staticContent;
|
struct StaticContentElement *staticContent;
|
||||||
|
@ -71,11 +82,15 @@ struct LevelDefinition {
|
||||||
struct PortalSurfaceMapping* portalSurfaceMapping;
|
struct PortalSurfaceMapping* portalSurfaceMapping;
|
||||||
struct Trigger* triggers;
|
struct Trigger* triggers;
|
||||||
struct Location* locations;
|
struct Location* locations;
|
||||||
|
struct Room* rooms;
|
||||||
|
struct Doorway* doorways;
|
||||||
short collisionQuadCount;
|
short collisionQuadCount;
|
||||||
short staticContentCount;
|
short staticContentCount;
|
||||||
short portalSurfaceCount;
|
short portalSurfaceCount;
|
||||||
short triggerCount;
|
short triggerCount;
|
||||||
short locationCount;
|
short locationCount;
|
||||||
|
short roomCount;
|
||||||
|
short doorwayCount;
|
||||||
short startLocation;
|
short startLocation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -81,14 +81,16 @@ void staticRenderSort(int min, int max) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void staticRender(struct FrustrumCullingInformation* cullingInfo, u16 startingRoom, struct RenderState* renderState) {
|
int staticRenderPopulateRooms(struct FrustrumCullingInformation* cullingInfo, int renderCount, u16 currentRoom, u32* visitedRooms) {
|
||||||
if (!gCurrentLevel) {
|
u32 roomMask = 1 << currentRoom;
|
||||||
return;
|
|
||||||
|
if (*visitedRooms & roomMask) {
|
||||||
|
return renderCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
int renderCount = 0;
|
*visitedRooms |= roomMask;
|
||||||
|
|
||||||
struct Rangeu16 staticRange = gCurrentLevel->roomStaticMapping[startingRoom];
|
struct Rangeu16 staticRange = gCurrentLevel->roomStaticMapping[currentRoom];
|
||||||
|
|
||||||
for (int i = staticRange.min; i < staticRange.max; ++i) {
|
for (int i = staticRange.min; i < staticRange.max; ++i) {
|
||||||
if (isOutsideFrustrum(cullingInfo, &gCurrentLevel->staticBoundingBoxes[i])) {
|
if (isOutsideFrustrum(cullingInfo, &gCurrentLevel->staticBoundingBoxes[i])) {
|
||||||
|
@ -100,6 +102,27 @@ void staticRender(struct FrustrumCullingInformation* cullingInfo, u16 startingRo
|
||||||
++renderCount;
|
++renderCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < gCurrentLevel->rooms[currentRoom].doorwayCount; ++i) {
|
||||||
|
struct Doorway* doorway = &gCurrentLevel->doorways[gCurrentLevel->rooms[currentRoom].doorwayIndices[i]];
|
||||||
|
|
||||||
|
if (isQuadOutsideFrustrum(cullingInfo, &doorway->quad)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderCount = staticRenderPopulateRooms(cullingInfo, renderCount, currentRoom == doorway->roomA ? doorway->roomB : doorway->roomA, visitedRooms);
|
||||||
|
};
|
||||||
|
|
||||||
|
return renderCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void staticRender(struct FrustrumCullingInformation* cullingInfo, u16 startingRoom, struct RenderState* renderState) {
|
||||||
|
if (!gCurrentLevel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 visitedRooms = 0;
|
||||||
|
int renderCount = staticRenderPopulateRooms(cullingInfo, 0, startingRoom, &visitedRooms);
|
||||||
|
|
||||||
renderCount = dynamicScenePopulate(cullingInfo, renderCount, gCurrentLevel->staticContentCount, gSortKey, gRenderOrder);
|
renderCount = dynamicScenePopulate(cullingInfo, renderCount, gCurrentLevel->staticContentCount, gSortKey, gRenderOrder);
|
||||||
|
|
||||||
staticRenderSort(0, renderCount);
|
staticRenderSort(0, renderCount);
|
||||||
|
|
|
@ -8,9 +8,11 @@ int isOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct Boundi
|
||||||
for (int i = 0; i < CLIPPING_PLANE_COUNT; ++i) {
|
for (int i = 0; i < CLIPPING_PLANE_COUNT; ++i) {
|
||||||
struct Vector3 closestPoint;
|
struct Vector3 closestPoint;
|
||||||
|
|
||||||
closestPoint.x = frustrum->clippingPlanes[i].normal.x < 0.0f ? boundingBox->minX : boundingBox->maxX;
|
struct Vector3* normal = &frustrum->clippingPlanes[i].normal;
|
||||||
closestPoint.y = frustrum->clippingPlanes[i].normal.y < 0.0f ? boundingBox->minY : boundingBox->maxY;
|
|
||||||
closestPoint.z = frustrum->clippingPlanes[i].normal.z < 0.0f ? boundingBox->minZ : boundingBox->maxZ;
|
closestPoint.x = normal->x < 0.0f ? boundingBox->minX : boundingBox->maxX;
|
||||||
|
closestPoint.y = normal->y < 0.0f ? boundingBox->minY : boundingBox->maxY;
|
||||||
|
closestPoint.z = normal->z < 0.0f ? boundingBox->minZ : boundingBox->maxZ;
|
||||||
|
|
||||||
if (planePointDistance(&frustrum->clippingPlanes[i], &closestPoint) < 0.0f) {
|
if (planePointDistance(&frustrum->clippingPlanes[i], &closestPoint) < 0.0f) {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -22,7 +24,7 @@ int isOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct Boundi
|
||||||
}
|
}
|
||||||
|
|
||||||
int isSphereOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct Vector3* scaledCenter, float scaledRadius) {
|
int isSphereOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct Vector3* scaledCenter, float scaledRadius) {
|
||||||
for (int i = 0; i < CLIPPING_PLANE_COUNT; ++i) {
|
for (int i = 0; i < CLIPPING_PLANE_COUNT; ++i) {
|
||||||
if (planePointDistance(&frustrum->clippingPlanes[i], scaledCenter) < -scaledRadius) {
|
if (planePointDistance(&frustrum->clippingPlanes[i], scaledCenter) < -scaledRadius) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -31,6 +33,27 @@ int isSphereOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int isQuadOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct CollisionQuad* quad) {
|
||||||
|
for (int i = 0; i < CLIPPING_PLANE_COUNT; ++i) {
|
||||||
|
struct Vector3* normal = &frustrum->clippingPlanes[i].normal;
|
||||||
|
float aLerp = vector3Dot(normal, &quad->edgeA) < 0.0f ? 0.0f : quad->edgeALength;
|
||||||
|
float bLerp = vector3Dot(normal, &quad->edgeB) < 0.0f ? 0.0f : quad->edgeBLength;
|
||||||
|
|
||||||
|
struct Vector3 closestPoint;
|
||||||
|
vector3AddScaled(&quad->corner, &quad->edgeA, aLerp, &closestPoint);
|
||||||
|
vector3AddScaled(&closestPoint, &quad->edgeB, bLerp, &closestPoint);
|
||||||
|
|
||||||
|
vector3Scale(&closestPoint, &closestPoint, SCENE_SCALE);
|
||||||
|
|
||||||
|
if (planePointDistance(&frustrum->clippingPlanes[i], &closestPoint) < 0.0f) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void cameraInit(struct Camera* camera, float fov, float near, float far) {
|
void cameraInit(struct Camera* camera, float fov, float near, float far) {
|
||||||
transformInitIdentity(&camera->transform);
|
transformInitIdentity(&camera->transform);
|
||||||
camera->fov = fov;
|
camera->fov = fov;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "math/transform.h"
|
#include "math/transform.h"
|
||||||
#include "math/plane.h"
|
#include "math/plane.h"
|
||||||
#include "graphics/renderstate.h"
|
#include "graphics/renderstate.h"
|
||||||
|
#include "../physics/collision_quad.h"
|
||||||
#include "../math/boxs16.h"
|
#include "../math/boxs16.h"
|
||||||
|
|
||||||
#define CLIPPING_PLANE_COUNT 5
|
#define CLIPPING_PLANE_COUNT 5
|
||||||
|
@ -27,6 +28,7 @@ struct FrustrumCullingInformation {
|
||||||
|
|
||||||
int isOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct BoundingBoxs16* boundingBox);
|
int isOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct BoundingBoxs16* boundingBox);
|
||||||
int isSphereOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct Vector3* scaledCenter, float scaledRadius);
|
int isSphereOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct Vector3* scaledCenter, float scaledRadius);
|
||||||
|
int isQuadOutsideFrustrum(struct FrustrumCullingInformation* frustrum, struct CollisionQuad* quad);
|
||||||
|
|
||||||
void cameraInit(struct Camera* camera, float fov, float near, float far);
|
void cameraInit(struct Camera* camera, float fov, float near, float far);
|
||||||
void cameraBuildViewMatrix(struct Camera* camera, float matrix[4][4]);
|
void cameraBuildViewMatrix(struct Camera* camera, float matrix[4][4]);
|
||||||
|
|
Loading…
Reference in a new issue