瀏覽代碼

btPhysTest : Added a new test mode called "CAT_MODE". Try it out at your own risks.

undefined
Benjamin ‘Touky’ Huet Sam Hocevar <sam@hocevar.net> 11 年之前
父節點
當前提交
a03c38872d
共有 10 個檔案被更改,包括 500 行新增117 行删除
  1. +17
    -0
      src/easymesh/easymesh.cpp
  2. +1
    -1
      src/lolcore.vcxproj
  3. +178
    -21
      test/btphystest.cpp
  4. +37
    -15
      test/btphystest.h
  5. +4
    -1
      test/btphystest.vcxproj
  6. +4
    -1
      test/btphystest.vcxproj.filters
  7. 二進制
      test/data/lolcatz.png
  8. +119
    -58
      test/physicobject.h
  9. +90
    -3
      test/physics/easyphysics.cpp
  10. +50
    -17
      test/physics/easyphysics.h

+ 17
- 0
src/easymesh/easymesh.cpp 查看文件

@@ -353,6 +353,23 @@ void GpuEasyMeshData::SetupVertexData(uint16_t vflags, EasyMesh* src_mesh)

COPY_VBO;
}
else if (has_position && has_color && has_texcoord && has_texcoordExt && flagnb == 4)
{
new_vdecl = new VertexDeclaration(VertexStream<vec3,vec4,vec4>(VertexUsage::Position, VertexUsage::Color, VertexUsage::TexCoord));

Array<vec3, vec4, vec4> vertexlist;
for (int i = 0; i < src_mesh->m_vert.Count(); i++)
vertexlist.Push(src_mesh->m_vert[i].m_coord, src_mesh->m_vert[i].m_color, src_mesh->m_vert[i].m_texcoord);

vbo_data = &vertexlist[0];
vbo_bytes = vertexlist.Bytes();
m_vertexcount = vertexlist.Count();

COPY_VBO;
}
else
ASSERT(!saveflags, "Vertex Declaration combination is not implemented for %s, feel free to do so.",
VertexUsage::GetNameList(vflags).C());

m_vdatas.Push(vflags, new_vdecl, new_vbo);
}


+ 1
- 1
src/lolcore.vcxproj 查看文件

@@ -98,7 +98,7 @@
<Import Project="$(SolutionDir)\Lol.Core.Rules.props" />
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions);LOL_INPUT_V2</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>


+ 178
- 21
test/btphystest.cpp 查看文件

@@ -20,28 +20,51 @@ using namespace lol;

#include "physics/lolphysics.h"
#include "physics/easyphysics.h"

#define CAT_MODE 0
#define OBJ_SIZE 2.f
#include "physicobject.h"

#include "btphystest.h"

using namespace lol::phys;

#define CUBE_HALF_EXTENTS .5f
#define EXTRA_HEIGHT 1.f
#define BASE_TIME 2.f
#define ZERO_TIME (BASE_TIME + rand(-BASE_TIME * .4f, BASE_TIME * .4f))
#define ZERO_SPEED 3.5f
#define JUMP_HEIGHT 30.f
#define JUMP_STRAFE .5f

int gNumObjects = 64;

#if CAT_MODE
#define USE_WALL 1
#define USE_BODIES 1
#else
#define USE_WALL 1
#define USE_PLATFORM 1
#define USE_ROPE 0
#define USE_BODIES 1
#define USE_ROTATION 0
#define USE_CHARACTER 1
#define USE_STAIRS 1
#define USE_CHARACTER 0
#define USE_STAIRS 0
#endif

LOLFX_RESOURCE_DECLARE(front_camera_sprite);

BtPhysTest::BtPhysTest(bool editor)
{
m_loop_value = .0f;

g_renderer->SetAlphaFunc(AlphaFunc::Greater, 0.0);

#if CAT_MODE
/* cat datas setup */
m_cat_texture = Tiler::Register("data/CatsSheet.png", ivec2(0), ivec2(0,1));
#endif //CAT_MODE

/* Register an input controller for the keyboard */
m_controller = new Controller(KEY_MAX, 0);
m_controller->GetKey(KEY_MOVE_FORWARD).Bind("Keyboard", "Up");
@@ -55,10 +78,17 @@ BtPhysTest::BtPhysTest(bool editor)

/* Create a camera that matches the settings of XNA BtPhysTest */
m_camera = new Camera();
#if CAT_MODE
m_camera->SetView(vec3(70.f, 50.f, 0.f),
vec3(0.f, 0.f, 0.f),
vec3(0, 1, 0));
m_camera->SetProjection(mat4::perspective(60.f, 1280.f, 960.f, .1f, 1000.f));
#else
m_camera->SetView(vec3(50.f, 50.f, 0.f),
vec3(0.f, 0.f, 0.f),
vec3(0, 1, 0));
m_camera->SetProjection(mat4::perspective(45.f, 1280.f, 960.f, .1f, 1000.f));
#endif
g_scene->PushCamera(m_camera);

m_ready = false;
@@ -86,7 +116,7 @@ BtPhysTest::BtPhysTest(bool editor)

float offset = 29.5f;
vec3 pos_offset = vec3(.0f, 30.f, .0f);
if (USE_STAIRS)
#if USE_STAIRS
{
vec3 new_offset = vec3(1.0f, .125f, .0f);
quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
@@ -118,8 +148,9 @@ BtPhysTest::BtPhysTest(bool editor)
m_stairs_list << NewPhyobj;
}
}
#endif //USE_STAIRS

