diff --git a/build/vs2010/Lol.sln b/build/vs2010/Lol.sln index a188eafd..ed05914e 100644 --- a/build/vs2010/Lol.sln +++ b/build/vs2010/Lol.sln @@ -114,6 +114,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Benlitz", "Benlitz", "{B583 EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "benlitzTest1", "..\..\people\benlitz\test1\benlitzTest1.vcxproj", "{FAF82AD2-D9F4-4694-9A01-103BC5B771B4}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MeshViewer", "..\..\test\MeshViewer.vcxproj", "{7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -617,6 +619,24 @@ Global {FAF82AD2-D9F4-4694-9A01-103BC5B771B4}.Release|x64.ActiveCfg = Release|x64 {FAF82AD2-D9F4-4694-9A01-103BC5B771B4}.Release|x64.Build.0 = Release|x64 {FAF82AD2-D9F4-4694-9A01-103BC5B771B4}.Release|Xbox 360.ActiveCfg = Release|x64 + {7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E}.Debug|Any CPU.ActiveCfg = Debug|x64 + {7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 + {7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E}.Debug|Mixed Platforms.Build.0 = Debug|x64 + {7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E}.Debug|PS3.ActiveCfg = Debug|x64 + {7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E}.Debug|Win32.ActiveCfg = Debug|Win32 + {7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E}.Debug|Win32.Build.0 = Debug|Win32 + {7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E}.Debug|x64.ActiveCfg = Debug|x64 + {7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E}.Debug|x64.Build.0 = Debug|x64 + {7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E}.Debug|Xbox 360.ActiveCfg = Debug|x64 + {7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E}.Release|Any CPU.ActiveCfg = Release|x64 + {7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E}.Release|Mixed Platforms.ActiveCfg = Release|x64 + {7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E}.Release|Mixed Platforms.Build.0 = Release|x64 + {7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E}.Release|PS3.ActiveCfg = Release|x64 + {7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E}.Release|Win32.ActiveCfg = Release|Win32 + {7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E}.Release|Win32.Build.0 = Release|Win32 + {7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E}.Release|x64.ActiveCfg = Release|x64 + {7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E}.Release|x64.Build.0 = Release|x64 + {7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E}.Release|Xbox 360.ActiveCfg = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -638,6 +658,7 @@ Global {B1E10086-A1DA-401A-834D-969C9DBB5CC1} = {E0491194-35E3-4513-9D31-608EA3165ECF} {80F81C11-8DA2-4990-91CB-9807783BA46E} = {E0491194-35E3-4513-9D31-608EA3165ECF} {EE203B88-44CF-4859-9D42-7A1F43FECB52} = {E0491194-35E3-4513-9D31-608EA3165ECF} + {7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E} = {E0491194-35E3-4513-9D31-608EA3165ECF} {B92ABADC-45BE-4CC5-B724-9426053123A1} = {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04} {7B083DA2-FE08-4F6D-BFDD-195D5C2783EB} = {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04} {1C5B8702-290C-42DA-AA9E-671348F5B747} = {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04} diff --git a/src/camera.cpp b/src/camera.cpp index 878469b4..fe10323e 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -87,6 +87,12 @@ mat4 const &Camera::GetProjMatrix() return m_proj_matrix; } +void Camera::ForceSceneUpdate() +{ + Scene::GetDefault()->SetViewMatrix(m_view_matrix); + Scene::GetDefault()->SetProjMatrix(m_proj_matrix); +} + void Camera::TickGame(float seconds) { WorldEntity::TickGame(seconds); @@ -124,8 +130,7 @@ void Camera::TickDraw(float seconds) { WorldEntity::TickDraw(seconds); - Scene::GetDefault()->SetViewMatrix(m_view_matrix); - Scene::GetDefault()->SetProjMatrix(m_proj_matrix); + ForceSceneUpdate(); } } /* namespace lol */ diff --git a/src/camera.h b/src/camera.h index 077cbdaa..319c5928 100644 --- a/src/camera.h +++ b/src/camera.h @@ -40,6 +40,7 @@ public: mat4 const &GetViewMatrix(); mat4 const &GetProjMatrix(); + void ForceSceneUpdate(); protected: virtual void TickGame(float seconds); diff --git a/src/easymesh/easymesh-parser.y b/src/easymesh/easymesh-parser.y index 988e1427..e6651ee9 100644 --- a/src/easymesh/easymesh-parser.y +++ b/src/easymesh/easymesh-parser.y @@ -47,7 +47,7 @@ %token T_TRANSLATEX T_ROTATEX T_TAPERX T_SCALEX T_MIRRORX %token T_TRANSLATEY T_ROTATEY T_TAPERY T_SCALEY T_MIRRORY %token T_TRANSLATEZ T_ROTATEZ T_TAPERZ T_SCALEZ T_MIRRORZ -%token T_TRANSLATE T_SCALE T_TOGGLESCALEWINDING +%token T_TRANSLATE T_SCALE T_TOGGLESCALEWINDING T_RADIALJITTER %token T_CSGUNION T_CSGSUBSTRACT T_CSGAND T_CSGXOR %token T_CHAMFER @@ -135,6 +135,7 @@ transform_command: | T_MIRRORX { mc.m_mesh.MirrorX(); } | T_MIRRORY { mc.m_mesh.MirrorY(); } | T_MIRRORZ { mc.m_mesh.MirrorZ(); } + | T_RADIALJITTER args1 { mc.m_mesh.RadialJitter($2.f0); } | T_TOGGLESCALEWINDING { mc.m_mesh.ToggleScaleWinding(); } | T_CSGUNION { mc.m_mesh.CsgUnion(); } | T_CSGSUBSTRACT { mc.m_mesh.CsgSubstract(); } diff --git a/src/easymesh/easymesh-scanner.l b/src/easymesh/easymesh-scanner.l index 40e51e84..42ee7cbb 100644 --- a/src/easymesh/easymesh-scanner.l +++ b/src/easymesh/easymesh-scanner.l @@ -66,10 +66,11 @@ sx { return token::T_SCALEX; } sy { return token::T_SCALEY; } sz { return token::T_SCALEZ; } s { return token::T_SCALE; } -tsw { return token::T_TOGGLESCALEWINDING; } +tsw { return token::T_TOGGLESCALEWINDING; } mx { return token::T_MIRRORX; } my { return token::T_MIRRORY; } mz { return token::T_MIRRORZ; } +rj { return token::T_RADIALJITTER; } csgu { return token::T_CSGUNION; } csgs { return token::T_CSGSUBSTRACT; } diff --git a/src/easymesh/easymesh.h b/src/easymesh/easymesh.h index 1857ed65..cf4da270 100644 --- a/src/easymesh/easymesh.h +++ b/src/easymesh/easymesh.h @@ -105,6 +105,11 @@ public: void AppendCog(int nbsides, float h, float r10, float r20, float r1, float r2, float r12, float r22, float sidemul, int offset); + //Convenience functions +public: + int GetVertexCount() { return m_vert.Count(); } + vec3 const &GetVertexLocation(int i) { return m_vert[i].m1; } + private: vec4 m_color, m_color2; Array m_indices; diff --git a/test/Makefile.am b/test/Makefile.am index 7dcd6fd2..28c75ac1 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -10,7 +10,7 @@ bench: benchsuite$(EXEEXT) EXTRA_DIST = data/gradient.png -noinst_PROGRAMS = benchsuite $(testsuite) btphystest +noinst_PROGRAMS = benchsuite $(testsuite) btphystest MeshViewer TESTS = $(testsuite) @@ -49,3 +49,8 @@ btphystest_CPPFLAGS = @LOL_CFLAGS@ -I$(top_srcdir)/src/bullet \ btphystest_LDFLAGS = $(top_builddir)/src/liblol.a @LOL_LIBS@ btphystest_DEPENDENCIES = $(top_builddir)/src/liblol.a +MeshViewer_SOURCES = MeshViewer.cpp +MeshViewer_CPPFLAGS = @LOL_CFLAGS@ +MeshViewer_LDFLAGS = $(top_builddir)/src/liblol.a @LOL_LIBS@ +MeshViewer_DEPENDENCIES = $(top_builddir)/src/liblol.a + diff --git a/test/MeshViewer.cpp b/test/MeshViewer.cpp new file mode 100644 index 00000000..3af6d743 --- /dev/null +++ b/test/MeshViewer.cpp @@ -0,0 +1,168 @@ +// +// Lol Engine - EasyMesh tutorial +// +// Copyright: (c) 2011-2013 Sam Hocevar +// (c) 2012-2013 Benjamin "Touky" Huet +// This program is free software; you can redistribute it and/or +// modify it under the terms of the Do What The Fuck You Want To +// Public License, Version 2, as published by Sam Hocevar. See +// http://www.wtfpl.net/ for more details. +// + +#if defined HAVE_CONFIG_H +# include "config.h" +#endif + +#include "core.h" + +using namespace std; +using namespace lol; +#define MESH_DIST 5.0f + +class MeshViewer : public WorldEntity +{ +public: + MeshViewer() + { + int i=10; + while (i--) + { + m_meshes.Push(EasyMesh()); + m_meshes.Last().Compile("[sc#0f0 ab 2 2 2 t .8 .8 .8 rx 20 ry 20 [sc#00f ab 2 2 2 tx 0 csgu]]"); + } + + m_angle = 0; + + m_camera = new Camera(vec3(0.f, 600.f, 0.f), + vec3(0.f, 0.f, 0.f), + vec3(0, 1, 0)); + m_camera->SetPerspective(60.f, 16, 9, .1f, 1000.f); + m_camera->SetTarget(vec3(0.f, 0.f, 0.f)); + m_camera->SetPosition(vec3(0.f, 0.f, 5.f)); + m_camera->ForceSceneUpdate(); + Ticker::Ref(m_camera); + min_pos = vec3(FLT_MAX); + max_pos = vec3(-FLT_MAX); + + m_ready = false; + } + + ~MeshViewer() + { + Ticker::Unref(m_camera); + } + + virtual void TickGame(float seconds) + { + WorldEntity::TickGame(seconds); + //vec4 vertex = in_ModelView * vec4(in_Vertex, 1.0); + // gl_Position = in_Proj * vertex; + + + m_angle += seconds * 70.0f; + m_mat = mat4::rotate(m_angle, vec3(0, 1, 0)); + + //mat4 screen_matrix = Scene::GetDefault()->GetProjMatrix() * Scene::GetDefault()->GetViewMatrix(); + mat4 world_view_matrix = m_camera->GetViewMatrix() * m_mat; + mat4 world_screen_matrix = m_camera->GetProjMatrix() * world_view_matrix; + mat4 view_world_matrix = inverse(m_camera->GetViewMatrix()); + mat4 screen_view_matrix = inverse(m_camera->GetProjMatrix()); + vec4 a(0, 2, 0, 1.0f); + vec4 b(0,-2, 0, 1.0f); + vec4 c(0, 0, -2, 1.0f); + vec4 d(-1, -1, 1, 1.0f); + + //vec2 toto; + //near plane : vec4(toto, 1.f, 1.f); + //far plane : vec4(toto, -1.f, 1.f); + + a = vec4((world_screen_matrix * a).xyz / a.w, a.w); + b = vec4((world_screen_matrix * b).xyz / b.w, b.w); + c = vec4((inverse(world_screen_matrix) * c).xyz / c.w, c.w); + d = vec4((inverse(world_screen_matrix) * d).xyz / d.w, d.w); + a = b; + c = d; + + //this is the algorithm for a camera that must keep n target in the screen + { + //Get the Min/Max needed + vec3 new_min_pos(FLT_MAX); + vec3 new_max_pos(-FLT_MAX); + for (int i = 0; i < m_meshes.Last().GetVertexCount(); i++) + { + vec4 vpos = world_view_matrix * vec4(m_meshes.Last().GetVertexLocation(i), 1.0f); + new_min_pos = min(vpos.xyz, new_min_pos); + new_max_pos = max(vpos.xyz, new_max_pos); + } + + //Actual camera algorithm + { + vec4 BottomLeft = m_camera->GetProjMatrix() * vec4(new_min_pos.xy, new_min_pos.z, 1.0f); + vec4 TopRight = m_camera->GetProjMatrix() * vec4(new_max_pos.xy, new_min_pos.z, 1.0f); + BottomLeft = vec4(BottomLeft.xyz / BottomLeft.w, BottomLeft.w); + TopRight = vec4(TopRight.xyz / TopRight.w, TopRight.w); + //vec2 NewSize = TopRight.xy - BottomLeft.xy; + //NewSize.x = max(NewSize.x, NewSize.y) * 1.5f; + vec4 DistantPoint = screen_view_matrix * vec4(vec2(1.0f, 1.0f), TopRight.z * TopRight.w, TopRight.w); + + vec3 vcenter = vec3(new_min_pos.xy + new_max_pos.xy, .0f) * .5f; + vec4 new_pos = screen_view_matrix * vec4(.0f, .0f, new_min_pos.z, 1.0f); + //vcenter.z += (new_pos.z - new_pos.z * NewSize.x); + vcenter = (view_world_matrix * vec4(vcenter, 1.0f)).xyz; + + m_camera->SetPosition(damp(m_camera->GetPosition(), vcenter, 0.4f, seconds)); + //m_camera->SetPosition(vcenter); + m_camera->SetTarget(m_camera->GetPosition() + vec3(0, 0, -5.0f)); + } + // + } + } + + virtual void TickDraw(float seconds) + { + WorldEntity::TickDraw(seconds); + + if (!m_ready) + { + for (int i = 0; i < m_meshes.Count(); i++) + m_meshes[i].MeshConvert(); + m_ready = true; + } + + Video::SetClearColor(vec4(0.0f, 0.0f, 0.0f, 1.0f)); + + m_mat = mat4::translate(vec3(m_meshes.Count() * MESH_DIST * 0.5f, 0, m_meshes.Count() * MESH_DIST) * -1.0f) * m_mat; + for (int i = 0; i < m_meshes.Count(); i++) + { + m_mat = mat4::translate(vec3(MESH_DIST * 0.5f, 0, MESH_DIST)) * m_mat; + m_meshes[i].Render(m_mat); + Video::Clear(ClearMask::Depth); + } + //m_mat = mat4::translate(vec3(.0f)); + //m_meshes.Last().Render(m_mat); + } + +private: + //Array m_gears; + float m_angle; + mat4 m_mat; + vec3 min_pos; + vec3 max_pos; + + Array m_meshes; + Camera *m_camera; + + bool m_ready; +}; + +int main(int argc, char **argv) +{ + System::Init(argc, argv); + + Application app("MeshViewer", ivec2(960, 600), 60.0f); + new MeshViewer(); + app.Run(); + + return EXIT_SUCCESS; +} + diff --git a/test/MeshViewer.vcxproj b/test/MeshViewer.vcxproj new file mode 100644 index 00000000..79875e26 --- /dev/null +++ b/test/MeshViewer.vcxproj @@ -0,0 +1,65 @@ + + + + + Debug + PS3 + + + Debug + Win32 + + + Debug + x64 + + + Debug + Xbox 360 + + + Release + PS3 + + + Release + Win32 + + + Release + x64 + + + Release + Xbox 360 + + + + + + + + {9e62f2fe-3408-4eae-8238-fd84238ceeda} + + + + {7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E} + Application + Win32Proj + + + + + + + + + + + + + + + + + \ No newline at end of file