Skip to content
This repository has been archived by the owner on Jan 12, 2024. It is now read-only.

Commit

Permalink
Add BSP-tree API
Browse files Browse the repository at this point in the history
  • Loading branch information
lmichaelis committed Oct 14, 2023
1 parent b5e0fb0 commit 3d64805
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 1 deletion.
2 changes: 1 addition & 1 deletion PxCs.Tests/PxPhoenixTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public abstract class PxPhoenixTest

public PxPhoenixTest()
{
string? dir = Environment.GetEnvironmentVariable("GOTHIC1_ASSET_DIR");
string? dir = "/mnt/games/Gothic/Gothic108kDE/"; // Environment.GetEnvironmentVariable("GOTHIC1_ASSET_DIR");

Assert.True(dir != null, "Please start test with dotnet test --environment GOTHIC1_ASSET_DIR=... or configure ./.runsettings to be used by your IDE runner.");
Assert.True(Directory.Exists(dir), "Path not exists");
Expand Down
31 changes: 31 additions & 0 deletions PxCs.Tests/PxWorldTest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Numerics;
using Microsoft.VisualBasic.CompilerServices;
using PxCs.Data.Vob;
using PxCs.Interface;
Expand Down Expand Up @@ -89,5 +90,35 @@ public void Test_load_Vobs()
PxWorld.pxWorldDestroy(worldPtr);
DestroyVfs(vfsPtr);
}

[Fact]
public void Test_load_BspTree()
{
var vfsPtr = LoadVfs("Data/worlds.VDF");
var worldPtr = PxWorld.pxWorldLoadFromVfs(vfsPtr, "world.zen");
var bspPtr = PxWorld.pxWorldGetBspTree(worldPtr);

var mode = PxBspTree.pxBspGetMode(bspPtr);
Assert.Equal(PxBspTree.PxBspTreeMode.PxBspOutdoor, mode);

var polygonIndices = PxBspTree.GetPolygonIndices(bspPtr);
Assert.Equal(480135, polygonIndices.Length);
Assert.Equal(102u, polygonIndices[150]);

var sectors = PxBspTree.GetSectors(bspPtr);
Assert.Equal(299, sectors.Length);
Assert.Equal("WALD11", sectors[0].name);
Assert.Equal(9, sectors[0].nodeIndices.Length);
Assert.Equal(24, sectors[0].portalPolygonIndices.Length);

var nodes = PxBspTree.GetNodes(bspPtr);
Assert.Equal(6644, nodes.Length);
Assert.Equal(new Vector4(1, 0, 0, 18540.0156f), nodes[0].plane);
Assert.Equal(1, nodes[0].frontNodeIndex);
Assert.Equal(1599, nodes[0].backNodeIndex);
Assert.Equal(-1, nodes[0].parentNodeIndex);
Assert.Equal(0u, nodes[0].polygonIndex);
Assert.Equal(0u, nodes[0].polygonCount);
}
}
}
16 changes: 16 additions & 0 deletions PxCs/Data/BspTree/PxBspNodeData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Numerics;
using PxCs.Data.Struct;

namespace PxCs.Data.BspTree
{
public class PxBspNodeData
{
public Vector4 plane;
public PxAABBData bbox;
public uint polygonIndex;
public uint polygonCount;
public int frontNodeIndex;
public int backNodeIndex;
public int parentNodeIndex;
}
}
12 changes: 12 additions & 0 deletions PxCs/Data/BspTree/PxBspSectorData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;

namespace PxCs.Data.BspTree
{
[Serializable]
public class PxBspSectorData
{
public string name;
public uint[] nodeIndices;
public uint[] portalPolygonIndices;
}
}
110 changes: 110 additions & 0 deletions PxCs/Interface/PxBspTree.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using System;
using System.Numerics;
using System.Runtime.InteropServices;
using PxCs.Data.BspTree;
using PxCs.Data.Struct;
using PxCs.Extensions;