if (USE_WALL)
#if USE_WALL
{
for (int i=0; i < 6; i++)
{
@@ -145,9 +176,10 @@ BtPhysTest::BtPhysTest(bool editor)
m_ground_list << NewPhyobj;
}
}
#endif //USE_WALL

PhysicsObject* BasePhyobj = NULL;
if (USE_PLATFORM)
#if USE_PLATFORM
{
quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
vec3 NewPosition = pos_offset + vec3(5.0f, -25.0f, -15.0f);
@@ -188,8 +220,9 @@ BtPhysTest::BtPhysTest(bool editor)
//m_platform_list << NewPhyobj;
//Ticker::Ref(NewPhyobj);
}
#endif //USE_PLATFORM

if (USE_CHARACTER)
#if USE_CHARACTER
{
quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
vec3 NewPosition = pos_offset + vec3(-5.0f, -10.0f, 15.0f);
@@ -201,26 +234,28 @@ BtPhysTest::BtPhysTest(bool editor)

//NewPhyobj->GetCharacter()->AttachTo(BasePhyobj->GetPhysic(), true, true);
}
#endif //USE_CHARACTER

if (USE_BODIES)
#if USE_BODIES
{
for (int x=0; x < 6; x++)
{
for (int y=0; y < 6; y++)
for (int y=0; y < 2; y++)
{
for (int z=0; z < 5; z++)
{
PhysicsObject* new_physobj = new PhysicsObject(m_simulation, 1000.f,
vec3(-20.f, 15.f, -20.f) +
vec3(8.f * (float)x, 8.f * (float)y, 8.f * (float)z));
m_physobj_list << new_physobj;
m_physobj_list.Push(new_physobj, ZERO_TIME);
Ticker::Ref(new_physobj);
}
}
}
}
#endif //USE_BODIES

if (USE_ROPE)
#if USE_ROPE
{
Array<PhysicsObject*> RopeElements;
for (int i = 0; i < 14; i++)
@@ -229,7 +264,7 @@ BtPhysTest::BtPhysTest(bool editor)
vec3(0.f, 15.f, -20.f) +
vec3(0.f, 0.f, 2.f * (float)i), 1);
RopeElements << new_physobj;
m_physobj_list << new_physobj;
m_physobj_list.Push(new_physobj, ZERO_TIME);
Ticker::Ref(new_physobj);
if (RopeElements.Count() > 1)
{
@@ -246,6 +281,7 @@ BtPhysTest::BtPhysTest(bool editor)
}
}
}
#endif //USE_ROPE
}

void BtPhysTest::TickGame(float seconds)
@@ -262,8 +298,66 @@ void BtPhysTest::TickGame(float seconds)
vec3 GroundBarycenter = vec3(.0f);
vec3 PhysObjBarycenter = vec3(.0f);
float factor = .0f;
#if CAT_MODE
#if USE_BODIES
vec3 cam_center(0.f);
float cam_factor = .0f;
vec2 screen_min_max[2] = { vec2(FLT_MAX), vec2(-FLT_MAX) };
vec3 cam_min_max[2] = { vec3(FLT_MAX), vec3(-FLT_MAX) };
mat4 world_cam = g_scene->GetCamera()->GetView();
mat4 cam_screen = g_scene->GetCamera()->GetProjection();

for (int i = 0; i < m_physobj_list.Count(); i++)
{
PhysicsObject* PhysObj = m_physobj_list[i].m1;
float &Timer = m_physobj_list[i].m2;

vec3 obj_loc = PhysObj->GetPhysic()->GetTransform().v3.xyz;

cam_center += obj_loc;
cam_factor += 1.f;

mat4 LocalPos = mat4::translate(obj_loc);
vec3 vpos;

LocalPos = world_cam * LocalPos;
vpos = LocalPos.v3.xyz;
cam_min_max[0] = min(vpos.xyz, cam_min_max[0]);
cam_min_max[1] = max(vpos.xyz, cam_min_max[1]);

LocalPos = cam_screen * LocalPos;
vpos = (LocalPos.v3 / LocalPos.v3.w).xyz;
screen_min_max[0] = min(vpos.xy, screen_min_max[0]);
screen_min_max[1] = max(vpos.xy, screen_min_max[1]);

//if (length(PhysObj->GetPhysic()->GetLinearVelocity()) < ZERO_SPEED)
if (lol::abs(PhysObj->GetPhysic()->GetLinearVelocity().y) < ZERO_SPEED)
Timer -= seconds;

if (Timer < .0f)
{
PhysObj->GetPhysic()->AddImpulse(JUMP_HEIGHT *
vec3(JUMP_STRAFE, 1.f, JUMP_STRAFE) *
vec3(rand(-1.f, 1.f), 1.0f, rand(-1.f, 1.f)) *
PhysObj->GetPhysic()->GetMass());
Timer = ZERO_TIME;
}
}

