Skip to content

Commit

Permalink
Physics heightfields (#198)
Browse files Browse the repository at this point in the history
- update vs build settings to disable LTCG and select WASAPI soloud backend by default
- add support for loading physx heightfields from R16_UNORM textures
- made physics run with actual physics framerate instead
  • Loading branch information
kaffeewolf authored Nov 12, 2023
1 parent d3917a0 commit 894938a
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 8 deletions.
18 changes: 15 additions & 3 deletions code/physics/physics/physxstate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,14 @@ PhysxState::BeginSimulating(Timing::Time delta, IndexT sceneId)

n_assert(this->activeSceneIds.FindIndex(sceneId) != InvalidIndex);
Physics::Scene& scene = this->activeScenes[sceneId];
n_assert(scene.isSimulating == false);
scene.time -= delta;

if (scene.time < -PHYSICS_RATE)
{
scene.isSimulating = scene.scene->simulate(PHYSICS_RATE);
}

scene.scene->simulate(PHYSICS_RATE);
N_MARKER_END();
}

Expand All @@ -287,11 +292,17 @@ PhysxState::BeginSimulating(Timing::Time delta, IndexT sceneId)
void
PhysxState::EndSimulating(IndexT sceneId)
{
N_MARKER_BEGIN(EndSimulating, Physics);
n_assert(this->activeSceneIds.FindIndex(sceneId) != InvalidIndex);
Physics::Scene& scene = this->activeScenes[sceneId];

if (!scene.isSimulating)
{
return;
}

N_MARKER_BEGIN(EndSimulating, Physics);
scene.scene->fetchResults(true);
scene.time += PHYSICS_RATE;

Util::Set<Ids::Id32> modifiedActors;
if (scene.updateFunction != nullptr)
Expand All @@ -301,7 +312,7 @@ PhysxState::EndSimulating(IndexT sceneId)

// we limit the simulation to 5 frames
scene.time = Math::max(scene.time, -5.0 * PHYSICS_RATE);
while (scene.time < PHYSICS_RATE)
while (scene.time < 0.0f)
{
// simulate synchronously until we are in sync again
scene.scene->simulate(PHYSICS_RATE);
Expand All @@ -318,6 +329,7 @@ PhysxState::EndSimulating(IndexT sceneId)
(*scene.updateFunction)(actor);
}
}
scene.isSimulating = false;
N_MARKER_END();
}

Expand Down
70 changes: 69 additions & 1 deletion code/physics/physics/streamactorpool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "flat/physics/actor.h"
#include "coregraphics/nvx3fileformatstructs.h"
#include "coregraphics/primitivegroup.h"
#include "coregraphics/load/glimltypes.h"

__ImplementClass(Physics::StreamActorPool, 'PSAP', Resources::ResourceLoader);

Expand Down Expand Up @@ -363,6 +364,68 @@ AddMeshColliders(PhysicsResource::MeshColliderT* colliderNode, Math::mat4 const&
nvx3Reader->Close();
}