namespace PxCs.Interface
{
public class PxBspTree
{
private const string DLLNAME = PxPhoenix.DLLNAME;

public enum PxBspTreeMode
{
PxBspIndoor = 0,
PxBspOutdoor = 1,
}

[DllImport(DLLNAME)] public static extern PxBspTreeMode pxBspGetMode(IntPtr bsp);
[DllImport(DLLNAME)] public static extern ulong pxBspGetPolygonIndicesLength(IntPtr bsp);
[DllImport(DLLNAME)] public static extern IntPtr pxBspGetPolygonIndices(IntPtr bsp, out ulong size);
[DllImport(DLLNAME)] public static extern ulong pxBspGetLeafPolygonIndicesLength(IntPtr bsp);
[DllImport(DLLNAME)] public static extern IntPtr pxBspGetLeafPolygonIndices(IntPtr bsp, out ulong size);
[DllImport(DLLNAME)] public static extern ulong pxBspGetPortalPolygonIndicesLength(IntPtr bsp);
[DllImport(DLLNAME)] public static extern IntPtr pxBspGetPortalPolygonIndices(IntPtr bsp, out ulong size);
[DllImport(DLLNAME)] public static extern ulong pxBspGetLeafNodeIndicesLength(IntPtr bsp);
[DllImport(DLLNAME)] public static extern IntPtr pxBspGetLeafNodeIndices(IntPtr bsp, out ulong size);
[DllImport(DLLNAME)] public static extern ulong pxBspGetLightPointsLength(IntPtr bsp);
[DllImport(DLLNAME)] public static extern Vector3 pxBspGetLightPoint(IntPtr bsp, ulong idx);
[DllImport(DLLNAME)] public static extern ulong pxBspGetSectorsLength(IntPtr bsp);
[DllImport(DLLNAME)] public static extern void pxBspGetSector(IntPtr bsp, ulong idx, out IntPtr name, out IntPtr nodeIndices,
out ulong nodeIndicesLength, out IntPtr portalPolygonIndices, out ulong portalPolygonIndicesLength);
[DllImport(DLLNAME)] public static extern ulong pxBspGetNodesLength(IntPtr bsp);
[DllImport(DLLNAME)] public static extern void pxBspGetNode(IntPtr bsp, ulong idx, out Vector4 plane, out PxAABBData bbox,
out uint polygonIndex, out uint polygonCount, out int frontNodeIndex, out int backNodeIndex,
out int parentNodeIndex);


public static uint[] GetPolygonIndices(IntPtr bsp)
{
return pxBspGetPolygonIndices(bsp, out ulong size).MarshalAsArray<uint>((uint)size);
}

public static uint[] GetLeafPolygonIndices(IntPtr bsp)
{
return pxBspGetLeafPolygonIndices(bsp, out ulong size).MarshalAsArray<uint>((uint)size);
}

public static uint[] GetPortalPolygonIndices(IntPtr bsp)
{
return pxBspGetPortalPolygonIndices(bsp, out ulong size).MarshalAsArray<uint>((uint)size);
}

public static ulong[] GetLeadNodeIndices(IntPtr bsp)
{
return pxBspGetLeafNodeIndices(bsp, out ulong size).MarshalAsArray<ulong>((uint)size);
}

public static Vector3[] GetLightPoints(IntPtr bsp)
{
var length = pxBspGetLightPointsLength(bsp);
var array = new Vector3[length];

for (var i = 0u; i < length; ++i)
{
array[i] = pxBspGetLightPoint(bsp, i);
}

return array;
}

public static PxBspSectorData[] GetSectors(IntPtr bsp)
{
var length = pxBspGetSectorsLength(bsp);
var array = new PxBspSectorData[length];

for (var i = 0u; i < length; ++i)
{
pxBspGetSector(bsp, i, out IntPtr name, out IntPtr nodeIndices,
out ulong nodeIndicesLength, out IntPtr portalPolygonIndices, out ulong portalPolygonIndicesLength);

array[i] = new PxBspSectorData
{
name = name.MarshalAsString(),
nodeIndices = nodeIndices.MarshalAsArray<uint>((uint)nodeIndicesLength),
portalPolygonIndices = portalPolygonIndices.MarshalAsArray<uint>((uint)portalPolygonIndicesLength)
};
}

return array;
}

public static PxBspNodeData[] GetNodes(IntPtr bsp)
{
var length = pxBspGetNodesLength(bsp);
var array = new PxBspNodeData[length];

for (var i = 0u; i < length; ++i)
{
array[i] = new PxBspNodeData();
pxBspGetNode(bsp, i, out array[i].plane, out array[i].bbox, out array[i].polygonIndex,
out array[i].polygonCount, out array[i].frontNodeIndex, out array[i].backNodeIndex,
out array[i].parentNodeIndex);
}

return array;
}
}
}
1 change: 1 addition & 0 deletions PxCs/Interface/PxWorld.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ public enum PxVobTriggerBatchMode
[DllImport(DLLNAME)] public static extern IntPtr pxWorldLoadFromVfs(IntPtr vfs, string name);
[DllImport(DLLNAME)] public static extern void pxWorldDestroy(IntPtr world);

[DllImport(DLLNAME)] public static extern IntPtr pxWorldGetBspTree(IntPtr world);
[DllImport(DLLNAME)] public static extern IntPtr pxWorldGetMesh(IntPtr world);
[DllImport(DLLNAME)] public static extern uint pxWorldGetWayPointCount(IntPtr world);
[DllImport(DLLNAME)]
Expand Down

0 comments on commit 3d64805

Please sign in to comment.