if (USE_WALL)
vec3 min_max_diff = (cam_min_max[1] - cam_min_max[0]);
float screen_size = max(max(lol::abs(min_max_diff.x), lol::abs(min_max_diff.y)),
max( lol::abs(min_max_diff.x), lol::abs(min_max_diff.y)));
float fov_ratio = max(max(lol::abs(screen_min_max[0].x), lol::abs(screen_min_max[0].y)),
max(lol::abs(screen_min_max[1].x), lol::abs(screen_min_max[1].y)));

//m_camera->SetProjection(mat4::perspective(30.f * fov_ratio * 1.1f, 1280.f, 960.f, .1f, 1000.f));
m_camera->SetView((mat4::rotate(10.f * seconds, vec3(.0f, 1.f, .0f)) * vec4(m_camera->GetPosition(), 1.0f)).xyz,
//vec3(70.f, 30.f, 0.f),
cam_center / cam_factor, vec3(0, 1, 0));
#endif //USE_BODIES
#endif //CAT_MODE

#if USE_WALL
{
for (int i = 0; i < m_ground_list.Count(); i++)
{
@@ -291,8 +385,9 @@ void BtPhysTest::TickGame(float seconds)
PhysObj->SetRender(true);
}
}
#endif //USE_WALL

if (USE_ROTATION)
#if USE_ROTATION
{
for (int i = 0; i < m_ground_list.Count(); i++)
{
@@ -307,8 +402,9 @@ void BtPhysTest::TickGame(float seconds)
PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
}
}
#endif //USE_ROTATION

if (USE_PLATFORM)
#if USE_PLATFORM
{
for (int i = 0; i < m_platform_list.Count(); i++)
{
@@ -329,8 +425,9 @@ void BtPhysTest::TickGame(float seconds)
}
}
}
#endif //USE_PLATFORM

if (USE_CHARACTER)
#if USE_CHARACTER
{
for (int i = 0; i < m_character_list.Count(); i++)
{
@@ -358,8 +455,9 @@ void BtPhysTest::TickGame(float seconds)
Character->AttachTo(NULL);
}
}
#endif //USE_CHARACTER

if (USE_CHARACTER)
#if USE_CHARACTER
{
PhysObjBarycenter = vec3(.0f);
factor = .0f;
@@ -381,12 +479,12 @@ void BtPhysTest::TickGame(float seconds)
m_camera->SetPosition(CamPosCenter + normalize(m_camera->GetPosition() - CamPosCenter) * 20.0f);
#endif
}
else
#else
{
PhysObjBarycenter = vec3(.0f);
for (int i = 0; i < m_physobj_list.Count(); i++)
{
PhysicsObject* PhysObj = m_physobj_list[i];
PhysicsObject* PhysObj = m_physobj_list[i].m1;
mat4 GroundMat = PhysObj->GetTransform();

PhysObjBarycenter += GroundMat.v3.xyz;
@@ -400,7 +498,7 @@ void BtPhysTest::TickGame(float seconds)
m_camera->SetPosition(GroundBarycenter + normalize(GroundBarycenter - PhysObjBarycenter) * 60.0f);
#endif
}
#endif //USE_CHARACTER
}

void BtPhysTest::TickDraw(float seconds)
@@ -409,6 +507,26 @@ void BtPhysTest::TickDraw(float seconds)

if (!m_ready)
{
#if CAT_MODE
/* cat datas setup */
m_cat_shader = Shader::Create(LOLFX_RESOURCE_NAME(front_camera_sprite));
#if USE_BODIES
for (int i = 0; i < m_physobj_list.Count(); i++)
{
PhysicsObject* PhysObj = m_physobj_list[i].m1;
m_cat_sdata = new CatShaderData(((1 << VertexUsage::Position) |
(1 << VertexUsage::Color) |
(1 << VertexUsage::TexCoord) |
(1 << VertexUsage::TexCoordExt)),
m_cat_shader);
m_cat_sdata->m_shader_texture = m_cat_texture->GetTexture();
PhysObj->SetCustomShaderData(m_cat_sdata);
}
#endif //USE_BODIES


#endif //CAT_MODE

/* FIXME: this object never cleans up */
m_ready = true;
}
@@ -423,6 +541,13 @@ BtPhysTest::~BtPhysTest()
Ticker::Unref(m_light1);
Ticker::Unref(m_light2);

#if CAT_MODE
/* cat datas setup */
delete(m_cat_sdata);
Shader::Destroy(m_cat_shader);
Tiler::Deregister(m_cat_texture);
#endif //CAT_MODE

