mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-11-22 21:02:07 +00:00
WIP: Updating code to follow laupentin's code review.
Done: - Moved custom map structures to their own objcommon header file - Updated GfxLightGridRow struct - Reverted shader_bin file path - Renamed Project Creator to BSP Creator - Removed model loading from BSP creator - Cleaned up BSP Creator and updated the names of structs WIP: - Update BSP calculation code to be more readable and use unique/shared ptrs
This commit is contained in:
@@ -158,100 +158,6 @@ namespace T6
|
|||||||
|
|
||||||
AUFT_NUM_FIELD_TYPES,
|
AUFT_NUM_FIELD_TYPES,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct customMapVertex
|
|
||||||
{
|
|
||||||
vec3_t pos;
|
|
||||||
float binormalSign;
|
|
||||||
float color[4];
|
|
||||||
float texCoord[2];
|
|
||||||
vec3_t normal;
|
|
||||||
vec3_t tangent;
|
|
||||||
unsigned int packedLmapCoord;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum CM_MATERIAL_TYPE
|
|
||||||
{
|
|
||||||
CM_MATERIAL_COLOUR,
|
|
||||||
CM_MATERIAL_TEXTURE,
|
|
||||||
CM_MATERIAL_EMPTY
|
|
||||||
};
|
|
||||||
|
|
||||||
struct customMapMaterial
|
|
||||||
{
|
|
||||||
CM_MATERIAL_TYPE materialType;
|
|
||||||
const char* materialName;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct worldSurface
|
|
||||||
{
|
|
||||||
customMapMaterial material;
|
|
||||||
|
|
||||||
//char lightmapIndex;
|
|
||||||
//char primaryLightIndex;
|
|
||||||
//char reflectionProbeIndex;
|
|
||||||
|
|
||||||
int triCount;
|
|
||||||
int firstVertexIndex;
|
|
||||||
int firstIndex_Index;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct customMapGfx
|
|
||||||
{
|
|
||||||
int vertexCount;
|
|
||||||
customMapVertex* vertices;
|
|
||||||
|
|
||||||
int indexCount;
|
|
||||||
uint16_t* indices;
|
|
||||||
|
|
||||||
int surfaceCount;
|
|
||||||
worldSurface* surfaces;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct customMapColVertex
|
|
||||||
{
|
|
||||||
vec3_t pos;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct collisionSurface
|
|
||||||
{
|
|
||||||
int triCount;
|
|
||||||
int firstVertexIndex;
|
|
||||||
int firstIndex_Index;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct customMapCol
|
|
||||||
{
|
|
||||||
int vertexCount;
|
|
||||||
customMapColVertex* vertices;
|
|
||||||
|
|
||||||
int indexCount;
|
|
||||||
uint16_t* indices;
|
|
||||||
|
|
||||||
int surfaceCount;
|
|
||||||
collisionSurface* surfaces;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct customMapModel
|
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
|
|
||||||
vec3_t origin;
|
|
||||||
vec3_t rotation; // euler rotation in degrees
|
|
||||||
float scale;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct customMapInfo
|
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
std::string bspName;
|
|
||||||
|
|
||||||
customMapGfx gfxInfo;
|
|
||||||
customMapGfx colInfo;
|
|
||||||
|
|
||||||
size_t modelCount;
|
|
||||||
customMapModel* models;
|
|
||||||
};
|
|
||||||
|
|
||||||
using AssetPhysPreset = Asset<ASSET_TYPE_PHYSPRESET, PhysPreset>;
|
using AssetPhysPreset = Asset<ASSET_TYPE_PHYSPRESET, PhysPreset>;
|
||||||
using AssetPhysConstraints = Asset<ASSET_TYPE_PHYSCONSTRAINTS, PhysConstraints>;
|
using AssetPhysConstraints = Asset<ASSET_TYPE_PHYSCONSTRAINTS, PhysConstraints>;
|
||||||
|
|||||||
@@ -1278,30 +1278,16 @@ namespace T6
|
|||||||
typedef tdef_align32(4) char aligned_byte_pointer;
|
typedef tdef_align32(4) char aligned_byte_pointer;
|
||||||
typedef tdef_align32(4) GfxCompressedLightGridCoeffs GfxCompressedLightGridCoeffs_align4;
|
typedef tdef_align32(4) GfxCompressedLightGridCoeffs GfxCompressedLightGridCoeffs_align4;
|
||||||
|
|
||||||
struct GfxLightGridUnk
|
|
||||||
{
|
|
||||||
char unknown1;
|
|
||||||
char unknown2;
|
|
||||||
char unknown3;
|
|
||||||
char unknown4;
|
|
||||||
char unknown5;
|
|
||||||
char unknown6;
|
|
||||||
char unknown7;
|
|
||||||
char unknown8;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct GfxLightGridRow
|
struct GfxLightGridRow
|
||||||
{
|
{
|
||||||
unsigned __int16 colStart;
|
uint16_t colStart;
|
||||||
unsigned __int16 colCount;
|
uint16_t colCount;
|
||||||
unsigned __int16 zStart;
|
uint16_t zStart;
|
||||||
unsigned __int16 zCount;
|
uint16_t zCount;
|
||||||
unsigned int firstEntry;
|
unsigned int firstEntry;
|
||||||
GfxLightGridUnk unk;
|
char lookupTable[1]; // The lookup table has a variable length
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct GfxLightGrid
|
struct GfxLightGrid
|
||||||
{
|
{
|
||||||
unsigned int sunPrimaryLightIndex;
|
unsigned int sunPrimaryLightIndex;
|
||||||
|
|||||||
53
src/ObjCommon/Game/T6/Maps/CustomMaps.h
Normal file
53
src/ObjCommon/Game/T6/Maps/CustomMaps.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Game/T6/T6.h"
|
||||||
|
using namespace T6;
|
||||||
|
|
||||||
|
struct CustomMapVertex
|
||||||
|
{
|
||||||
|
vec3_t pos;
|
||||||
|
vec4_t color;
|
||||||
|
vec2_t texCoord;
|
||||||
|
vec3_t normal;
|
||||||
|
vec3_t tangent;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CustomMapMaterialType
|
||||||
|
{
|
||||||
|
MATERIAL_TYPE_COLOUR,
|
||||||
|
MATERIAL_TYPE_TEXTURE,
|
||||||
|
MATERIAL_TYPE_EMPTY
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CustomMapMaterial
|
||||||
|
{
|
||||||
|
CustomMapMaterialType materialType;
|
||||||
|
std::string materialName;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CustomMapSurface
|
||||||
|
{
|
||||||
|
CustomMapMaterial material;
|
||||||
|
int triCount;
|
||||||
|
int indexOfFirstVertex;
|
||||||
|
int indexOfFirstIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CustomMapWorld
|
||||||
|
{
|
||||||
|
std::vector<CustomMapSurface> surfaces;
|
||||||
|
std::vector<CustomMapVertex> vertices;
|
||||||
|
std::vector<uint16_t> indices;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CustomMapBSP
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
std::string bspName;
|
||||||
|
|
||||||
|
CustomMapWorld gfxWorld;
|
||||||
|
CustomMapWorld colWorld;
|
||||||
|
};
|
||||||
@@ -6,11 +6,11 @@ namespace shader
|
|||||||
{
|
{
|
||||||
std::string GetFileNameForPixelShaderAssetName(const std::string& assetName)
|
std::string GetFileNameForPixelShaderAssetName(const std::string& assetName)
|
||||||
{
|
{
|
||||||
return std::format("techniquesets/shader_bin/ps_{}.cso", assetName);
|
return std::format("shader_bin/ps_{}.cso", assetName);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetFileNameForVertexShaderAssetName(const std::string& assetName)
|
std::string GetFileNameForVertexShaderAssetName(const std::string& assetName)
|
||||||
{
|
{
|
||||||
return std::format("techniquesets/shader_bin/vs_{}.cso", assetName);
|
return std::format("shader_bin/vs_{}.cso", assetName);
|
||||||
}
|
}
|
||||||
} // namespace shader
|
} // namespace shader
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
#include "ProjectCreator.h"
|
#include "BSPCreator.h"
|
||||||
|
|
||||||
#include "fbx/ufbx.h"
|
#include "fbx/ufbx.h"
|
||||||
|
#include "Game/T6/T6.h"
|
||||||
|
using namespace T6;
|
||||||
|
|
||||||
std::vector<customMapVertex> vertexVec;
|
bool addFBXMeshToWorld(ufbx_node* node,
|
||||||
std::vector<uint16_t> indexVec;
|
std::vector<CustomMapSurface>& surfaceVec,
|
||||||
std::vector<worldSurface> surfaceVec;
|
std::vector<CustomMapVertex>& vertexVec,
|
||||||
std::vector<customMapModel> modelVec;
|
std::vector<uint16_t>& indexVec,
|
||||||
bool hasTangentSpace = true;
|
bool& hasTangentSpace)
|
||||||
|
|
||||||
bool loadFBXMesh(ufbx_node* node)
|
|
||||||
{
|
{
|
||||||
if (node->attrib_type != UFBX_ELEMENT_MESH)
|
if (node->attrib_type != UFBX_ELEMENT_MESH)
|
||||||
{
|
{
|
||||||
@@ -65,15 +65,15 @@ bool loadFBXMesh(ufbx_node* node)
|
|||||||
if (meshPart->num_faces == 0)
|
if (meshPart->num_faces == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
worldSurface surface;
|
CustomMapSurface surface;
|
||||||
surface.triCount = meshPart->num_triangles;
|
surface.triCount = meshPart->num_triangles;
|
||||||
surface.firstVertexIndex = vertexVec.size();
|
surface.indexOfFirstVertex = vertexVec.size();
|
||||||
surface.firstIndex_Index = indexVec.size();
|
surface.indexOfFirstIndex = indexVec.size();
|
||||||
|
|
||||||
CM_MATERIAL_TYPE meshMaterialType;
|
CustomMapMaterialType meshMaterialType;
|
||||||
if (mesh->materials.count == 0)
|
if (mesh->materials.count == 0)
|
||||||
{
|
{
|
||||||
meshMaterialType = CM_MATERIAL_EMPTY;
|
meshMaterialType = MATERIAL_TYPE_EMPTY;
|
||||||
}
|
}
|
||||||
//else if (mesh->materials.data[i]->textures.count != 0)
|
//else if (mesh->materials.data[i]->textures.count != 0)
|
||||||
//{
|
//{
|
||||||
@@ -87,13 +87,13 @@ bool loadFBXMesh(ufbx_node* node)
|
|||||||
//}
|
//}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
meshMaterialType = CM_MATERIAL_TEXTURE;
|
meshMaterialType = MATERIAL_TYPE_TEXTURE;
|
||||||
surface.material.materialName = _strdup(mesh->materials.data[i]->name.data);
|
surface.material.materialName = _strdup(mesh->materials.data[i]->name.data);
|
||||||
}
|
}
|
||||||
surface.material.materialType = meshMaterialType;
|
surface.material.materialType = meshMaterialType;
|
||||||
|
|
||||||
size_t num_triangles = meshPart->num_triangles;
|
size_t num_triangles = meshPart->num_triangles;
|
||||||
customMapVertex* vertices = (customMapVertex*)calloc(num_triangles * 3, sizeof(customMapVertex));
|
CustomMapVertex* vertices = (CustomMapVertex*)calloc(num_triangles * 3, sizeof(CustomMapVertex));
|
||||||
size_t num_vertices = 0;
|
size_t num_vertices = 0;
|
||||||
|
|
||||||
// Reserve space for the maximum triangle indices.
|
// Reserve space for the maximum triangle indices.
|
||||||
@@ -113,7 +113,7 @@ bool loadFBXMesh(ufbx_node* node)
|
|||||||
{
|
{
|
||||||
uint32_t index = tri_indices[q];
|
uint32_t index = tri_indices[q];
|
||||||
|
|
||||||
customMapVertex* vertex = &vertices[num_vertices++];
|
CustomMapVertex* vertex = &vertices[num_vertices++];
|
||||||
|
|
||||||
//ufbx_vec3 pos = ufbx_get_vertex_vec3(&mesh->vertex_position, index);
|
//ufbx_vec3 pos = ufbx_get_vertex_vec3(&mesh->vertex_position, index);
|
||||||
//vertex->pos.x = static_cast<float>(pos.x);
|
//vertex->pos.x = static_cast<float>(pos.x);
|
||||||
@@ -128,21 +128,21 @@ bool loadFBXMesh(ufbx_node* node)
|
|||||||
|
|
||||||
switch (meshMaterialType)
|
switch (meshMaterialType)
|
||||||
{
|
{
|
||||||
case CM_MATERIAL_TEXTURE:
|
case MATERIAL_TYPE_TEXTURE:
|
||||||
case CM_MATERIAL_EMPTY:
|
case MATERIAL_TYPE_EMPTY:
|
||||||
vertex->color[0] = 1.0f;
|
vertex->color.x = 1.0f;
|
||||||
vertex->color[1] = 1.0f;
|
vertex->color.y = 1.0f;
|
||||||
vertex->color[2] = 1.0f;
|
vertex->color.z = 1.0f;
|
||||||
vertex->color[3] = 1.0f;
|
vertex->color.w = 1.0f;
|
||||||
break;
|
break;
|
||||||
case CM_MATERIAL_COLOUR:
|
case MATERIAL_TYPE_COLOUR:
|
||||||
{
|
{
|
||||||
float factor = static_cast<float>(mesh->materials.data[i]->fbx.diffuse_factor.value_real);
|
float factor = static_cast<float>(mesh->materials.data[i]->fbx.diffuse_factor.value_real);
|
||||||
ufbx_vec4 diffuse = mesh->materials.data[i]->fbx.diffuse_color.value_vec4;
|
ufbx_vec4 diffuse = mesh->materials.data[i]->fbx.diffuse_color.value_vec4;
|
||||||
vertex->color[0] = static_cast<float>(diffuse.x * factor);
|
vertex->color.x = static_cast<float>(diffuse.x * factor);
|
||||||
vertex->color[1] = static_cast<float>(diffuse.y * factor);
|
vertex->color.y = static_cast<float>(diffuse.y * factor);
|
||||||
vertex->color[2] = static_cast<float>(diffuse.z * factor);
|
vertex->color.z = static_cast<float>(diffuse.z * factor);
|
||||||
vertex->color[3] = static_cast<float>(diffuse.w * factor);
|
vertex->color.w = static_cast<float>(diffuse.w * factor);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,8 +155,8 @@ bool loadFBXMesh(ufbx_node* node)
|
|||||||
// 1.0f - uv.y reason:
|
// 1.0f - uv.y reason:
|
||||||
// https://gamedev.stackexchange.com/questions/92886/fbx-uv-coordinates-is-strange
|
// https://gamedev.stackexchange.com/questions/92886/fbx-uv-coordinates-is-strange
|
||||||
ufbx_vec2 uv = ufbx_get_vertex_vec2(&mesh->vertex_uv, index);
|
ufbx_vec2 uv = ufbx_get_vertex_vec2(&mesh->vertex_uv, index);
|
||||||
vertex->texCoord[0] = (float)(uv.x);
|
vertex->texCoord.x = (float)(uv.x);
|
||||||
vertex->texCoord[1] = (float)(1.0f - uv.y);
|
vertex->texCoord.y = (float)(1.0f - uv.y);
|
||||||
|
|
||||||
ufbx_vec3 normal = ufbx_get_vertex_vec3(&mesh->vertex_normal, index);
|
ufbx_vec3 normal = ufbx_get_vertex_vec3(&mesh->vertex_normal, index);
|
||||||
vertex->normal.x = static_cast<float>(normal.x);
|
vertex->normal.x = static_cast<float>(normal.x);
|
||||||
@@ -176,11 +176,6 @@ bool loadFBXMesh(ufbx_node* node)
|
|||||||
vertex->tangent.y = 0.0f;
|
vertex->tangent.y = 0.0f;
|
||||||
vertex->tangent.z = 0.0f;
|
vertex->tangent.z = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
vertex->packedLmapCoord = 0;
|
|
||||||
|
|
||||||
// possibly bitangent, unsure what the sign part means though
|
|
||||||
vertex->binormalSign = 0.0f;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +183,7 @@ bool loadFBXMesh(ufbx_node* node)
|
|||||||
|
|
||||||
// Generate the index buffer.
|
// Generate the index buffer.
|
||||||
ufbx_vertex_stream streams[1] = {
|
ufbx_vertex_stream streams[1] = {
|
||||||
{vertices, num_vertices, sizeof(customMapVertex)},
|
{vertices, num_vertices, sizeof(CustomMapVertex)},
|
||||||
};
|
};
|
||||||
size_t num_indices = num_triangles * 3;
|
size_t num_indices = num_triangles * 3;
|
||||||
uint32_t* indices = (uint32_t*)calloc(num_indices, sizeof(uint32_t));
|
uint32_t* indices = (uint32_t*)calloc(num_indices, sizeof(uint32_t));
|
||||||
@@ -213,120 +208,32 @@ bool loadFBXMesh(ufbx_node* node)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool loadFBXModel(ufbx_node* node)
|
void loadWorldData(ufbx_scene* scene, CustomMapBSP* bsp, bool isGfxData)
|
||||||
{
|
{
|
||||||
customMapModel model;
|
bool hasTangentSpace = true;
|
||||||
|
|
||||||
model.name = node->name.data;
|
|
||||||
|
|
||||||
model.origin.x = static_cast<float>(node->local_transform.translation.x);
|
|
||||||
model.origin.y = static_cast<float>(node->local_transform.translation.y);
|
|
||||||
model.origin.z = static_cast<float>(node->local_transform.translation.z);
|
|
||||||
model.rotation.x = static_cast<float>(node->euler_rotation.x);
|
|
||||||
model.rotation.y = static_cast<float>(node->euler_rotation.y);
|
|
||||||
model.rotation.z = static_cast<float>(node->euler_rotation.z);
|
|
||||||
model.scale = static_cast<float>(node->local_transform.scale.x);
|
|
||||||
|
|
||||||
if (model.scale == 0.0f)
|
|
||||||
{
|
|
||||||
printf("WARN: Ignoring model %s: has a scale of 0!\n", node->name.data);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node->local_transform.scale.x != node->local_transform.scale.y || node->local_transform.scale.x != node->local_transform.scale.z)
|
|
||||||
printf("WARNING: model %s uses non-uniform scaling! Only the X axis will be used for the scale value.\n", node->name.data);
|
|
||||||
modelVec.push_back(model);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void parseGFXData(ufbx_scene* scene, customMapInfo* projInfo)
|
|
||||||
{
|
|
||||||
vertexVec.clear();
|
|
||||||
indexVec.clear();
|
|
||||||
surfaceVec.clear();
|
|
||||||
modelVec.clear();
|
|
||||||
hasTangentSpace = true;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < scene->nodes.count; i++)
|
for (size_t i = 0; i < scene->nodes.count; i++)
|
||||||
{
|
{
|
||||||
ufbx_node* node = scene->nodes.data[i];
|
ufbx_node* node = scene->nodes.data[i];
|
||||||
|
|
||||||
switch (node->attrib_type)
|
if (node->attrib_type == UFBX_ELEMENT_MESH)
|
||||||
|
{
|
||||||
|
if (isGfxData)
|
||||||
|
addFBXMeshToWorld(node, bsp->gfxWorld.surfaces, bsp->gfxWorld.vertices, bsp->gfxWorld.indices, hasTangentSpace);
|
||||||
|
else
|
||||||
|
addFBXMeshToWorld(node, bsp->colWorld.surfaces, bsp->colWorld.vertices, bsp->colWorld.indices, hasTangentSpace);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
case UFBX_ELEMENT_MESH:
|
|
||||||
loadFBXMesh(node);
|
|
||||||
break;
|
|
||||||
case UFBX_ELEMENT_EMPTY:
|
|
||||||
// loadFBXModel(node);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
//printf("ignoring node type %i: %s\n", node->attrib_type, node->name.data);
|
//printf("ignoring node type %i: %s\n", node->attrib_type, node->name.data);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
projInfo->gfxInfo.surfaceCount = surfaceVec.size();
|
|
||||||
projInfo->gfxInfo.vertexCount = vertexVec.size();
|
|
||||||
projInfo->gfxInfo.indexCount = indexVec.size();
|
|
||||||
projInfo->modelCount = modelVec.size();
|
|
||||||
projInfo->gfxInfo.surfaces = new worldSurface[surfaceVec.size()];
|
|
||||||
projInfo->gfxInfo.vertices = new customMapVertex[vertexVec.size()];
|
|
||||||
projInfo->gfxInfo.indices = new uint16_t[indexVec.size()];
|
|
||||||
projInfo->models = new customMapModel[modelVec.size()];
|
|
||||||
memcpy(projInfo->gfxInfo.surfaces, &surfaceVec[0], surfaceVec.size() * sizeof(worldSurface));
|
|
||||||
memcpy(projInfo->gfxInfo.vertices, &vertexVec[0], vertexVec.size() * sizeof(customMapVertex));
|
|
||||||
memcpy(projInfo->gfxInfo.indices, &indexVec[0], indexVec.size() * sizeof(uint16_t));
|
|
||||||
// memcpy(projInfo->models, &modelVec[0], modelVec.size() * sizeof(customMapModel));
|
|
||||||
|
|
||||||
if (hasTangentSpace == false)
|
if (hasTangentSpace == false)
|
||||||
printf("warning: one or more meshes have no tangent space. Be sure to select the tangent space box when exporting the FBX from blender.\n");
|
printf("warning: one or more meshes have no tangent space. Be sure to select the tangent space box when exporting the FBX from blender.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseCollisionData(ufbx_scene* scene, customMapInfo* projInfo)
|
CustomMapBSP* BSPCreator::createCustomMapBSP(std::string& mapName, ISearchPath& searchPath)
|
||||||
{
|
|
||||||
// hack: cbf changing the code for collision data, so just load collision dada as if it was gfx data
|
|
||||||
|
|
||||||
vertexVec.clear();
|
|
||||||
indexVec.clear();
|
|
||||||
surfaceVec.clear();
|
|
||||||
modelVec.clear();
|
|
||||||
hasTangentSpace = true;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < scene->nodes.count; i++)
|
|
||||||
{
|
|
||||||
ufbx_node* node = scene->nodes.data[i];
|
|
||||||
|
|
||||||
switch (node->attrib_type)
|
|
||||||
{
|
|
||||||
case UFBX_ELEMENT_MESH:
|
|
||||||
loadFBXMesh(node);
|
|
||||||
break;
|
|
||||||
case UFBX_ELEMENT_EMPTY:
|
|
||||||
// loadFBXModel(node);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
//printf("ignoring node type %i: %s\n", node->attrib_type, node->name.data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
projInfo->colInfo.surfaceCount = surfaceVec.size();
|
|
||||||
projInfo->colInfo.vertexCount = vertexVec.size();
|
|
||||||
projInfo->colInfo.indexCount = indexVec.size();
|
|
||||||
projInfo->modelCount = modelVec.size();
|
|
||||||
projInfo->colInfo.surfaces = new worldSurface[surfaceVec.size()];
|
|
||||||
projInfo->colInfo.vertices = new customMapVertex[vertexVec.size()];
|
|
||||||
projInfo->colInfo.indices = new uint16_t[indexVec.size()];
|
|
||||||
projInfo->models = new customMapModel[modelVec.size()];
|
|
||||||
memcpy(projInfo->colInfo.surfaces, &surfaceVec[0], surfaceVec.size() * sizeof(worldSurface));
|
|
||||||
memcpy(projInfo->colInfo.vertices, &vertexVec[0], vertexVec.size() * sizeof(customMapVertex));
|
|
||||||
memcpy(projInfo->colInfo.indices, &indexVec[0], indexVec.size() * sizeof(uint16_t));
|
|
||||||
// memcpy(projInfo->models, &modelVec[0], modelVec.size() * sizeof(customMapModel));
|
|
||||||
|
|
||||||
if (hasTangentSpace == false)
|
|
||||||
printf("warning: one or more meshes have no tangent space. Be sure to select the tangent space box when exporting the FBX from blender.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
customMapInfo* ProjectCreator::createCustomMapInfo(std::string& projectName, ISearchPath& searchPath)
|
|
||||||
{
|
{
|
||||||
ufbx_scene* gfxScene;
|
ufbx_scene* gfxScene;
|
||||||
ufbx_scene* colScene;
|
ufbx_scene* colScene;
|
||||||
@@ -379,13 +286,13 @@ customMapInfo* ProjectCreator::createCustomMapInfo(std::string& projectName, ISe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customMapInfo* projInfo = new customMapInfo;
|
CustomMapBSP* projInfo = new CustomMapBSP;
|
||||||
|
|
||||||
projInfo->name = projectName;
|
projInfo->name = mapName;
|
||||||
projInfo->bspName = "maps/mp/" + projectName + ".d3dbsp";
|
projInfo->bspName = "maps/mp/" + mapName + ".d3dbsp";
|
||||||
|
|
||||||
parseGFXData(gfxScene, projInfo);
|
loadWorldData(gfxScene, projInfo, true);
|
||||||
parseCollisionData(colScene, projInfo);
|
loadWorldData(colScene, projInfo, false);
|
||||||
|
|
||||||
ufbx_free_scene(gfxScene);
|
ufbx_free_scene(gfxScene);
|
||||||
if (gfxScene != colScene)
|
if (gfxScene != colScene)
|
||||||
10
src/ObjLoading/Game/T6/CustomMap/BSPCreator.h
Normal file
10
src/ObjLoading/Game/T6/CustomMap/BSPCreator.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Game/T6/Maps/CustomMaps.h"
|
||||||
|
#include "SearchPath/ISearchPath.h"
|
||||||
|
|
||||||
|
class BSPCreator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static CustomMapBSP* createCustomMapBSP(std::string& mapName, ISearchPath& searchPath);
|
||||||
|
};
|
||||||
@@ -1,22 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/*
|
|
||||||
Heavily modified version of https://github.com/sudeshnapal12/Space-Partitioning-Algorithms BSP implementation
|
|
||||||
Credit to sudeshnapal12
|
|
||||||
|
|
||||||
|
|
||||||
BSP leaf sizes are precalculated, evenly sized BSPs are much more efficient and smaller compared to dynamically creating them
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cmath>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <iostream>
|
|
||||||
#include <map>
|
|
||||||
#include <sstream>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#define MAX_AABB_SIZE 512 // maximum size a BSP node can be before it becomes a leaf
|
#include "Game/T6/T6.h"
|
||||||
|
using namespace T6;
|
||||||
|
|
||||||
|
constexpr int MAX_NODE_SIZE = 512; // maximum size a BSP node can be before it becomes a leaf
|
||||||
|
|
||||||
enum PlaneAxis
|
enum PlaneAxis
|
||||||
{
|
{
|
||||||
@@ -28,56 +18,50 @@ enum PlaneAxis
|
|||||||
class Object
|
class Object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
double low[3];
|
vec3_t min;
|
||||||
double high[3];
|
vec3_t max;
|
||||||
|
|
||||||
// custom data
|
int partitionIndex; // index of the partition the object is contained in
|
||||||
int partitionIndex; // index of the partition the object is based on (custom)
|
|
||||||
|
|
||||||
Object(double min_x, double min_y, double min_z, double max_x, double max_y, double max_z, int partition_Index)
|
Object(float xMin, float yMin, float zMin, float xMax, float yMax, float zMax, int objPartitionIndex)
|
||||||
{
|
{
|
||||||
low[0] = min_x;
|
min.x = xMin;
|
||||||
low[1] = min_y, low[2] = min_z;
|
min.y = yMin;
|
||||||
high[0] = max_x;
|
min.z = zMin;
|
||||||
high[1] = max_y;
|
max.x = xMax;
|
||||||
high[2] = max_z;
|
max.y = yMax;
|
||||||
partitionIndex = partition_Index;
|
max.z = zMax;
|
||||||
|
partitionIndex = objPartitionIndex;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
union u_BSPNode;
|
union u_BSPNode
|
||||||
|
{
|
||||||
|
BSPLeaf* leaf;
|
||||||
|
BSPNode* node;
|
||||||
|
};
|
||||||
class BSPTree;
|
class BSPTree;
|
||||||
|
|
||||||
class BSPLeaf
|
class BSPLeaf
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::vector<Object*> objectList;
|
std::vector<std::unique_ptr<Object>> objectList;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BSPLeaf()
|
void addObject(std::unique_ptr<Object> object)
|
||||||
{
|
{
|
||||||
objectList = std::vector<Object*>();
|
objectList.push_back(std::move(object));
|
||||||
}
|
}
|
||||||
|
|
||||||
~BSPLeaf()
|
std::unique_ptr<Object> getObject(int index)
|
||||||
{
|
{
|
||||||
objectList.clear();
|
return std::move(objectList.at(index));
|
||||||
}
|
|
||||||
|
|
||||||
void addToList(Object* object)
|
|
||||||
{
|
|
||||||
objectList.push_back(object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int getObjectCount()
|
int getObjectCount()
|
||||||
{
|
{
|
||||||
return objectList.size();
|
return objectList.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
Object* getObject(int index)
|
|
||||||
{
|
|
||||||
return objectList.at(index);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum objectPlaneSide
|
enum objectPlaneSide
|
||||||
@@ -106,25 +90,23 @@ public:
|
|||||||
|
|
||||||
objectPlaneSide objectIsInfront(Object* object)
|
objectPlaneSide objectIsInfront(Object* object)
|
||||||
{
|
{
|
||||||
double minCoord, maxCoord;
|
float minCoord, maxCoord;
|
||||||
|
|
||||||
// Select the relevant coordinate based on the plane's axis
|
// Select the relevant coordinate based on the plane's axis
|
||||||
switch (axis)
|
if (axis == AXIS_X)
|
||||||
{
|
{
|
||||||
case AXIS_X:
|
minCoord = object->min.x;
|
||||||
minCoord = object->low[0];
|
maxCoord = object->max.x;
|
||||||
maxCoord = object->high[0];
|
}
|
||||||
break;
|
else if (axis == AXIS_Y)
|
||||||
case AXIS_Y:
|
{
|
||||||
minCoord = object->low[1];
|
minCoord = object->min.y;
|
||||||
maxCoord = object->high[1];
|
maxCoord = object->max.y;
|
||||||
break;
|
}
|
||||||
case AXIS_Z:
|
else // axis == AXIS_Z
|
||||||
minCoord = object->low[2];
|
{
|
||||||
maxCoord = object->high[2];
|
minCoord = object->min.z;
|
||||||
break;
|
maxCoord = object->max.z;
|
||||||
default:
|
|
||||||
_ASSERT(false); // this should never be executed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare with the plane's distance
|
// Compare with the plane's distance
|
||||||
@@ -143,12 +125,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
union u_BSPNode
|
|
||||||
{
|
|
||||||
BSPLeaf* leaf;
|
|
||||||
BSPNode* node;
|
|
||||||
};
|
|
||||||
|
|
||||||
class BSPTree
|
class BSPTree
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -178,7 +154,7 @@ public:
|
|||||||
BSPTree* back;
|
BSPTree* back;
|
||||||
double halfLength;
|
double halfLength;
|
||||||
|
|
||||||
if (high[0] - low[0] > MAX_AABB_SIZE)
|
if (high[0] - low[0] > MAX_NODE_SIZE)
|
||||||
{
|
{
|
||||||
// split along the x axis
|
// split along the x axis
|
||||||
halfLength = (low[0] + high[0]) * 0.5f;
|
halfLength = (low[0] + high[0]) * 0.5f;
|
||||||
@@ -188,7 +164,7 @@ public:
|
|||||||
isLeaf = false;
|
isLeaf = false;
|
||||||
u.node = new BSPNode(front, back, AXIS_X, halfLength);
|
u.node = new BSPNode(front, back, AXIS_X, halfLength);
|
||||||
}
|
}
|
||||||
else if (high[2] - low[2] > MAX_AABB_SIZE)
|
else if (high[2] - low[2] > MAX_NODE_SIZE)
|
||||||
{
|
{
|
||||||
// split along the z axis
|
// split along the z axis
|
||||||
halfLength = (low[2] + high[2]) * 0.5f;
|
halfLength = (low[2] + high[2]) * 0.5f;
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
|
#include "Game/T6/Maps/CustomMaps.h"
|
||||||
|
|
||||||
#include "LoaderCustomMapT6.h"
|
#include "LoaderCustomMapT6.h"
|
||||||
#include "ProjectCreator.h"
|
#include "BSPCreator.h"
|
||||||
#include "CustomMapLinker.h"
|
#include "CustomMapLinker.h"
|
||||||
|
|
||||||
#include "Game/T6/T6.h"
|
#include "Game/T6/T6.h"
|
||||||
@@ -27,18 +29,16 @@ namespace
|
|||||||
if (!mapGfxFile.IsOpen())
|
if (!mapGfxFile.IsOpen())
|
||||||
return AssetCreationResult::NoAction();
|
return AssetCreationResult::NoAction();
|
||||||
|
|
||||||
// create map info from the fbx file
|
CustomMapBSP* mapBSP = BSPCreator::createCustomMapBSP(m_zone.m_name, m_search_path);
|
||||||
customMapInfo* mapInfo = ProjectCreator::createCustomMapInfo(m_zone.m_name, m_search_path);
|
if (mapBSP == NULL)
|
||||||
if (mapInfo == NULL)
|
|
||||||
return AssetCreationResult::Failure();
|
return AssetCreationResult::Failure();
|
||||||
|
|
||||||
// linker will add all the assets needed
|
|
||||||
CustomMapLinker* linker = new CustomMapLinker(m_memory, m_search_path, m_zone, context);
|
CustomMapLinker* linker = new CustomMapLinker(m_memory, m_search_path, m_zone, context);
|
||||||
bool result = linker->linkCustomMap(mapInfo);
|
bool result = linker->linkCustomMap(mapBSP);
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
auto gfxWorldAsset = context.LoadDependency<AssetGfxWorld>(mapInfo->bspName);
|
auto gfxWorldAsset = context.LoadDependency<AssetGfxWorld>(mapBSP->bspName);
|
||||||
_ASSERT(gfxWorldAsset != NULL);
|
_ASSERT(gfxWorldAsset != NULL);
|
||||||
return AssetCreationResult::Success(gfxWorldAsset);
|
return AssetCreationResult::Success(gfxWorldAsset);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "SearchPath/ISearchPath.h"
|
|
||||||
#include "Utils/MemoryManager.h"
|
|
||||||
#include "Game/T6/T6.h"
|
|
||||||
using namespace T6;
|
|
||||||
|
|
||||||
class ProjectCreator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static customMapInfo* createCustomMapInfo(std::string& projectName, ISearchPath& searchPath);
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user