diff --git a/CMakeLists.txt b/CMakeLists.txt index 47c503f..48210b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ add_subdirectory(vendor/phoenix) set(PXC_SOURCES src/Animation.cc + src/BspTree.cc src/Buffer.cc src/Cutscene.cc src/DaedalusScript.cc diff --git a/include/phoenix/cffi/Api.h b/include/phoenix/cffi/Api.h index c458b38..ca8387d 100644 --- a/include/phoenix/cffi/Api.h +++ b/include/phoenix/cffi/Api.h @@ -1,6 +1,7 @@ // Copyright © 2023. Luis Michaelis // SPDX-License-Identifier: MIT-Modern-Variant #pragma once +#include #ifdef __cplusplus #define PXC_EXTERN extern "C" @@ -36,6 +37,10 @@ typedef struct { float x, y, z; } PxVec3; +typedef struct { + float x, y, z, w; +} PxVec4; + typedef struct { float x, y, z, w; } PxQuat; diff --git a/include/phoenix/cffi/BspTree.h b/include/phoenix/cffi/BspTree.h new file mode 100644 index 0000000..f35fc15 --- /dev/null +++ b/include/phoenix/cffi/BspTree.h @@ -0,0 +1,48 @@ +// Copyright © 2023. GothicKit Contributors +// SPDX-License-Identifier: MIT +#pragma once +#include "Api.h" + +#ifdef __cplusplus + #include +typedef phoenix::bsp_tree PxBspTree; +#else +typedef PxInternal_BspTree PxBspTree; +#endif + +typedef enum { + PxBspIndoor = 0, + PxBspOutdoor = 1, +} PxBspTreeMode; + +PXC_API PxBspTreeMode pxBspGetMode(PxBspTree const* slf); +PXC_API size_t pxBspGetPolygonIndicesLength(PxBspTree const* slf); +PXC_API uint32_t const* pxBspGetPolygonIndices(PxBspTree const* slf, size_t* size); +PXC_API size_t pxBspGetLeafPolygonIndicesLength(PxBspTree const* slf); +PXC_API uint32_t const* pxBspGetLeafPolygonIndices(PxBspTree const* slf, size_t* size); +PXC_API size_t pxBspGetPortalPolygonIndicesLength(PxBspTree const* slf); +PXC_API uint32_t const* pxBspGetPortalPolygonIndices(PxBspTree const* slf, size_t* size); +PXC_API size_t pxBspGetLightPointsLength(PxBspTree const* slf); +PXC_API PxVec3 pxBspGetLightPoint(PxBspTree const* slf, size_t idx); +PXC_API size_t pxBspGetLeafNodeIndicesLength(PxBspTree const* slf); +PXC_API uint64_t const* pxBspGetLeafNodeIndices(PxBspTree const* slf, size_t* size); + +PXC_API size_t pxBspGetSectorsLength(PxBspTree const* slf); +PXC_API void pxBspGetSector(PxBspTree const* slf, + size_t idx, + char const** name, + uint32_t const** nodeIndices, + size_t* nodeIndicesLength, + uint32_t const** portalPolygonIndices, + size_t* portalPolygonIndicesLength); + +PXC_API size_t pxBspGetNodesLength(PxBspTree const* slf); +PXC_API void pxBspGetNode(PxBspTree const* slf, + size_t idx, + PxVec4* plane, + PxAABB* bbox, + uint32_t* polygonIndex, + uint32_t* polygonCount, + int32_t* frontNodeIndex, + int32_t* backNodeIndex, + int32_t* parentNodeIndex); diff --git a/include/phoenix/cffi/World.h b/include/phoenix/cffi/World.h index 8659f86..18a0fa9 100644 --- a/include/phoenix/cffi/World.h +++ b/include/phoenix/cffi/World.h @@ -2,6 +2,7 @@ // SPDX-License-Identifier: MIT #pragma once #include "Api.h" +#include "BspTree.h" #include "Buffer.h" #include "Mesh.h" #include "Vfs.h" @@ -233,6 +234,7 @@ PXC_API PxWorld* pxWorldLoad(PxBuffer* buffer); PXC_API PxWorld* pxWorldLoadFromVfs(PxVfs const* vfs, char const* name); PXC_API void pxWorldDestroy(PxWorld* world); +PXC_API PxBspTree const* pxWorldGetBspTree(PxWorld const* world); PXC_API PxMesh const* pxWorldGetMesh(PxWorld const* world); PXC_API uint32_t pxWorldGetWayPointCount(PxWorld const* world); PXC_API void pxWorldGetWayPoint(PxWorld const* world, diff --git a/src/BspTree.cc b/src/BspTree.cc new file mode 100644 index 0000000..25cc6c5 --- /dev/null +++ b/src/BspTree.cc @@ -0,0 +1,108 @@ +// Copyright © 2023. GothicKit Contributors +// SPDX-License-Identifier: MIT +#include "phoenix/cffi/BspTree.h" + +PxBspTreeMode pxBspGetMode(PxBspTree const* slf) { + return static_cast(slf->mode); +} + +size_t pxBspGetPolygonIndicesLength(PxBspTree const* slf) { + return slf->polygon_indices.size(); +} + +uint32_t const* pxBspGetPolygonIndices(PxBspTree const* slf, size_t* size) { + if (size != nullptr) *size = slf->polygon_indices.size(); + return slf->polygon_indices.data(); +} + +size_t pxBspGetLeafPolygonIndicesLength(PxBspTree const* slf) { + return slf->leaf_polygons.size(); +} + +uint32_t const* pxBspGetLeafPolygonIndices(PxBspTree const* slf, size_t* size) { + if (size != nullptr) *size = slf->leaf_polygons.size(); + return slf->leaf_polygons.data(); +} + +size_t pxBspGetPortalPolygonIndicesLength(PxBspTree const* slf) { + return slf->portal_polygon_indices.size(); +} + +uint32_t const* pxBspGetPortalPolygonIndices(PxBspTree const* slf, size_t* size) { + if (size != nullptr) *size = slf->portal_polygon_indices.size(); + return slf->portal_polygon_indices.data(); +} + +size_t pxBspGetLightPointsLength(PxBspTree const* slf) { + return slf->light_points.size(); +} + +PxVec3 pxBspGetLightPoint(PxBspTree const* slf, size_t idx) { + auto& v = slf->light_points.at(idx); + return {v.x, v.y, v.z}; +} + +size_t pxBspGetLeafNodeIndicesLength(PxBspTree const* slf) { + return slf->leaf_node_indices.size(); +} + +uint64_t const* pxBspGetLeafNodeIndices(PxBspTree const* slf, size_t* size) { + if (size != nullptr) *size = slf->leaf_node_indices.size(); + return slf->leaf_node_indices.data(); +} + +size_t pxBspGetSectorsLength(PxBspTree const* slf) { + return slf->sectors.size(); +} + +void pxBspGetSector(PxBspTree const* slf, + size_t idx, + char const** name, + uint32_t const** nodeIndices, + size_t* nodeIndicesLength, + uint32_t const** portalPolygonIndices, + size_t* portalPolygonIndicesLength) { + auto& v = slf->sectors.at(idx); + if (name != nullptr) *name = v.name.c_str(); + if (nodeIndices != nullptr) *nodeIndices = v.node_indices.data(); + if (nodeIndicesLength != nullptr) *nodeIndicesLength = v.node_indices.size(); + if (portalPolygonIndices != nullptr) *portalPolygonIndices = v.portal_polygon_indices.data(); + if (portalPolygonIndicesLength != nullptr) *portalPolygonIndicesLength = v.portal_polygon_indices.size(); +} + +size_t pxBspGetNodesLength(PxBspTree const* slf) { + return slf->nodes.size(); +} + +void pxBspGetNode(PxBspTree const* slf, + size_t idx, + PxVec4* plane, + PxAABB* bbox, + uint32_t* polygonIndex, + uint32_t* polygonCount, + int32_t* frontNodeIndex, + int32_t* backNodeIndex, + int32_t* parentNodeIndex) { + auto& v = slf->nodes.at(idx); + if (plane != nullptr) { + plane->x = v.plane.x; + plane->y = v.plane.y; + plane->z = v.plane.z; + plane->w = v.plane.w; + } + + if (bbox != nullptr) { + bbox->max.x = v.bbox.max.x; + bbox->max.y = v.bbox.max.y; + bbox->max.z = v.bbox.max.z; + bbox->min.x = v.bbox.min.x; + bbox->min.y = v.bbox.min.y; + bbox->min.z = v.bbox.min.z; + } + + if (polygonIndex != nullptr) *polygonIndex = v.polygon_index; + if (polygonCount != nullptr) *polygonCount = v.polygon_count; + if (frontNodeIndex != nullptr) *frontNodeIndex = v.front_index; + if (backNodeIndex != nullptr) *backNodeIndex = v.back_index; + if (parentNodeIndex != nullptr) *parentNodeIndex = v.parent_index; +} diff --git a/src/World.cc b/src/World.cc index 87c2b22..674dc4d 100644 --- a/src/World.cc +++ b/src/World.cc @@ -29,6 +29,10 @@ void pxWorldDestroy(PxWorld* world) { delete world; } +PxBspTree const* pxWorldGetBspTree(PxWorld const* world) { + return &world->world_bsp_tree; +} + PxMesh const* pxWorldGetMesh(PxWorld const* world) { return &world->world_mesh; }