while (m_constraint_list.Count())
{
EasyConstraint* CurPop = m_constraint_list.Last();
@@ -460,7 +585,7 @@ BtPhysTest::~BtPhysTest()
}
while (m_physobj_list.Count())
{
PhysicsObject* CurPop = m_physobj_list.Last();
PhysicsObject* CurPop = m_physobj_list.Last().m1;
m_physobj_list.Pop();
CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
Ticker::Unref(CurPop);
@@ -469,11 +594,43 @@ BtPhysTest::~BtPhysTest()

}

//-----------------------------------------------------------------------------
// CShaderData
//-----------------------------------------------------------------------------
CatShaderData::CatShaderData(uint32_t vert_decl_flags, Shader* shader)
: GpuShaderData(vert_decl_flags, shader, DebugRenderMode::Default)
{
SetupDefaultData();
}

//-----------------------------------------------------------------------------
void CatShaderData::SetupDefaultData()
{
AddUniform("in_model_view");
AddUniform("in_normal_mat");
AddUniform("in_proj");
AddUniform("in_texture");
}

//-----------------------------------------------------------------------------
void CatShaderData::SetupShaderDatas(mat4 const &model)
{
mat4 proj = g_scene->GetCamera()->GetProjection();
mat4 view = g_scene->GetCamera()->GetView();

mat4 modelview = view * model;
mat3 normalmat = transpose(inverse(mat3(view)));

m_shader->SetUniform(*GetUniform("in_model_view"), modelview);
m_shader->SetUniform(*GetUniform("in_normal_mat"), normalmat);
m_shader->SetUniform(*GetUniform("in_proj"), proj);
}

int main(int argc, char **argv)
{
System::Init(argc, argv);

Application app("BtPhysTest", ivec2(1280, 720), 60.0f);
Application app("BtPhysTest", ivec2(1280, 960), 60.0f);

new BtPhysTest(argc > 1);
app.ShowPointer(false);


+ 37
- 15
test/btphystest.h 查看文件

@@ -8,6 +8,25 @@
#if !defined __BTPHYSTEST_H__
#define __BTPHYSTEST_H__

class CatShaderData : public GpuShaderData
{
friend class CRenderer;

public:
//---
CatShaderData(uint32_t vert_decl_flags, Shader* shader);
//---
void SetupDefaultData();
virtual void SetupShaderDatas(mat4 const &model);
//--
virtual lol::String GetInVertexName() { return lol::String("in_vertex"); }
virtual lol::String GetInNormalName() { return lol::String("in_normal"); }
virtual lol::String GetInColorName() { return lol::String("in_color"); }
virtual lol::String GetInTexCoordName() { return lol::String("in_texcoord"); }

ShaderTexture m_shader_texture;
};

class BtPhysTest : public WorldEntity
{
public:
@@ -34,21 +53,24 @@ private:
KEY_MAX,
};

Camera* m_camera;
Controller * m_controller;
Light * m_light1;
Light * m_light2;
bool m_ready;

lol::phys::Simulation* m_simulation;
Array<EasyConstraint*> m_constraint_list;
Array<PhysicsObject*> m_physobj_list;
Array<PhysicsObject*> m_ground_list;
Array<PhysicsObject*> m_platform_list;
Array<PhysicsObject*> m_character_list;
Array<PhysicsObject*> m_stairs_list;

float m_loop_value;
TileSet* m_cat_texture;
Shader* m_cat_shader;
CatShaderData* m_cat_sdata;
Camera* m_camera;
Controller * m_controller;
Light * m_light1;
Light * m_light2;
bool m_ready;

lol::phys::Simulation* m_simulation;
Array<EasyConstraint*> m_constraint_list;
Array<PhysicsObject*, float> m_physobj_list;
Array<PhysicsObject*> m_ground_list;
Array<PhysicsObject*> m_platform_list;
Array<PhysicsObject*> m_character_list;
Array<PhysicsObject*> m_stairs_list;

float m_loop_value;
};

#endif // __BTPHYSTEST_H__


+ 4
- 1
test/btphystest.vcxproj 查看文件

@@ -75,6 +75,9 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
</None>
</ItemGroup>
<ItemGroup>
<LolFxCompile Include="front_camera_sprite.lolfx" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{ee203b88-44cf-4859-9d42-7a1f43fecb52}</ProjectGuid>
<ConfigurationType>Application</ConfigurationType>
@@ -95,4 +98,4 @@
<ImportGroup Label="ExtensionTargets">
<Import Project="$(SolutionDir)\Lol.Fx.targets" />
</ImportGroup>
</Project>
</Project>

+ 4
- 1
test/btphystest.vcxproj.filters 查看文件

@@ -48,4 +48,7 @@
<ItemGroup>
<None Include="Makefile.am" />
</ItemGroup>
</Project>
<ItemGroup>
<LolFxCompile Include="front_camera_sprite.lolfx" />
</ItemGroup>
</Project>

二進制
test/data/lolcatz.png 查看文件

Before After
Width: 512  |  Height: 512  |  Size: 4.6 KiB

+ 119
- 58
test/physicobject.h 查看文件

@@ -20,12 +20,25 @@
using namespace lol;
using namespace lol::phys;

