Skip to content

Commit

Permalink
ragdoll will also work as GPU particle collider
Browse files Browse the repository at this point in the history
  • Loading branch information
turanszkij committed Feb 18, 2025
1 parent 1ec618e commit 7c93a17
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 19 deletions.
19 changes: 2 additions & 17 deletions Content/scripts/character_controller/character_controller.lua
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,6 @@ local function Character(model_scene, start_transform, controllable, anim_scene,
end
else
-- move towards patrol waypoint:
local charactercomponent = scene.Component_GetCharacter(self.model)
charactercomponent.SetPathGoal(patrol_pos, voxelgrid) -- this is deferred into scene update
local pathquery = charactercomponent.GetPathQuery()
pathquery.SetAgentHeight(3)
Expand All @@ -316,7 +315,7 @@ local function Character(model_scene, start_transform, controllable, anim_scene,
end
self.patrol_wait = 0
-- check if it's blocked by player collision:
local capsule = scene.Component_GetCollider(self.collider).GetCapsule()
local capsule = charactercomponent.GetCapsule()
local forward_offset = vector.Multiply(patrol_vec.Normalize(), 0.5)
capsule.SetBase(vector.Add(capsule.GetBase(), forward_offset))
capsule.SetTip(vector.Add(capsule.GetTip(), forward_offset))
Expand Down Expand Up @@ -527,20 +526,6 @@ local function Character(model_scene, start_transform, controllable, anim_scene,
end
end

-- Create a base capsule collider for character:
local collider = scene.Component_CreateCollider(self.model)
self.collider = self.model
collider.SetCPUEnabled(false)
collider.SetGPUEnabled(true)
collider.Shape = ColliderShape.Capsule
collider.Radius = charactercomponent.GetWidth()
collider.Offset = Vector(0, collider.Radius, 0)
collider.Tail = Vector(0, charactercomponent.GetHeight() - collider.Radius, 0)
local head_transform = scene.Component_GetTransform(self.head)
if head_transform ~= nil then
collider.Tail = head_transform.GetPosition()
end

self.root = self.humanoid

scene.ResetPose(self.model)
Expand Down Expand Up @@ -988,7 +973,7 @@ runProcess(function()
DrawPoint(scene.Component_GetTransform(player.right_foot).GetPosition(),0.05, Vector(0,1,1,1))


local capsule = scene.Component_GetCollider(player.collider).GetCapsule()
local capsule = scene.Component_GetCharacter(player.model).GetCapsule()
DrawCapsule(capsule)

local str = "State: " .. player.state .. "\n"
Expand Down
12 changes: 12 additions & 0 deletions WickedEngine/shaders/globals.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,18 @@ inline void draw_point(float3 pos, float size = 1, float4 color = 1)
draw_line(pos - float3(0, size, 0), pos + float3(0, size, 0), color);
draw_line(pos - float3(0, 0, size), pos + float3(0, 0, size), color);
}
inline void draw_sphere(float3 pos, float radius, float4 color = 1)
{
const uint segmentcount = 36;
for (int i = 0; i < segmentcount; ++i)
{
const float angle0 = (float)i / (float)segmentcount * PI * 2;
const float angle1 = (float)(i + 1) / (float)segmentcount * PI * 2;
draw_line(pos + float3(sin(angle0), cos(angle0), 0) * radius, pos + float3(sin(angle1), cos(angle1), 0) * radius, color);
draw_line(pos + float3(sin(angle0), 0, cos(angle0)) * radius, pos + float3(sin(angle1), 0, cos(angle1)) * radius, color);
draw_line(pos + float3(0, sin(angle0), cos(angle0)) * radius, pos + float3(0, sin(angle1), cos(angle1)) * radius, color);
}
}

// Mie scaterring approximated with Henyey-Greenstein phase function.
// https://www.alexandre-pestana.com/volumetric-lights/
Expand Down
7 changes: 7 additions & 0 deletions WickedEngine/shaders/hairparticle_simulateCS.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn
float3 to_tail = normalize(tail_next - base);
tail_next = base + to_tail * boneLength;

//draw_sphere(tail_next, len);

// Accumulate forces, apply colliders:
for (uint i = forces().first_item(); i < forces().end_item(); ++i)
{
Expand All @@ -218,6 +220,11 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn
float3 N = normalize(A - B);
A -= N * range;
B += N * range;
//if (DTid.x == 0)
//{
// draw_sphere(A, range);
// draw_sphere(B, range);
//}
float3 C = closest_point_on_segment(A, B, tail_next);
float3 dir = C - tail_next;
float dist = length(dir);
Expand Down
46 changes: 45 additions & 1 deletion WickedEngine/wiRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2084,9 +2084,10 @@ void LoadBuffers()
bd.usage = Usage::READBACK;
bd.bind_flags = {};
bd.misc_flags = {};
IndirectDrawArgsInstanced initdata_readback = {};
for (auto& buf : indirectDebugStatsReadback)
{
device->CreateBuffer(&bd, nullptr, &buf);
device->CreateBuffer(&bd, &initdata_readback, &buf);
device->SetName(&buf, "indirectDebugStatsReadback");
}

Expand Down Expand Up @@ -4002,6 +4003,7 @@ void UpdatePerFrameData(
device->SetName(&buffers[BUFFERTYPE_INDIRECT_DEBUG_0], "buffers[BUFFERTYPE_INDIRECT_DEBUG_0]");
device->CreateBuffer(&bd, nullptr, &buffers[BUFFERTYPE_INDIRECT_DEBUG_1]);
device->SetName(&buffers[BUFFERTYPE_INDIRECT_DEBUG_1], "buffers[BUFFERTYPE_INDIRECT_DEBUG_1]");
std::memset(indirectDebugStatsReadback_available, 0, sizeof(indirectDebugStatsReadback_available));
}
}

Expand Down Expand Up @@ -4564,6 +4566,48 @@ void UpdatePerFrameData(
entityCounter++;
forcefieldarray_count++;
}

// Write ragdoll colliders into entity array:
for (size_t i = 0; i < vis.scene->humanoids.GetCount(); ++i)
{
if (entityCounter == SHADER_ENTITY_COUNT)
{
entityCounter--;
break;
}

uint32_t layerMask = ~0u;

Entity entity = vis.scene->humanoids.GetEntity(i);
const LayerComponent* layer = vis.scene->layers.GetComponent(entity);
if (layer != nullptr)
{
layerMask = layer->layerMask;
}

const HumanoidComponent& humanoid = vis.scene->humanoids[i];
for (auto& bodypart : humanoid.ragdoll_bodyparts)
{
if (entityCounter == SHADER_ENTITY_COUNT)
{
entityCounter--;
break;
}

ShaderEntity shaderentity = {};
shaderentity.SetType(ENTITY_TYPE_COLLIDER_CAPSULE);
shaderentity.layerMask = layerMask;
shaderentity.position = bodypart.capsule.base;
shaderentity.SetColliderTip(bodypart.capsule.tip);
shaderentity.SetRange(bodypart.capsule.radius);

//DrawCapsule(bodypart.capsule);

std::memcpy(entityArray + entityCounter, &shaderentity, sizeof(ShaderEntity));
entityCounter++;
forcefieldarray_count++;
}
}
}

frameCB.probes = ShaderEntityIterator(envprobearray_offset, envprobearray_count);
Expand Down
2 changes: 1 addition & 1 deletion WickedEngine/wiVersion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace wi::version
// minor features, major updates, breaking compatibility changes
const int minor = 71;
// minor bug fixes, alterations, refactors, updates
const int revision = 682;
const int revision = 683;

const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);

Expand Down

0 comments on commit 7c93a17

Please sign in to comment.