@@ -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); | |||
} | |||
@@ -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> | |||
@@ -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); | |||
@@ -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__ | |||
@@ -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> |
@@ -48,4 +48,7 @@ | |||
<ItemGroup> | |||
<None Include="Makefile.am" /> | |||
</ItemGroup> | |||
</Project> | |||
<ItemGroup> | |||
<LolFxCompile Include="front_camera_sprite.lolfx" /> | |||
</ItemGroup> | |||
</Project> |
@@ -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__ */ | |||
@@ -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) | |||
{ | |||
@@ -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 */ | |||