#if CAT_MODE
#define USE_SPHERE 1
#else
#define USE_BOX 1
#define USE_SPHERE 1
#define USE_CONE 1
#define USE_CYLINDER 1
#define USE_CAPSULE 1
#endif

class PhysicsObject : public WorldEntity
{
public:
PhysicsObject(Simulation* new_sim, const vec3 &base_location, const quat &base_rotation)
: m_ready(false), m_should_render(true), m_is_character(false)
: m_ready(false), m_should_render(true), m_is_character(false), m_custom_shader(0)
{
#if CAT_MODE
m_is_phys = false;
#endif //CAT_MODE
m_physics = new EasyPhysic(this);

m_mesh.Compile("[sc#ddd afcb 60 1 60 -.1]");
@@ -39,8 +52,11 @@ public:
}

PhysicsObject(Simulation* new_sim, const vec3 &base_location, const quat &base_rotation, int dummy)
: m_ready(false), m_should_render(true), m_is_character(false)
: m_ready(false), m_should_render(true), m_is_character(false), m_custom_shader(0)
{
#if CAT_MODE
m_is_phys = false;
#endif //CAT_MODE
if (dummy == 1) //for platform purpose
{
m_physics = new EasyPhysic(this);
@@ -106,10 +122,19 @@ public:
}

PhysicsObject(Simulation* new_sim, float base_mass, const vec3 &base_location, int RandValue = -1)
: m_ready(false), m_should_render(true), m_is_character(false)
: m_ready(false), m_should_render(true), m_is_character(false), m_custom_shader(0)
{
Array<char const *> MeshRand;
Array<int> MeshLimit;
Array<int> MeshType;

#if CAT_MODE
m_is_phys = true;
#endif //CAT_MODE

MeshLimit << 0;

#if USE_BOX
MeshRand << "[sc#add afcb1.7 1.7 1.7 0.4][sc#000 tsw afcb1.9 1.9 1.9 0.4 sx-1 sy-1 sz-1]";
MeshRand << "[sc#dad afcb1.7 1.7 1.7 0.4][sc#000 tsw afcb1.9 1.9 1.9 0.4 sx-1 sy-1 sz-1]";
MeshRand << "[sc#dda afcb1.7 1.7 1.7 0.4][sc#000 tsw afcb1.9 1.9 1.9 0.4 sx-1 sy-1 sz-1]";
@@ -117,17 +142,41 @@ public:
MeshRand << "[sc#ada afcb1.7 1.7 1.7 0.4][sc#000 tsw afcb1.9 1.9 1.9 0.4 sx-1 sy-1 sz-1]";
MeshRand << "[sc#aad afcb1.7 1.7 1.7 0.4][sc#000 tsw afcb1.9 1.9 1.9 0.4 sx-1 sy-1 sz-1]";

int SphereLimit = MeshRand.Count();

MeshLimit << MeshRand.Count();
MeshType << 0;
#endif //USE_BOX


#if USE_SPHERE
#if CAT_MODE
int nb_sprite = 4;
//SPRITE
vec2 start_point = vec2((float)rand(nb_sprite), (float)rand(nb_sprite)) / vec2((float)nb_sprite);
vec2 size = vec2(1.f) / vec2((float)nb_sprite);
m_mesh.BD()->SetTexCoordCustomBuild(MeshType::Quad, MeshFaceType::QuadDefault,
start_point, start_point + size);
m_mesh.BD()->SetTexCoordCustomBuild2(MeshType::Quad, MeshFaceType::QuadDefault,
vec2(-4.f), vec2(4.f));
MeshRand << "[sc#ffff aq 0 0]";
MeshRand << "[sc#ffff aq 0 0]";
MeshRand << "[sc#ffff aq 0 0]";
MeshRand << "[sc#fbbf aq 0 0]";
MeshRand << "[sc#bbff aq 0 0]";
MeshRand << "[sc#bfbf aq 0 0]";
#else
MeshRand << "[sc#add asph1 2]";
MeshRand << "[sc#dad asph1 2]";
MeshRand << "[sc#dda asph1 2]";
MeshRand << "[sc#daa asph1 2]";
MeshRand << "[sc#ada asph1 2]";
MeshRand << "[sc#aad asph1 2]";
#endif

int ConeLimit = MeshRand.Count();
MeshLimit << MeshRand.Count();
MeshType << 1;
#endif //USE_SPHERE

#if USE_CONE
MeshRand << "[sc#add scb#add ad8 2 0 rx180 ty-1 ac8 2 2 0 0 0]";
MeshRand << "[sc#dad scb#dad ad8 2 0 rx180 ty-1 ac8 2 2 0 0 0]";
MeshRand << "[sc#dda scb#dda ad8 2 0 rx180 ty-1 ac8 2 2 0 0 0]";
@@ -135,8 +184,11 @@ public:
MeshRand << "[sc#ada scb#ada ad8 2 0 rx180 ty-1 ac8 2 2 0 0 0]";
MeshRand << "[sc#aad scb#aad ad8 2 0 rx180 ty-1 ac8 2 2 0 0 0]";

int CylLimit = MeshRand.Count();
MeshLimit << MeshRand.Count();
MeshType << 2;
#endif //USE_CONE

#if USE_CYLINDER
MeshRand << "[sc#add scb#add ad8 2 0 rx180 ty-1 my ac8 2 2 2 0 0]";
MeshRand << "[sc#dad scb#dad ad8 2 0 rx180 ty-1 my ac8 2 2 2 0 0]";
MeshRand << "[sc#dda scb#dda ad8 2 0 rx180 ty-1 my ac8 2 2 2 0 0]";
@@ -144,8 +196,11 @@ public:
MeshRand << "[sc#ada scb#ada ad8 2 0 rx180 ty-1 my ac8 2 2 2 0 0]";
MeshRand << "[sc#aad scb#aad ad8 2 0 rx180 ty-1 my ac8 2 2 2 0 0]";

int CapsLimit = MeshRand.Count();
MeshLimit << MeshRand.Count();
MeshType << 3;
#endif //USE_CYLINDER

#if USE_CAPSULE
MeshRand << "[sc#add scb#add acap1 2 1]";
MeshRand << "[sc#dad scb#dad acap1 2 1]";
MeshRand << "[sc#dda scb#dda acap1 2 1]";
@@ -153,70 +208,60 @@ public:
MeshRand << "[sc#ada scb#ada acap1 2 1]";
MeshRand << "[sc#aad scb#aad acap1 2 1]";

switch (RandValue)
MeshLimit << MeshRand.Count();
MeshType << 4;
#endif //USE_CAPSULE

int RandLimit = RandValue;
if (MeshLimit.Count() <= RandValue || RandValue < 0)
RandLimit = rand(MeshLimit.Count() - 1);
RandValue = rand(MeshLimit[RandLimit], MeshLimit[RandLimit + 1]);

m_physics = new EasyPhysic(this);

m_mesh.Compile(MeshRand[RandValue]);
m_mesh.Scale(vec3(OBJ_SIZE));
vec3 BoxSize = vec3(2.0f) * OBJ_SIZE;
int ColGroup = 1;

switch (MeshType[RandLimit])
{
case 0:
{
RandValue = rand(SphereLimit);
m_physics->SetShapeToBox(BoxSize);
ColGroup += 0;
break;
}
case 1:
{
RandValue = rand(SphereLimit, ConeLimit);
m_physics->SetShapeToSphere(BoxSize.x);
ColGroup += 1;
break;
}
case 2:
{
RandValue = rand(ConeLimit, CylLimit);
m_physics->SetShapeToCone(BoxSize.x, BoxSize.y);
ColGroup += 2;
break;
}
case 3:
{
RandValue = rand(CylLimit, CapsLimit);
m_physics->SetShapeToCylinder(BoxSize);
ColGroup += 3;
break;
}
case 4:
{
RandValue = rand(CapsLimit, MeshRand.Count());
m_physics->SetShapeToCapsule(BoxSize.x, BoxSize.y);
ColGroup += 4;
break;
}
default:
{
RandValue = rand(MeshRand.Count());
}
}

m_physics = new EasyPhysic(this);

m_mesh.Compile(MeshRand[RandValue]);
vec3 BoxSize = vec3(2.0f);
int ColGroup = 1;
if (RandValue < SphereLimit)
{
m_physics->SetShapeToBox(BoxSize);
ColGroup += 0;
}
else if (RandValue < ConeLimit)
{
m_physics->SetShapeToSphere(BoxSize.x * 2.f);
ColGroup += 1;
}
else if (RandValue < CylLimit)
{
m_physics->SetShapeToCone(BoxSize.x, BoxSize.y);
ColGroup += 2;
}
else if (RandValue < CapsLimit)
{
m_physics->SetShapeToCylinder(BoxSize);
ColGroup += 3;
}
else
{
m_physics->SetShapeToCapsule(BoxSize.x, BoxSize.y);
ColGroup += 4;
}

m_physics->SetHitRestitution(1.0f);
m_physics->SetCollisionChannel(0, 0xFF);
//m_physics->SetCollisionChannel(ColGroup, (1 << ColGroup)|(1));
m_physics->SetMass(base_mass);
@@ -246,6 +291,11 @@ public:
m_should_render = should_render;
}

void SetCustomShaderData(GpuShaderData* custom_shader)
{
m_custom_shader = custom_shader;
}

EasyMesh *GetMesh() { return &m_mesh; }
EasyPhysic *GetPhysic() { return m_physics; }
EasyCharacterController *GetCharacter() { return m_character; }
@@ -266,30 +316,41 @@ protected:
{
WorldEntity::TickDraw(seconds);

if (!m_ready)
{
m_mesh.MeshConvert();
m_ready = true;
}

if (m_should_render)
#if CAT_MODE
if (!m_is_phys || m_custom_shader)
#endif //CAT_MODE
{
if (m_is_character)
m_mesh.Render(m_character->GetTransform());
else
m_mesh.Render(m_physics->GetTransform());
if (!m_ready)
{
if (m_custom_shader)
m_mesh.MeshConvert(m_custom_shader);
else
m_mesh.MeshConvert();
m_ready = true;
}
else if (m_should_render)
{
if (m_is_character)
m_mesh.Render(m_character->GetTransform());
else
m_mesh.Render(m_physics->GetTransform());
}
}
}

private:
//Base datas
EasyMesh m_mesh;
EasyPhysic* m_physics;
EasyPhysic* m_physics;
EasyCharacterController* m_character;
GpuShaderData* m_custom_shader;

bool m_ready;
bool m_should_render;
bool m_is_character;
#if CAT_MODE
bool m_is_phys;
#endif //CAT_MODE
};

#endif /* __PHYSICOBJECT_H__ */


+ 90
- 3
test/physics/easyphysics.cpp 查看文件

@@ -38,6 +38,7 @@ EasyPhysic::EasyPhysic(WorldEntity* NewOwnerEntity) :
m_convex_shape(NULL),
m_motion_state(NULL),
m_mass(.0f),
m_hit_restitution(.0f),
m_collision_group(1),
m_collision_mask(1),
m_owner_entity(NewOwnerEntity),
@@ -174,7 +175,7 @@ void EasyPhysic::BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol
//-------------------------------------------------------------------------
//Mass related functions
//--
//Set Shape functions
//Set Mass functions
void EasyPhysic::SetMass(float mass)
{
m_mass = mass;
@@ -182,12 +183,26 @@ void EasyPhysic::SetMass(float mass)
if (m_rigid_body)
{
SetLocalInertia(m_mass);
m_rigid_body->setMassProps(mass, m_local_inertia);
m_rigid_body->setMassProps(m_mass, m_local_inertia);
}
}

//-------------------------------------------------------------------------
//Hit restitution functions
//--
//Set Hit Restitution functions
void EasyPhysic::SetHitRestitution(float hit_restitution)
{
m_hit_restitution = hit_restitution;

if (m_rigid_body)
{
m_rigid_body->setRestitution(m_hit_restitution);
}
}

//-------------------------------------------------------------------------
//Final conversion pass functons : Body related
//Final conversion pass functions : Body related
//--

//Init to rigid body
@@ -200,6 +215,7 @@ void EasyPhysic::InitBodyToRigid(bool SetToKinematic)
SetTransform(vec3(.0f));

btRigidBody::btRigidBodyConstructionInfo NewInfos(m_mass, m_motion_state, m_collision_shape, m_local_inertia);
NewInfos.m_restitution = m_hit_restitution;
m_rigid_body = new btRigidBody(NewInfos);
m_collision_object = m_rigid_body;
m_collision_object->setUserPointer(this);
@@ -329,6 +345,77 @@ void EasyPhysic::RemoveFromSimulation(class Simulation* current_simulation)
}
}