//------------------------------------------------------------------------------
/**
*/
static void
AddHeightField(PhysicsResource::HeightFieldColliderT* colliderNode, Math::mat4 const& nodeTransform, Util::String nodeName, IndexT materialIdx, const Util::StringAtom& tag, Ids::Id32 entry, ActorInfo& targetActor)
{
Ptr<IO::Stream> stream = IO::IoServer::Instance()->CreateStream(IO::URI(colliderNode->file));
stream->SetAccessMode(IO::Stream::ReadAccess);
if (stream->Open())
{
void* heightData = stream->MemoryMap();
uint heightSize = stream->GetSize();
n_assert(heightData != nullptr);

gliml::context ctx;
if (ctx.load_dds(heightData, heightSize))
{
int depth = ctx.image_depth(0, 0);
int width = ctx.image_width(0, 0);
int height = ctx.image_height(0, 0);

CoreGraphics::PixelFormat::Code format = CoreGraphics::Gliml::ToPixelFormat(ctx);
n_assert(format == CoreGraphics::PixelFormat::R16);

PxHeightFieldSample* heightSamples = (PxHeightFieldSample*)Memory::Alloc(Memory::PhysicsHeap, width * height * sizeof(PxHeightFieldSample));
n_assert(heightSamples != nullptr);
Memory::Clear(heightSamples, width * height * sizeof(PxHeightFieldSample));

uint16_t* heightBuffer = (uint16_t*)ctx.image_data(0, 0);

// need to flip to be in same orientation with rendering
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
heightSamples[i * width + j].height = heightBuffer[j * width + i];
}
}

PxHeightFieldDesc hfDesc;
hfDesc.format = PxHeightFieldFormat::eS16_TM;
hfDesc.nbColumns = width;
hfDesc.nbRows = height;
hfDesc.samples.data = heightSamples;
hfDesc.samples.stride = sizeof(PxHeightFieldSample);

PxHeightField* physxHeightField = PxCreateHeightField(hfDesc);

float sh = colliderNode->height_range / 65536.0f;
float sx = colliderNode->target_size_x / (float)width;
float sy = colliderNode->target_size_y / (float)height;
PxHeightFieldGeometry hfGeom(physxHeightField, PxMeshGeometryFlags(), sh, sx, sy);
Math::mat4 offsetTransform = Math::mat4::identity;
offsetTransform.position = Math::vec4(-0.5f * colliderNode->target_size_x, 0.0f, -0.5f * colliderNode->target_size_y, 1.0f);
physx::PxGeometryHolder holder = hfGeom;
AddCollider(holder, materialIdx, offsetTransform, colliderNode->file.AsCharPtr(), nodeName, targetActor, tag, entry);
Memory::Free(Memory::HeapType::PhysicsHeap, heightSamples);
}
stream->MemoryUnmap();
stream->Close();
}
}

//------------------------------------------------------------------------------
/**
Expand Down Expand Up @@ -435,8 +498,13 @@ StreamActorPool::LoadFromStream(const Ids::Id32 entry, const Util::StringAtom &
*/
}
break;
case ColliderType_HeightField:
{
AddHeightField(collider->data.AsHeightFieldCollider(), shape->transform, collider->name, material, tag, entry, actorInfo);
}
break;
default:
n_assert("unknown collider type")
n_error("unknown collider type");
}
}

Expand Down
1 change: 1 addition & 0 deletions code/physics/physicsinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ struct Scene
physx::PxDefaultCpuDispatcher *dispatcher;
UpdateFunctionType updateFunction = nullptr;
Timing::Time time;
bool isSimulating = false;
};

/// initialize the physics subsystem and create a default scene
Expand Down
3 changes: 3 additions & 0 deletions fips-files/configs/win64-vstudio-debug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@ build_type: Debug
defines:
N_USE_VULKAN: ON
__X64__: ON
FIPS_MSVC_LTCG: OFF
N_DEBUG_SYMBOLS: ON
PX_TARGET: win.x86_64.vc143.mt
SOLOUD_BACKEND_WASAPI: ON
SOLOUD_BACKEND_NULL: OFF
3 changes: 3 additions & 0 deletions fips-files/configs/win64-vstudio-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@ build_tool: cmake
build_type: Release
defines:
N_USE_VULKAN: ON
FIPS_MSVC_LTCG: OFF
__X64__: ON
PX_TARGET: win.x86_64.vc143.mt
SOLOUD_BACKEND_WASAPI: ON
SOLOUD_BACKEND_NULL: OFF
10 changes: 9 additions & 1 deletion syswork/data/flatbuffer/physics/actor.fbs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,17 @@ table BoxCollider
extents : Flat.Vec3 (native_inline);
}

table HeightFieldCollider
{
height_range : float;
target_size_x : float;
target_size_y : float;
file : string;
}

union ColliderData
{
BoxCollider, SphereCollider, CapsuleCollider, MeshCollider
BoxCollider, SphereCollider, CapsuleCollider, MeshCollider, HeightFieldCollider
}

table Collider
Expand Down
6 changes: 3 additions & 3 deletions syswork/data/flatbuffer/physics/material.fbs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ enum MeshTopology : byte
Convex = 0,
ConvexHull = 1,
Triangles = 2,
HeightField = 3,
ApproxSkin = 4,
ApproxSkin = 3
}

enum ColliderType : byte
Expand All @@ -29,7 +28,8 @@ enum ColliderType : byte
Cube = 1,
Capsule = 2,
Plane = 3,
Mesh = 4
Mesh = 4,
HeightField = 5
}

table MaterialDefinition
Expand Down

0 comments on commit 894938a

Please sign in to comment.