//-------------------------------------------------------------------------
//Force/Impulse functions
//--
void EasyPhysic::AddImpulse(const lol::vec3& impulse)
{
if (m_rigid_body)
m_rigid_body->applyCentralImpulse(LOL2BT_VEC3(impulse));
}

void EasyPhysic::AddImpulse(const lol::vec3& impulse, const lol::vec3& rel_pos)
{
if (m_rigid_body)
m_rigid_body->applyImpulse(LOL2BT_VEC3(impulse), LOL2BTU_VEC3(rel_pos));
}

void EasyPhysic::AddImpulseTorque(const lol::vec3& torque)
{
if (m_rigid_body)
m_rigid_body->applyTorqueImpulse(LOL2BT_VEC3(torque));
}

//--
void EasyPhysic::AddForce(const lol::vec3& force)
{
if (m_rigid_body)
m_rigid_body->applyCentralForce(LOL2BT_VEC3(force));
}

void EasyPhysic::AddForce(const lol::vec3& force, const lol::vec3& rel_pos)
{
if (m_rigid_body)
m_rigid_body->applyForce(LOL2BT_VEC3(force), LOL2BTU_VEC3(rel_pos));
}

void EasyPhysic::AddForceTorque(const lol::vec3& torque)
{
if (m_rigid_body)
m_rigid_body->applyTorque(LOL2BT_VEC3(torque));
}

//-------------------------------------------------------------------------
//Movements getter
//--
lol::vec3 EasyPhysic::GetLinearVelocity() const
{
if (m_rigid_body)
return BT2LOL_VEC3(m_rigid_body->getLinearVelocity());
return lol::vec3(.0f);
}

lol::vec3 EasyPhysic::GetLinearForce() const
{
if (m_rigid_body)
return BT2LOL_VEC3(m_rigid_body->getTotalForce());
return lol::vec3(.0f);
}

lol::vec3 EasyPhysic::GetAngularVelocity() const
{
if (m_rigid_body)
return BT2LOL_VEC3(m_rigid_body->getAngularVelocity());
return lol::vec3(.0f);
}

lol::vec3 EasyPhysic::GetAngularForce() const
{
if (m_rigid_body)
return BT2LOL_VEC3(m_rigid_body->getTotalTorque());
return lol::vec3(.0f);
}

//Set Local Inertia
void EasyPhysic::SetLocalInertia(float mass)
{


+ 50
- 17
test/physics/easyphysics.h 查看文件

@@ -55,27 +55,43 @@ protected:
virtual void BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix);
public:
virtual void SetMass(float mass);
virtual float GetMass() { return m_mass; }
virtual void SetHitRestitution(float hit_restitution);
virtual void InitBodyToRigid(bool ZeroMassIsKinematic=false);
virtual void InitBodyToGhost();
virtual void AddToSimulation(class Simulation* current_simulation);
virtual void RemoveFromSimulation(class Simulation* current_simulation);

//Force/Impulse functions
virtual void AddImpulse(const lol::vec3& impulse);
virtual void AddImpulse(const lol::vec3& impulse, const lol::vec3& rel_pos);
virtual void AddImpulseTorque(const lol::vec3& torque);
virtual void AddForce(const lol::vec3& force);
virtual void AddForce(const lol::vec3& force, const lol::vec3& rel_pos);
virtual void AddForceTorque(const lol::vec3& torque);

//Movements getter
lol::vec3 GetLinearVelocity() const;
lol::vec3 GetLinearForce() const;
lol::vec3 GetAngularVelocity() const;
lol::vec3 GetAngularForce() const;

protected:
virtual void SetLocalInertia(float mass);
virtual void SetShapeTo(btCollisionShape* collision_shape);

virtual btGhostObject* GetGhostObjectInstance();

btCollisionObject* m_collision_object;
btCollisionObject* m_collision_object;

btGhostObject* m_ghost_object;
btGhostObject* m_ghost_object;

btRigidBody* m_rigid_body;
btVector3 m_local_inertia;
btVector3 m_local_inertia;

btCollisionShape* m_collision_shape;
btConvexShape* m_convex_shape;
btMotionState* m_motion_state;
btCollisionShape* m_collision_shape;
btConvexShape* m_convex_shape;
btMotionState* m_motion_state;

#else // NO PHYSIC IMPLEMENTATION

@@ -95,11 +111,27 @@ private:
virtual void BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix) { }
public:
virtual void SetMass(float mass) { }
virtual float GetMass() { return .0f; }
virtual void SetHitRestitution(float hit_restitution) { }
virtual void InitBodyToRigid() { }
virtual void InitBodyToGhost() { }
virtual void AddToSimulation(class Simulation* current_simulation) { }
virtual void RemoveFromSimulation(class Simulation* current_simulation) { }

//Force/Impulse functions
virtual void AddImpulse(const lol::vec3& impulse) { }
virtual void AddImpulse(const lol::vec3& impulse, const lol::vec3& rel_pos) { }
virtual void AddImpulseTorque(const lol::vec3& torque) { }
virtual void AddForce(const lol::vec3& force) { }
virtual void AddForce(const lol::vec3& force, const lol::vec3& rel_pos) { }
virtual void AddForceTorque(const lol::vec3& torque) { }

//Movements getter
lol::vec3 GetLinearVelocity() const { return lol::vec3(.0f); }
lol::vec3 GetLinearForce() const { return lol::vec3(.0f); }
lol::vec3 GetAngularVelocity() const { return lol::vec3(.0f); }
lol::vec3 GetAngularForce() const { return lol::vec3(.0f); }

virtual void InitBodyToGhost() { }

#endif // PHYSIC IMPLEMENTATION
@@ -148,21 +180,22 @@ public:
}

protected:
lol::mat4 m_local_to_world;
float m_mass;
int m_collision_group;
int m_collision_mask;
WorldEntity* m_owner_entity;
Simulation* m_owner_simulation;
lol::mat4 m_local_to_world;
float m_mass;
float m_hit_restitution;
int m_collision_group;
int m_collision_mask;
WorldEntity* m_owner_entity;
Simulation* m_owner_simulation;

//Base/Attachment logic
Array<EasyPhysic*> m_based_physic_list; //List of objects based on this : this object moves, its based object MoveStep with it.
EasyPhysic* m_base_physic; //Base for this object : The base moves, the object moves with it.
bool m_base_lock_location; //when this is TRUE, location moves with rotation change.
bool m_base_lock_rotation; //when this is TRUE, rotation moves with rotation change.
Array<EasyPhysic*> m_based_physic_list; //List of objects based on this : this object moves, its based object MoveStep with it.
EasyPhysic* m_base_physic; //Base for this object : The base moves, the object moves with it.
bool m_base_lock_location; //when this is TRUE, location moves with rotation change.
bool m_base_lock_rotation; //when this is TRUE, rotation moves with rotation change.

//Touch logic
Array<EasyPhysic*> m_touching_physic; //Maintained by ghost objects
Array<EasyPhysic*> m_touching_physic; //Maintained by ghost objects
};

} /* namespace phys */


Loading…
取消
儲存