Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2010-10-17 17:19:03 +0000
committerStijn Buys <ingar@osirion.org>2010-10-17 17:19:03 +0000
commitd6e4c4e7c2b1e28961f1dfe2f25ef96ced60b21b (patch)
tree63744dff093a8b23f65d9c68b922b678805647d9
parentea6e6bb769d713ac55114c1940626f13e384ebed (diff)
core bullet physics support,
initial vstrafe support
-rw-r--r--AUTHORS5
-rw-r--r--ChangeLog5
-rw-r--r--configure.in46
-rw-r--r--osirion-doc.webprj21
-rw-r--r--osirion.kdevelop252
-rw-r--r--src/client/action.h1
-rw-r--r--src/client/input.cc22
-rw-r--r--src/client/keyboard.cc16
-rw-r--r--src/core/Makefile.am73
-rw-r--r--src/core/entity.cc127
-rw-r--r--src/core/entity.h78
-rw-r--r--src/core/gameserver.cc9
-rw-r--r--src/core/physics.cc54
-rw-r--r--src/core/physics.h53
-rw-r--r--src/core/zone.cc36
-rw-r--r--src/core/zone.h9
-rw-r--r--src/game/base/cargo.cc1
-rw-r--r--src/game/base/cargopod.cc5
-rw-r--r--src/game/base/game.cc5
-rw-r--r--src/game/base/ship.cc15
-rw-r--r--src/game/base/ship.h3
-rw-r--r--src/math/axis.cc9
-rw-r--r--src/math/axis.h12
-rw-r--r--src/math/vector3f.cc7
-rw-r--r--src/math/vector3f.h11
-rw-r--r--src/render/Makefile.am45
-rw-r--r--src/render/debugdrawer.cc127
-rw-r--r--src/render/debugdrawer.h54
-rw-r--r--src/render/draw.cc37
-rw-r--r--src/render/render.cc10
-rw-r--r--src/render/render.h4
-rw-r--r--src/sys/sys.h5
32 files changed, 778 insertions, 379 deletions
diff --git a/AUTHORS b/AUTHORS
index 0753833..49252bb 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1 +1,4 @@
-Ingar <ingar@telenet.be>
+Project::OSiRiON
+Copyright (c) 2007-2010, Stijn Buys
+http://ingar.satgnu.net/osirion
+
diff --git a/ChangeLog b/ChangeLog
index e69de29..7e162dd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -0,0 +1,5 @@
+
+revision xyz "Bullet in the Sky"
+
+revision 754 "Broken Skies"
+ - replaced skyglobes with skyboxes \ No newline at end of file
diff --git a/configure.in b/configure.in
index a64eed2..0b32047 100644
--- a/configure.in
+++ b/configure.in
@@ -240,39 +240,33 @@ AC_ARG_WITH(bullet,
)
)
-dnl disable bullet for now
-with_bullet=no
+save_CPPFLAGS="$CPPFLAGS"
+save_LDFLAGS="$LDFLAGS"
-if test "x${with_bullet}" != "xno"; then
- save_CPPFLAGS="$CPPFLAGS"
- save_LDFLAGS="$LDFLAGS"
+AC_MSG_CHECKING(for bullet directory)
- AC_MSG_CHECKING(for bullet directory)
+BULLET_DIR="/usr/local"
+if test "x${with_bullet}" != "x"; then
+ BULLET_DIR="${with_bullet}"
+fi
+AC_MSG_RESULT([$BULLET_DIR])
- BULLET_DIR="/usr/local"
- if test "x${with_bullet}" != "x"; then
- BULLET_DIR="${with_bullet}"
- fi
- AC_MSG_RESULT([$BULLET_DIR])
+BULLET_CFLAGS="-I${BULLET_DIR}/include/bullet"
+BULLET_LIBS="-L${BULLET_DIR}/lib"
- BULLET_CFLAGS="-I${BULLET_DIR}/include/bullet"
- BULLET_LIBS="-L${BULLET_DIR}/lib"
+CPPFLAGS="$save_CPPFLAGS $BULLET_CFLAGS"
+LDFLAGS="$save_LDFLAGS $BULLET_LIBS"
- CPPFLAGS="$save_CPPFLAGS $BULLET_CFLAGS"
- LDFLAGS="$save_LDFLAGS $BULLET_LIBS"
+AC_CHECK_HEADER(btBulletDynamicsCommon.h,
+ AC_DEFINE(HAVE_BULLET, yes, [Define this if you have the bullet physics library])
+ BULLET_LIBS="$BULLET_LIBS -lLinearMath -lBulletDynamics -lBulletCollision"
+ HAVE_BULLET="yes",
+ AC_MSG_ERROR([bullet physics library not found (http://bulletphysics.org)])
+)
- AC_CHECK_HEADER(btBulletDynamicsCommon.h,
- AC_DEFINE(HAVE_BULLET, yes, [Define this if you have the bullet physics library])
- BULLET_LIBS="$BULLET_LIBS -lbulletmath -lbulletdynamics -lbulletcollision"
- HAVE_BULLET="yes",
- BULLET_LIBS=""
- BULLET_CFLAGS=""
- HAVE_BULLET="no"
- )
+CPPFLAGS="$save_CPPFLAGS"
+LDFLAGS="$save_LDFLAGS"
- CPPFLAGS="$save_CPPFLAGS"
- LDFLAGS="$save_LDFLAGS"
-fi
AC_SUBST(BULLET_CFLAGS)
AC_SUBST(BULLET_LIBS)
diff --git a/osirion-doc.webprj b/osirion-doc.webprj
deleted file mode 100644
index bb11a5c..0000000
--- a/osirion-doc.webprj
+++ /dev/null
@@ -1,21 +0,0 @@
-<!DOCTYPE webproject>
-<webproject>
- <project type="Local" name="The Osirion Project - Documentation" encoding="utf8" >
- <upload/>
- <author>Ingar</author>
- <email>ingar@telenet.be</email>
- <defaultDTD>-//W3C//DTD HTML 4.01//EN</defaultDTD>
- <item url="doc/" uploadstatus="1" />
- <item modified_time="1217287896" url="doc/assets.html" uploadstatus="1" />
- <item modified_time="1217008503" url="doc/index.html" uploadstatus="1" />
- <item modified_time="1216035705" url="doc/license.html" uploadstatus="1" />
- <item modified_time="1217944621" url="doc/manual.html" uploadstatus="1" />
- <item modified_time="1217009100" url="doc/models.html" uploadstatus="1" />
- <item modified_time="1216214171" url="doc/style.css" uploadstatus="1" />
- <item modified_time="1217289882" url="doc/world.html" uploadstatus="1" />
- <item url="" uploadstatus="1" />
- <templates>templates/</templates>
- <toolbars>toolbars/</toolbars>
- <annotations/>
- </project>
-</webproject>
diff --git a/osirion.kdevelop b/osirion.kdevelop
deleted file mode 100644
index 105213e..0000000
--- a/osirion.kdevelop
+++ /dev/null
@@ -1,252 +0,0 @@
-<?xml version = '1.0'?>
-<kdevelop>
- <general>
- <author>Ingar</author>
- <email>ingar@telenet.be</email>
- <version>0.0.1</version>
- <projectmanagement>KDevAutoProject</projectmanagement>
- <primarylanguage>C++</primarylanguage>
- <keywords>
- <keyword>C++</keyword>
- <keyword>Code</keyword>
- <keyword>SDL</keyword>
- </keywords>
- <ignoreparts/>
- <projectname>osirion</projectname>
- <projectdirectory>./</projectdirectory>
- <absoluteprojectpath>false</absoluteprojectpath>
- <description>The OSiRiON Project is an SDL+OpenGL space game.</description>
- <defaultencoding/>
- <versioncontrol/>
- </general>
- <kdevautoproject>
- <general>
- <activetarget>src/render/librender.la</activetarget>
- <useconfiguration>debug</useconfiguration>
- </general>
- <run>
- <mainprogram/>
- <terminal>true</terminal>
- <directoryradio>executable</directoryradio>
- <runarguments>
- <osirion/>
- <osiriond/>
- </runarguments>
- <debugarguments>
- <osiriond/>
- <osirion/>
- </debugarguments>
- <cwd>
- <osiriond>/home/ingar/projects/osirion/osirion-work/debug/src/</osiriond>
- <osirion>/home/ingar/projects/osirion/osirion-work/debug/src/</osirion>
- </cwd>
- <programargs/>
- <globaldebugarguments/>
- <globalcwd>/home/ingar/projects/osirion/osirion-work/debug</globalcwd>
- <useglobalprogram>false</useglobalprogram>
- <autocompile>false</autocompile>
- <autoinstall>false</autoinstall>
- <autokdesu>false</autokdesu>
- <envvars/>
- </run>
- <configurations>
- <optimized>
- <builddir>optimized</builddir>
- <ccompiler>kdevgccoptions</ccompiler>
- <cxxcompiler>kdevgppoptions</cxxcompiler>
- <f77compiler>kdevg77options</f77compiler>
- <cxxflags>-O2 -g0</cxxflags>
- </optimized>
- <debug>
- <configargs>--enable-debug=full</configargs>
- <builddir>debug</builddir>
- <ccompiler>kdevgccoptions</ccompiler>
- <cxxcompiler>kdevgppoptions</cxxcompiler>
- <f77compiler>kdevg77options</f77compiler>
- <cxxflags>-O0 -g3</cxxflags>
- <envvars/>
- </debug>
- </configurations>
- <configurations>
- <default>
- <ldflags>-lSDL</ldflags>
- </default>
- </configurations>
- <make>
- <envvars>
- <envvar value="1" name="WANT_AUTOCONF_2_5" />
- <envvar value="1" name="WANT_AUTOMAKE_1_6" />
- </envvars>
- <abortonerror>true</abortonerror>
- <runmultiplejobs>false</runmultiplejobs>
- <numberofjobs>2</numberofjobs>
- <dontact>false</dontact>
- <makebin/>
- <prio>0</prio>
- </make>
- </kdevautoproject>
- <kdevdoctreeview>
- <ignoretocs>
- <toc>ada</toc>
- <toc>ada_bugs_gcc</toc>
- <toc>bash</toc>
- <toc>bash_bugs</toc>
- <toc>w3c-dom-level2-html</toc>
- <toc>fortran_bugs_gcc</toc>
- <toc>gnome1</toc>
- <toc>gnustep</toc>
- <toc>gtk</toc>
- <toc>gtk_bugs</toc>
- <toc>haskell</toc>
- <toc>haskell_bugs_ghc</toc>
- <toc>java_bugs_gcc</toc>
- <toc>java_bugs_sun</toc>
- <toc>kde2book</toc>
- <toc>opengl</toc>
- <toc>pascal_bugs_fp</toc>
- <toc>php</toc>
- <toc>php_bugs</toc>
- <toc>perl</toc>
- <toc>perl_bugs</toc>
- <toc>python</toc>
- <toc>python_bugs</toc>
- <toc>qt-kdev3</toc>
- <toc>ruby</toc>
- <toc>ruby_bugs</toc>
- <toc>w3c-svg</toc>
- <toc>sw</toc>
- <toc>w3c-uaag10</toc>
- <toc>wxwidgets_bugs</toc>
- </ignoretocs>
- <ignoreqt_xml>
- <toc>Guide to the Qt Translation Tools</toc>
- <toc>Qt Assistant Manual</toc>
- <toc>Qt Designer Manual</toc>
- <toc>Qt Reference Documentation</toc>
- <toc>qmake User Guide</toc>
- </ignoreqt_xml>
- <ignoredoxygen>
- <toc>KDE Libraries (Doxygen)</toc>
- </ignoredoxygen>
- </kdevdoctreeview>
- <kdevfilecreate>
- <filetypes/>
- <useglobaltypes>
- <type ext="cpp" />
- <type ext="h" />
- </useglobaltypes>
- </kdevfilecreate>
- <kdevdocumentation>
- <projectdoc>
- <docsystem>Doxygen documentatieverzameling</docsystem>
- <docurl>osirion.tag</docurl>
- <usermanualurl/>
- </projectdoc>
- </kdevdocumentation>
- <substmap>
- <APPNAME>osirion</APPNAME>
- <APPNAMELC>osirion</APPNAMELC>
- <APPNAMESC>Osirion</APPNAMESC>
- <APPNAMEUC>OSIRION</APPNAMEUC>
- <AUTHOR>Stijn Buys</AUTHOR>
- <EMAIL>stijn.buys@telenet.be</EMAIL>
- <LICENSE>GPL</LICENSE>
- <LICENSEFILE>COPYING</LICENSEFILE>
- <VERSION>0.0.1</VERSION>
- <YEAR>2007</YEAR>
- <dest>/home/ingar/projects/osirion</dest>
- </substmap>
- <kdevcppsupport>
- <references/>
- <codecompletion>
- <includeGlobalFunctions>true</includeGlobalFunctions>
- <includeTypes>true</includeTypes>
- <includeEnums>true</includeEnums>
- <includeTypedefs>false</includeTypedefs>
- <automaticCodeCompletion>true</automaticCodeCompletion>
- <automaticArgumentsHint>true</automaticArgumentsHint>
- <automaticHeaderCompletion>true</automaticHeaderCompletion>
- <codeCompletionDelay>150</codeCompletionDelay>
- <argumentsHintDelay>150</argumentsHintDelay>
- <headerCompletionDelay>250</headerCompletionDelay>
- <showOnlyAccessibleItems>false</showOnlyAccessibleItems>
- <completionBoxItemOrder>0</completionBoxItemOrder>
- <howEvaluationContextMenu>true</howEvaluationContextMenu>
- <showCommentWithArgumentHint>true</showCommentWithArgumentHint>
- <statusBarTypeEvaluation>false</statusBarTypeEvaluation>
- <namespaceAliases>std=_GLIBCXX_STD;__gnu_cxx=std</namespaceAliases>
- <processPrimaryTypes>true</processPrimaryTypes>
- <processFunctionArguments>false</processFunctionArguments>
- <preProcessAllHeaders>true</preProcessAllHeaders>
- <parseMissingHeadersExperimental>false</parseMissingHeadersExperimental>
- <resolveIncludePathsUsingMakeExperimental>false</resolveIncludePathsUsingMakeExperimental>
- <alwaysParseInBackground>true</alwaysParseInBackground>
- <usePermanentCaching>true</usePermanentCaching>
- <alwaysIncludeNamespaces>false</alwaysIncludeNamespaces>
- <includePaths>.;</includePaths>
- </codecompletion>
- <qt>
- <used>false</used>
- <version>3</version>
- <includestyle>3</includestyle>
- <root>/opt/qt</root>
- <designerintegration>EmbeddedKDevDesigner</designerintegration>
- <qmake>/opt/qt/bin/qmake</qmake>
- <designer>/opt/qt/bin/designer</designer>
- <designerpluginpaths/>
- </qt>
- <creategettersetter>
- <prefixGet/>
- <prefixSet>set</prefixSet>
- <prefixVariable>m_,_</prefixVariable>
- <parameterName>theValue</parameterName>
- <inlineGet>true</inlineGet>
- <inlineSet>true</inlineSet>
- </creategettersetter>
- <splitheadersource>
- <enabled>false</enabled>
- <synchronize>true</synchronize>
- <orientation>Vertical</orientation>
- </splitheadersource>
- </kdevcppsupport>
- <kdevfileview>
- <groups>
- <hidenonprojectfiles>false</hidenonprojectfiles>
- <hidenonlocation>false</hidenonlocation>
- </groups>
- <tree>
- <hidepatterns>*.o,*.lo,CVS</hidepatterns>
- <hidenonprojectfiles>false</hidenonprojectfiles>
- <showvcsfields>false</showvcsfields>
- </tree>
- </kdevfileview>
- <cppsupportpart>
- <filetemplates>
- <interfacesuffix>.h</interfacesuffix>
- <implementationsuffix>.cc</implementationsuffix>
- </filetemplates>
- </cppsupportpart>
- <kdevdebugger>
- <general>
- <gdbpath/>
- <dbgshell/>
- <configGdbScript/>
- <runShellScript/>
- <runGdbScript/>
- <breakonloadinglibs>true</breakonloadinglibs>
- <separatetty>false</separatetty>
- <floatingtoolbar>false</floatingtoolbar>
- <raiseGDBOnStart>false</raiseGDBOnStart>
- </general>
- <display>
- <staticmembers>false</staticmembers>
- <demanglenames>true</demanglenames>
- <outputradix>10</outputradix>
- </display>
- </kdevdebugger>
- <ctagspart>
- <customArguments/>
- <customTagfilePath>/home/ingar/projects/osirion/tags</customTagfilePath>
- <activeTagsFiles/>
- </ctagspart>
-</kdevelop>
diff --git a/src/client/action.h b/src/client/action.h
index 5d56bb9..6cb710b 100644
--- a/src/client/action.h
+++ b/src/client/action.h
@@ -25,6 +25,7 @@ public:
Console,
Left, Right, Up, Down,
RollLeft, RollRight,
+ StrafeUp, StrafeDown,
StrafeLeft, StrafeRight,
ThrustUp, ThrustDown,
Afterburner, Reverse,
diff --git a/src/client/input.cc b/src/client/input.cc
index 16ba048..d483f5d 100644
--- a/src/client/input.cc
+++ b/src/client/input.cc
@@ -52,6 +52,7 @@ float local_pitch = 0.0f;
float local_thrust = 0.0f;
float local_roll = 0.0f;
float local_strafe = 0.0f;
+float local_vstrafe = 0.0f;
float local_afterburner = 0.0f;
// last controlled entity
@@ -375,7 +376,13 @@ void action_press(Key *key)
case Action::StrafeRight:
local_strafe = -1.0f;
break;
-
+ case Action::StrafeUp:
+ local_vstrafe = -1.0f;
+ break;
+ case Action::StrafeDown:
+ local_vstrafe = -1.0f;
+ break;
+
/* -- thruster ------------------------------------ */
case Action::ThrustUp:
local_thrust += thruster_offset;
@@ -456,6 +463,12 @@ void action_release(Key *key)
case Action::StrafeRight:
local_strafe = 0.0f;
break;
+ case Action::StrafeUp:
+ local_vstrafe = 0.0f;
+ break;
+ case Action::StrafeDown:
+ local_vstrafe = 0.0f;
+ break;
/* -- thruster ------------------------------------ */
case Action::ThrustUp:
@@ -483,6 +496,8 @@ void action_release(Key *key)
local_direction = 0.0f;
local_pitch = 0.0f;
local_roll = 0.0f;
+ local_vstrafe = 0.0f;
+ local_strafe = 0.0f;
render::Camera::set_direction(0.0f);
render::Camera::set_pitch(0.0f);
@@ -660,6 +675,7 @@ void reset()
local_direction = 0.0f;
local_pitch = 0.0f;
local_roll = 0.0f;
+ local_vstrafe = 0.0f;
local_strafe = 0.0f;
local_afterburner = 0.0f;
@@ -897,6 +913,7 @@ void frame()
core::localcontrol()->set_pitch(local_pitch / render::State::aspect());
core::localcontrol()->set_roll(local_roll);
core::localcontrol()->set_strafe(local_strafe);
+ core::localcontrol()->set_vstrafe(local_vstrafe);
core::localcontrol()->set_afterburner(local_afterburner);
} else {
@@ -904,6 +921,9 @@ void frame()
local_direction = 0.0f;
local_pitch = 0.0f;
local_roll = 0.0f;
+ local_vstrafe = 0.0f;
+ local_strafe = 0.0f;
+ local_afterburner = 0.0f;
render::Camera::set_direction(0.0f);
render::Camera::set_pitch(0.0f);
diff --git a/src/client/keyboard.cc b/src/client/keyboard.cc
index e617c59..176e310 100644
--- a/src/client/keyboard.cc
+++ b/src/client/keyboard.cc
@@ -54,6 +54,8 @@ Keyboard::Keyboard()
add_action("+strafeleft", Action::StrafeLeft, "strafe left");
add_action("+straferight", Action::StrafeRight, "strafe right");
+ add_action("+strafeup", Action::StrafeUp, "strafe up");
+ add_action("+strafedown", Action::StrafeDown, "strafe down");
add_action("+afterburner", Action::Afterburner, "afterburner");
add_action("+reverse", Action::Reverse, "reverse engine");
@@ -112,11 +114,11 @@ Keyboard::Keyboard()
add_key("`", SDLK_BACKQUOTE, '`', "+console");
add_key("a", SDLK_a, 'a', "+strafeleft");
- add_key("b", SDLK_b, 'b');
+ add_key("b", SDLK_b, 'b', "beam");
add_key("c", SDLK_c, 'c');
add_key("d", SDLK_d, 'd', "+straferight");
add_key("e", SDLK_e, 'e', "+rollright");
- add_key("f", SDLK_f, 'f');
+ add_key("f", SDLK_f, 'f', "+strafedown");
add_key("g", SDLK_g, 'g');
add_key("h", SDLK_h, 'h');
add_key("i", SDLK_i, 'i');
@@ -130,7 +132,7 @@ Keyboard::Keyboard()
add_key("o", SDLK_o, 'o');
add_key("p", SDLK_p, 'p');
add_key("q", SDLK_q, 'q', "+rollleft");
- add_key("r", SDLK_r, 'r');
+ add_key("r", SDLK_r, 'r', "+strafeup");
add_key("s", SDLK_s, 's', "+reverse");
add_key("t", SDLK_t, 't', "ui_chatbar");
add_key("u", SDLK_u, 'u');
@@ -280,16 +282,16 @@ void Keyboard::save_binds()
for (it = begin(); it != end(); it++) {
Key *key = (*it).second;
if (key->bind(Key::None).size()) {
- ofs << "bind " << key->name() << " " << key->bind(Key::None) << std::endl;
+ ofs << "bind " << key->name() << " \"" << key->bind(Key::None) << '\"' << std::endl;
}
if (key->bind(Key::Shift).size()) {
- ofs << "bind shift+" << key->name() << " " << key->bind(Key::Shift) << std::endl;
+ ofs << "bind shift+" << key->name() << " \"" << key->bind(Key::Shift) << '\"' << std::endl;
}
if (key->bind(Key::Ctrl).size()) {
- ofs << "bind ctrl+" << key->name() << " " << key->bind(Key::Ctrl) << std::endl;
+ ofs << "bind ctrl+" << key->name() << " \"" << key->bind(Key::Ctrl) << '\"' << std::endl;
}
if (key->bind(Key::Alt).size()) {
- ofs << "bind alt+" << key->name() << " " << key->bind(Key::Alt) << std::endl;
+ ofs << "bind alt+" << key->name() << " \"" << key->bind(Key::Alt) << '\"' << std::endl;
}
/*
} else {
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index 6085085..7155f86 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -1,17 +1,72 @@
METASOURCES = AUTO
INCLUDES = -I$(top_srcdir)/src
-libcore_la_SOURCES = application.cc commandbuffer.cc core.cc cvar.cc \
- descriptions.cc entity.cc extension.cc func.cc gameconnection.cc gameinterface.cc \
- gameserver.cc info.cc item.cc inventory.cc label.cc loader.cc module.cc netclient.cc \
- netconnection.cc netplayer.cc netserver.cc parser.cc player.cc stats.cc timer.cc zone.cc
+noinst_LTLIBRARIES = libcore.la
+
libcore_la_LDFLAGS = -avoid-version -no-undefined
+
libcore_la_LIBADD = $(top_builddir)/src/model/libmodel.la \
$(top_builddir)/src/filesystem/libfilesystem.la $(top_builddir)/src/math/libmath.la $(top_builddir)/src/sys/libsys.la \
$(top_builddir)/src/auxiliary/libauxiliary.la
-noinst_LTLIBRARIES = libcore.la
-noinst_HEADERS = application.h commandbuffer.h core.h cvar.h entity.h func.h \
- gameconnection.h gameinterface.h gameserver.h label.h message.h module.h net.h netclient.h \
- netconnection.h netserver.h player.h range.h stats.h timer.h parser.h descriptions.h \
- extension.h loader.h info.h item.h inventory.h zone.h
+
+libcore_la_SOURCES = \
+ application.cc \
+ commandbuffer.cc \
+ core.cc \
+ cvar.cc \
+ descriptions.cc \
+ entity.cc \
+ extension.cc \
+ func.cc \
+ gameconnection.cc \
+ gameinterface.cc \
+ gameserver.cc \
+ info.cc \
+ inventory.cc \
+ item.cc \
+ label.cc \
+ loader.cc \
+ module.cc \
+ netclient.cc \
+ netconnection.cc \
+ netplayer.cc \
+ netserver.cc \
+ parser.cc \
+ physics.cc \
+ player.cc \
+ stats.cc \
+ timer.cc \
+ zone.cc
+
+noinst_HEADERS = \
+ application.h \
+ commandbuffer.h \
+ core.h \
+ cvar.h \
+ descriptions.h \
+ entity.h \
+ extension.h \
+ func.h \
+ gameconnection.h \
+ gameinterface.h \
+ gameserver.h \
+ info.h \
+ inventory.h \
+ item.h \
+ label.h \
+ loader.h \
+ message.h \
+ module.h \
+ netclient.h \
+ netconnection.h \
+ net.h \
+ netplayer.h \
+ netserver.h \
+ parser.h \
+ physics.h \
+ player.h \
+ range.h \
+ stats.h \
+ timer.h \
+ zone.h
diff --git a/src/core/entity.cc b/src/core/entity.cc
index ba79424..8a7976f 100644
--- a/src/core/entity.cc
+++ b/src/core/entity.cc
@@ -15,6 +15,8 @@
#include "core/application.h"
#include "core/gameinterface.h"
+#include "BulletCollision/CollisionShapes/btBoxShape.h"
+
namespace core
{
@@ -141,7 +143,12 @@ Entity::Entity() :
entity_flags = 0;
entity_moduletypeid = 0;
+ entity_model = 0;
+ entity_body = 0;
+ entity_collision_shape = 0;
+
entity_speed = 0.0f;
+ entity_mass = 0.0f;
entity_radius = 0.5f;
entity_shape = Diamond;
@@ -150,8 +157,6 @@ Entity::Entity() :
entity_destroyed = false;
entity_dirty = false;
- entity_model = 0;
-
entity_zone = 0;
entity_oldzone = 0;
entity_visible = true;
@@ -175,7 +180,11 @@ Entity::Entity(std::istream & is)
entity_visible = true;
entity_model = 0;
+ entity_body = 0;
+ entity_collision_shape = 0;
+
entity_speed = 0.0f;
+ entity_mass = 0.0f;
entity_created = true;
entity_destroyed = false;
@@ -209,6 +218,12 @@ Entity::~Entity()
if (entity_zone)
entity_zone->remove(this);
+
+ if (entity_collision_shape)
+ delete entity_collision_shape;
+
+ if (entity_body)
+ delete entity_body;
}
void Entity::die()
@@ -229,6 +244,34 @@ void Entity::clear_updates()
}
}
+// reset physics state
+void Entity::reset()
+{
+ if (!entity_body) {
+ if (entity_collision_shape ) {
+ delete entity_collision_shape ;
+ entity_collision_shape = 0;
+ }
+
+ if (model()) {
+ entity_collision_shape = new btBoxShape(to_btVector3(model()->maxbbox()));
+ } else {
+ entity_collision_shape = new btSphereShape(radius());
+ }
+
+ btVector3 inertia(0, 0, 0);
+ entity_body = new btRigidBody(0.0f, 0, entity_collision_shape, inertia);
+ }
+
+ btTransform t;
+ t.setIdentity();
+ t.setOrigin(to_btVector3(location()));
+ t.setBasis(to_btMatrix3x3(axis()));
+
+ entity_body->setWorldTransform(t);
+ set_dirty();
+}
+
void Entity::set_info(Info *info)
{
entity_info = info;
@@ -260,8 +303,9 @@ void Entity::set_zone(Zone *zone)
entity_zone = zone;
entity_dirty = true;
- if (entity_zone)
+ if (entity_zone) {
entity_zone->add(this);
+ }
}
void Entity::set_model(model::Model *model)
@@ -460,16 +504,21 @@ EntityDynamic::EntityDynamic() : Entity()
{
entity_state = Normal;
entity_timer = 0;
+
+ entity_motionstate = new btDefaultMotionState();
}
EntityDynamic::EntityDynamic(std::istream & is) : Entity(is)
{
entity_state = Normal;
entity_timer = 0;
+ entity_motionstate = 0;
}
EntityDynamic::~EntityDynamic()
{
+ if (entity_motionstate)
+ delete entity_motionstate;
}
void EntityDynamic::set_state(int state)
@@ -480,17 +529,66 @@ void EntityDynamic::set_state(int state)
}
}
+// reset physics state
+void EntityDynamic::reset()
+{
+ assert(entity_motionstate);
+
+ // construct physics body if necessary
+ if (!entity_body) {
+ if (entity_collision_shape ) {
+ delete entity_collision_shape ;
+ entity_collision_shape = 0;
+ }
+
+ if (model()) {
+ entity_collision_shape = new btBoxShape(to_btVector3(model()->maxbbox()));
+ } else {
+ entity_collision_shape = new btSphereShape(radius());
+ }
+
+ btVector3 inertia(0, 0, 0);
+ entity_collision_shape->calculateLocalInertia(entity_mass, inertia);
+ entity_body = new btRigidBody(entity_mass, entity_motionstate, entity_collision_shape, inertia);
+ }
+
+ // transfer entity location to motion state
+ btTransform t;
+ t.setIdentity();
+ t.setOrigin(to_btVector3(location()));
+ t.setBasis(to_btMatrix3x3(axis()));
+ entity_body->setWorldTransform(t);
+ if (zone())
+ zone()->physics()->synchronizeSingleMotionState(entity_body);
+
+ set_dirty();
+}
+
void EntityDynamic::frame(float seconds)
{
if ((flags() & Static) == Static)
return;
- if (entity_speed == 0)
- return;
-
- get_location() += axis().forward() * entity_speed * seconds;
-
- set_dirty();
+ // transfer bullet state to entity state
+ // FIXME disable physics when docked
+ if (entity_body && entity_motionstate) {
+
+ // this makes sure an update is sent if speed goes to 0 in the next step
+ if (entity_speed > 0) {
+ set_dirty();
+ }
+
+ btTransform t;
+ entity_motionstate->getWorldTransform(t);
+ get_location().assign(t.getOrigin());
+ get_axis().assign(t.getBasis());
+
+ entity_speed = (float) entity_body->getLinearVelocity().length();
+
+ if (entity_speed > 0) {
+ set_dirty();
+ }
+ }
}
void EntityDynamic::serialize_server_create(std::ostream & os) const
@@ -755,6 +853,17 @@ void EntityControlable::set_strafe(float strafe)
}
}
+void EntityControlable::set_vstrafe(float vstrafe)
+{
+ if ((flags() & Static) == Static)
+ return;
+
+ if (target_vstrafe != vstrafe) {
+ target_vstrafe = vstrafe;
+ set_dirty();
+ }
+}
+
void EntityControlable::set_afterburner(float afterburner)
{
if ((flags() & Static) == Static)
diff --git a/src/core/entity.h b/src/core/entity.h
index 3ba2b0c..2719040 100644
--- a/src/core/entity.h
+++ b/src/core/entity.h
@@ -28,6 +28,7 @@ class EntityControlable;
#include "core/descriptions.h"
#include "core/inventory.h"
#include "core/label.h"
+#include "core/physics.h"
#include "core/player.h"
#include "core/zone.h"
@@ -146,11 +147,30 @@ public:
return entity_radius;
}
- /// current speed of the entity in game units per second
+ /**
+ * @brief current speed of the entity in game units per second
+ * For a normal entity, speed is always 0. Use the EntityDynamic
+ * and EntityControlable classes to create moving entities
+ */
inline const float speed() const {
return entity_speed;
}
+ /// mass of the entity
+ inline const float mass() const {
+ return entity_mass;
+ }
+
+ /// physics body
+ inline btRigidBody *body() {
+ return entity_body;
+ }
+
+ /// collision shape
+ inline btCollisionShape *collision_shape() {
+ return entity_collision_shape;
+ }
+
/// indicates a server-side entity
inline const bool serverside() const {
return entity_serverside;
@@ -234,11 +254,6 @@ public:
*/
virtual void set_zone(Zone *zone);
- /// current speed of the entity in game units per second
- inline void set_speed(const float speed) {
- entity_speed = speed;
- }
-
/// set visibility
inline void set_visible(const bool visible = true) {
entity_visible = visible;
@@ -259,10 +274,11 @@ public:
inline void set_radius(const float radius) {
entity_radius = radius;
}
-
-/* ---- actors ---------------------------------------------------- */
+
+ /* ---- actors ---------------------------------------------------- */
/// called when the entity received a docking request
+ // FIXME move docking functions to game
virtual void dock(Entity *entity);
/// set flags
@@ -275,6 +291,11 @@ public:
entity_flags &= ~flag;
}
+ /**
+ * @brief reset the physics state
+ */
+ virtual void reset();
+
/// add an entity menu
void add_menu(MenuDescription *menu);
@@ -318,7 +339,6 @@ public:
/**
* @brief mutable reference to the secondary color
*/
-
inline math::Color& get_color_second() {
return entity_color_second;
}
@@ -387,7 +407,7 @@ public:
/* entity_ variables can be set by the module */
- /// speed of the entity
+ float entity_mass;
float entity_speed;
Shape entity_shape;
unsigned int entity_moduletypeid;
@@ -398,8 +418,11 @@ public:
/// timestamp when entity data was received from the server
float entity_servertimestamp;
-private:
+protected:
+ btRigidBody *entity_body;
+ btCollisionShape *entity_collision_shape;
+private:
unsigned int entity_id;
unsigned int entity_flags;
@@ -430,7 +453,7 @@ private:
Info* entity_info;
Extension* entity_extension[4];
-
+
static Registry entity_registry;
static size_t entity_nextid;
@@ -466,6 +489,27 @@ public:
return entity_timer;
}
+ inline btMotionState *motionstate() {
+ return entity_motionstate;
+ }
+
+ /*----- mutators -------------------------------------------------- */
+
+ /// mass of the entity
+ inline void set_mass(const float mass) {
+ entity_mass = mass;
+ }
+
+ /// current speed of the entity in game units per second
+ inline void set_speed(const float speed) {
+ entity_speed = speed;
+ }
+
+ /**
+ * @brief reset the physics state
+ */
+ virtual void reset();
+
/*----- serializers ----------------------------------------------- */
/// serialize the entity to a stream
@@ -501,6 +545,9 @@ public:
protected:
float entity_timer;
int entity_state;
+
+ btMotionState *entity_motionstate;
+
};
@@ -577,7 +624,10 @@ public:
void set_roll(float roll);
/// set target strafe
- void set_strafe(float strage);
+ void set_strafe(float strafe);
+
+ /// set target vertical strafe
+ void set_vstrafe(float vstrafe);
/// set afterburner/reverse
void set_afterburner(float afterburner);
@@ -621,6 +671,8 @@ protected:
float target_afterburner;
float target_strafe;
+
+ float target_vstrafe;
float entity_movement;
diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc
index 31c6d42..597de33 100644
--- a/src/core/gameserver.cc
+++ b/src/core/gameserver.cc
@@ -14,6 +14,7 @@
#include "core/gameserver.h"
#include "core/loader.h"
#include "core/parser.h"
+#include "core/physics.h"
#include "core/netserver.h"
#include "filesystem/filesystem.h"
#include "sys/sys.h"
@@ -130,6 +131,8 @@ GameServer::GameServer() : GameInterface()
Parser::init();
+ Physics::init();
+
server_module = Loader::init();
if (!server_module) {
@@ -228,8 +231,10 @@ GameServer::~GameServer()
Func::remove("time");
Func::remove("who");
+ Physics::done();
+
Parser::done();
-
+
server_instance = 0;
}
@@ -490,6 +495,8 @@ void GameServer::frame(unsigned long timestamp)
update_clientstate();
}*/
+ Physics::frame(timestamp);
+
if ((Cvar::sv_dedicated->value() || Cvar::sv_private->value())) {
if (core::Cvar::sv_framerate->value()) {
float f = 1000.0f / core::Cvar::sv_framerate->value();
diff --git a/src/core/physics.cc b/src/core/physics.cc
new file mode 100644
index 0000000..a8577b3
--- /dev/null
+++ b/src/core/physics.cc
@@ -0,0 +1,54 @@
+/*
+ core/physics.cc
+ This file is part of the Osirion project and is distributed under
+ the terms and conditions of the GNU General Public License version 2
+*/
+
+#include "core/physics.h"
+#include "core/zone.h"
+
+namespace core {
+
+btDefaultCollisionConfiguration *Physics::physics_configuration;
+btCollisionDispatcher *Physics::physics_dispatcher;
+btSequentialImpulseConstraintSolver *Physics::physics_solver;
+unsigned long Physics::physics_timestamp;
+
+void Physics::init()
+{
+ con_print << "^BInitializing physics engine..." << std::endl;
+
+ physics_configuration = new btDefaultCollisionConfiguration();
+ physics_dispatcher = new btCollisionDispatcher(physics_configuration);
+ physics_solver = new btSequentialImpulseConstraintSolver;
+
+ physics_timestamp = 0;
+}
+
+void Physics::done()
+{
+ con_print << "^Bshutting down physics engine..." << std::endl;
+ delete physics_solver;
+ delete physics_dispatcher;
+ delete physics_configuration;
+
+ physics_configuration = 0;
+ physics_dispatcher = 0;
+ physics_solver = 0;
+}
+
+void Physics::frame(const unsigned long timestamp)
+{
+ if (!timestamp)
+ return;
+
+ const float seconds = (float) (timestamp - physics_timestamp) / 1000.0f;
+
+ for (core::Zone::Registry::iterator it = core::Zone::registry().begin(); it != core::Zone::registry().end(); it++) {
+ (*it).second->physics()->stepSimulation(seconds);
+ }
+
+ physics_timestamp = timestamp;
+}
+
+} // namespace core \ No newline at end of file
diff --git a/src/core/physics.h b/src/core/physics.h
new file mode 100644
index 0000000..e565403
--- /dev/null
+++ b/src/core/physics.h
@@ -0,0 +1,53 @@
+/*
+ core/physics.h
+ This file is part of the Osirion project and is distributed under
+ the terms and conditions of the GNU General Public License version 2
+*/
+
+#ifndef __INCLUDED_CORE_PHYSICS_H__
+#define __INCLUDED_CORE_PHYSICS_H__
+
+#include "sys/sys.h"
+#include "math/vector3f.h"
+#include "math/axis.h"
+
+#include "btBulletDynamicsCommon.h"
+#include "BulletCollision/CollisionShapes/btTriangleMesh.h"
+#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
+#include "BulletCollision/Gimpact/btGImpactShape.h"
+
+namespace core
+{
+
+class Physics {
+public:
+ static void init();
+
+ static void done();
+
+ static void frame(const unsigned long timestamp);
+
+ inline static btDefaultCollisionConfiguration *configuration() {
+ return physics_configuration;
+ }
+
+ inline static btCollisionDispatcher *dispatcher() {
+ return physics_dispatcher;
+ }
+
+ inline static btSequentialImpulseConstraintSolver *solver() {
+ return physics_solver;
+ }
+
+private:
+ static btDefaultCollisionConfiguration *physics_configuration;
+ static btCollisionDispatcher *physics_dispatcher;
+ static btSequentialImpulseConstraintSolver *physics_solver;
+
+ static unsigned long physics_timestamp;
+};
+
+} // namespace core
+
+#endif // __INCLUDED_CORE_PHYSICS_H__
+
diff --git a/src/core/zone.cc b/src/core/zone.cc
index 3791b93..8a8c056 100644
--- a/src/core/zone.cc
+++ b/src/core/zone.cc
@@ -116,27 +116,46 @@ void Zone ::clear()
}
/* ---- class Zone ------------------------------------------------- */
-Zone::Zone(std::string const & label)
+Zone::Zone(std::string const & label) : Label(label)
{
- zone_id = 0;
- zone_sky.clear();
+ zone_id = 0;
zone_defaultview = 0;
- set_label(label);
+ btVector3 worldAabbMin(-10000, -10000, -10000);
+ btVector3 worldAabbMax(10000, 10000, 10000);
+ const int maxProxies = 1024;
+
+ zone_bullet_cache = new btAxisSweep3(worldAabbMin, worldAabbMax, maxProxies);
+ zone_bullet_world = new btDiscreteDynamicsWorld(Physics::dispatcher(), zone_bullet_cache, Physics::solver(), Physics::configuration());
+
+ // disable gravity
+ zone_bullet_world->setGravity(btVector3(0.0f, 0.0f, 0.0f));
+
}
-Zone::Zone(std::istream & is)
+Zone::Zone(std::istream & is) : Label()
{
zone_id = 0;
+ zone_defaultview = 0;
+ // client side does not setup a bullet physics environment
+ zone_bullet_cache = 0;
+ zone_bullet_world = 0;
receive_server_update(is);
}
Zone::~Zone()
{
for (Content::iterator it = zone_content.begin(); it != zone_content.end(); it++) {
+ (*it) = 0;
}
zone_content.clear();
+
+ if (zone_bullet_world)
+ delete zone_bullet_world;
+
+ if (zone_bullet_cache)
+ delete zone_bullet_cache;
}
void Zone::print()
@@ -153,12 +172,19 @@ void Zone::print()
void Zone::add(Entity *entity)
{
zone_content.push_back(entity);
+ if (physics() && entity->body()) {
+ physics()->addRigidBody(entity->body());
+ entity->reset();
+ }
}
void Zone::remove(Entity *entity)
{
for (Content::iterator it = zone_content.begin(); it != zone_content.end(); it++) {
if ((*it) == entity) {
+ if (physics() && entity->body()) {
+ physics()->removeRigidBody(entity->body());
+ }
zone_content.erase(it);
return;
}
diff --git a/src/core/zone.h b/src/core/zone.h
index 38a9298..f040939 100644
--- a/src/core/zone.h
+++ b/src/core/zone.h
@@ -19,6 +19,7 @@ class Zone;
}
#include "core/entity.h"
+#include "core/physics.h"
namespace core
{
@@ -140,6 +141,11 @@ public:
/// remove an entity from this zone
void remove(Entity *entity);
+ /// physics world for this zone
+ inline btDiscreteDynamicsWorld *physics() {
+ return zone_bullet_world;
+ }
+
private:
unsigned int zone_id;
@@ -149,6 +155,9 @@ private:
static Registry zone_registry;
Entity *zone_defaultview;
+
+ btAxisSweep3 *zone_bullet_cache;
+ btDiscreteDynamicsWorld *zone_bullet_world;
};
}
diff --git a/src/game/base/cargo.cc b/src/game/base/cargo.cc
index 1a933e8..daf4ac2 100644
--- a/src/game/base/cargo.cc
+++ b/src/game/base/cargo.cc
@@ -374,6 +374,7 @@ void Cargo::eject(core::EntityControlable *ejector, const int amount)
ejector->owner()->send(msgstr.str());
ejector->owner()->sound("game/eject");
}
+ pod->reset();
}
void Cargo::list()
diff --git a/src/game/base/cargopod.cc b/src/game/base/cargopod.cc
index a3b44bf..b6d2123 100644
--- a/src/game/base/cargopod.cc
+++ b/src/game/base/cargopod.cc
@@ -18,6 +18,11 @@ CargoPod::CargoPod() : EntityDynamic()
// FIXME hardcoded modelname
set_modelname("maps/cargo/pod");
+
+ set_mass(radius());
+
+ // activate physics
+ reset();
}
CargoPod::~CargoPod()
diff --git a/src/game/base/game.cc b/src/game/base/game.cc
index 3c84d58..c0ef4ce 100644
--- a/src/game/base/game.cc
+++ b/src/game/base/game.cc
@@ -604,7 +604,7 @@ void Game::func_launch(core::Player *player, std::string const &args)
ship->get_axis().assign(dock->axis());
ship->set_state(core::Entity::Normal);
- ship->set_state(core::Entity::Jump);
+ ship->reset();
player->set_view(0);
player->send("^BLaunching from " + dock->name());
@@ -671,8 +671,7 @@ void Game::func_goto(core::Player *player, const std::string &args)
ship->get_axis().assign(dock->axis());
ship->get_axis().change_direction(180.0f);
ship->set_state(core::Entity::Normal);
-
- ship->set_state(core::Entity::Jump);
+ ship->reset();
player->set_view(0);
player->send("Going to " + dock->name());
diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc
index a588122..d7d6b59 100644
--- a/src/game/base/ship.cc
+++ b/src/game/base/ship.cc
@@ -76,6 +76,8 @@ Ship::Ship(core::Player *owner, ShipModel *shipmodel) : core::EntityControlable(
set_flag(core::Entity::Dockable);
}
+
+ set_mass(radius());
reset();
}
@@ -89,7 +91,10 @@ void Ship::reset()
current_target_pitch = 0.0f;;
current_target_roll = 0.0f;
current_target_strafe = 0.0f;
+ current_target_vstrafe = 0.0f;
current_target_afterburner = 0.0f;
+
+ EntityControlable::reset();
}
// this is called if another shuo wants to dock this ship
@@ -617,6 +622,16 @@ void Ship::frame(float seconds)
if ((entity_movement > 0) || (entity_speed > 0)) {
set_dirty();
}
+
+ // transfer entity location to motion state
+ btTransform t;
+ t.setIdentity();
+ t.setOrigin(math::to_btVector3(location()));
+ t.setBasis(math::to_btMatrix3x3(axis()));
+ entity_body->setWorldTransform(t);
+
+ if (zone())
+ zone()->physics()->synchronizeSingleMotionState(entity_body);
}
} // namespace game
diff --git a/src/game/base/ship.h b/src/game/base/ship.h
index 1114df2..1f4f743 100644
--- a/src/game/base/ship.h
+++ b/src/game/base/ship.h
@@ -40,7 +40,7 @@ public:
void initiate_jump(JumpPoint *depart);
/// void reset drive controls
- void reset();
+ virtual void reset();
/// explode the ship
void explode();
@@ -62,6 +62,7 @@ private:
float current_target_pitch;
float current_target_roll;
float current_target_strafe;
+ float current_target_vstrafe;
float current_target_afterburner;
bool ship_jumpdrive;
diff --git a/src/math/axis.cc b/src/math/axis.cc
index 8273469..7281047 100644
--- a/src/math/axis.cc
+++ b/src/math/axis.cc
@@ -35,6 +35,15 @@ void Axis::assign(const Axis & other)
}
}
+void Axis::assign(const btMatrix3x3 & other)
+{
+ for (size_t i = 0; i < 3; i++) {
+ for (size_t j = 0; j < 3; j++) {
+ axis_vector[i][j] = other[i][j];
+ }
+ }
+}
+
Axis & Axis::operator=(const Axis & other)
{
assign(other);
diff --git a/src/math/axis.h b/src/math/axis.h
index c22568c..d3a5ec6 100644
--- a/src/math/axis.h
+++ b/src/math/axis.h
@@ -10,7 +10,7 @@
#include <iostream>
#include "math/vector3f.h"
-
+#include "LinearMath/btMatrix3x3.h"
namespace math
{
@@ -24,6 +24,8 @@ public:
void clear();
void assign(const Axis & other);
+
+ void assign(const btMatrix3x3 & other);
/// global coordinates of the X-axis in the local coordinates system
inline const Vector3f & forward() const {
@@ -86,6 +88,14 @@ private:
Vector3f axis_vector[3];
};
+/// helper function to conver math::Axis to btMatrix3x3
+inline btMatrix3x3 to_btMatrix3x3(const math::Axis &a)
+{
+ return btMatrix3x3(a[0][0], a[0][1], a[0][2],
+ a[1][0], a[1][1], a[1][2],
+ a[2][0], a[2][1], a[2][2]);
+}
+
/// write an axis to a std::ostream
std::ostream &operator<<(std::ostream & os, const Axis & axis);
diff --git a/src/math/vector3f.cc b/src/math/vector3f.cc
index 4594665..421d84e 100644
--- a/src/math/vector3f.cc
+++ b/src/math/vector3f.cc
@@ -48,6 +48,13 @@ void Vector3f::assign(const Vector3f & other)
memcpy(coord, other.coord, sizeof(coord));
}
+void Vector3f::assign(const btVector3 & other)
+{
+ for (size_t i = 0; i < 3; i++) {
+ coord[i] = other[i];
+ }
+}
+
Vector3f & Vector3f::operator=(const Vector3f & other)
{
assign(other);
diff --git a/src/math/vector3f.h b/src/math/vector3f.h
index 09e6e84..a7437aa 100644
--- a/src/math/vector3f.h
+++ b/src/math/vector3f.h
@@ -10,6 +10,8 @@
#include <iostream>
#include "math/vector3f.h"
+#include "LinearMath/btVector3.h"
+
namespace math
{
@@ -49,6 +51,9 @@ public:
/// assignment
void assign(const Vector3f & other);
+
+ /// assign bullet btVector3 value
+ void assign(const btVector3 & other);
/// assignment operator
Vector3f& operator=(const Vector3f &other);
@@ -214,6 +219,12 @@ float distance(const Vector3f& first, const Vector3f& second);
/// distance between two vectors squared
float distancesquared(const Vector3f& first, const Vector3f& second);
+/// helper function to convert Vector3f to btVector3
+inline btVector3 to_btVector3(const math::Vector3f & v)
+{
+ return btVector3(v[0], v[1], v[2]);
+}
+
} // namespace math
#endif // __INCLUDED_MATH_VECTOR3F_H__
diff --git a/src/render/Makefile.am b/src/render/Makefile.am
index 4636250..4389805 100644
--- a/src/render/Makefile.am
+++ b/src/render/Makefile.am
@@ -8,10 +8,43 @@ noinst_LTLIBRARIES = librender.la
endif
librender_la_LDFLAGS = -avoid-version -no-undefined @GL_LIBS@
+
librender_la_LIBADD = $(top_builddir)/src/math/libmath.la
-librender_la_SOURCES = camera.cc draw.cc dust.cc gl.cc image.cc jpgfile.cc \
- particles.cc pngfile.cc render.cc renderext.cc screenshot.cc sky.cc \
- state.cc text.cc textures.cc tgafile.cc
-noinst_HEADERS = camera.h draw.h dust.h gl.h image.h jpgfile.h \
- particles.h pngfile.h render.h renderext.h screenshot.h sky.h \
- state.h text.h textures.h tgafile.h
+
+librender_la_SOURCES = \
+ camera.cc \
+ debugdrawer.cc \
+ draw.cc \
+ dust.cc \
+ gl.cc \
+ image.cc \
+ jpgfile.cc \
+ particles.cc \
+ pngfile.cc \
+ render.cc \
+ renderext.cc \
+ screenshot.cc \
+ sky.cc \
+ state.cc \
+ text.cc \
+ textures.cc \
+ tgafile.cc
+
+noinst_HEADERS = \
+ camera.h \
+ debugdrawer.h \
+ draw.h \
+ dust.h \
+ gl.h \
+ image.h \
+ jpgfile.h \
+ particles.h \
+ pngfile.h \
+ render.h \
+ renderext.h \
+ screenshot.h \
+ sky.h \
+ state.h \
+ text.h \
+ textures.h \
+ tgafile.h
diff --git a/src/render/debugdrawer.cc b/src/render/debugdrawer.cc
new file mode 100644
index 0000000..03d5746
--- /dev/null
+++ b/src/render/debugdrawer.cc
@@ -0,0 +1,127 @@
+/*
+ render/debugdrawer.h
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#include "render/debugdrawer.h"
+#include "render/gl.h"
+#include "sys/sys.h"
+
+namespace render {
+
+DebugDrawer bullet_debugdrawer;
+
+DebugDrawer::DebugDrawer()
+{
+ debugdrawer_debugmode = btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawConstraints;
+}
+
+DebugDrawer::~DebugDrawer()
+{
+}
+
+void DebugDrawer::drawLine(const btVector3& from, const btVector3& to,const btVector3& color)
+{
+ gl::vertex(from[0], from[1], from[2]);
+ gl::vertex(to[0], to[1], to[2]);
+}
+
+void DebugDrawer::drawLine(const btVector3& from, const btVector3 & to, const btVector3 & fromColor, const btVector3 & toColor)
+{
+ gl::vertex(from[0], from[1], from[2]);
+ gl::vertex(to[0], to[1], to[2]);
+}
+
+void DebugDrawer::drawContactPoint(const btVector3 & point, const btVector3 & normal, btScalar distance , int lifetime, const btVector3 & color)
+{
+
+}
+
+void DebugDrawer::drawSphere(btScalar radius, const btTransform & transform, const btVector3 & color)
+{
+ btVector3 start = transform.getOrigin();
+
+ const btVector3 xoffs = transform.getBasis() * btVector3(radius,0,0);
+ const btVector3 yoffs = transform.getBasis() * btVector3(0,radius,0);
+ const btVector3 zoffs = transform.getBasis() * btVector3(0,0,radius);
+
+ // XY
+ drawLine(start-xoffs, start+yoffs, color);
+ drawLine(start+yoffs, start+xoffs, color);
+ drawLine(start+xoffs, start-yoffs, color);
+ drawLine(start-yoffs, start-xoffs, color);
+
+ // XZ
+ drawLine(start-xoffs, start+zoffs, color);
+ drawLine(start+zoffs, start+xoffs, color);
+ drawLine(start+xoffs, start-zoffs, color);
+ drawLine(start-zoffs, start-xoffs, color);
+
+ // YZ
+ drawLine(start-yoffs, start+zoffs, color);
+ drawLine(start+zoffs, start+yoffs, color);
+ drawLine(start+yoffs, start-zoffs, color);
+ drawLine(start-zoffs, start-yoffs, color);
+}
+
+void DebugDrawer::drawSphere(const btVector3 & p, btScalar radius, const btVector3 & color)
+{
+ btTransform tr;
+ tr.setIdentity();
+ tr.setOrigin(p);
+ drawSphere(radius,tr,color);
+}
+
+void DebugDrawer::drawBox(const btVector3 & bbMin, const btVector3 & bbMax, const btVector3 & color)
+{
+ drawLine(btVector3(bbMin[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMin[1], bbMin[2]), color);
+ drawLine(btVector3(bbMax[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMax[1], bbMin[2]), color);
+ drawLine(btVector3(bbMax[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMax[1], bbMin[2]), color);
+ drawLine(btVector3(bbMin[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMin[1], bbMin[2]), color);
+ drawLine(btVector3(bbMin[0], bbMin[1], bbMin[2]), btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
+ drawLine(btVector3(bbMax[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
+ drawLine(btVector3(bbMax[0], bbMax[1], bbMin[2]), btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
+ drawLine(btVector3(bbMin[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
+ drawLine(btVector3(bbMin[0], bbMin[1], bbMax[2]), btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
+ drawLine(btVector3(bbMax[0], bbMin[1], bbMax[2]), btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
+ drawLine(btVector3(bbMax[0], bbMax[1], bbMax[2]), btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
+ drawLine(btVector3(bbMin[0], bbMax[1], bbMax[2]), btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
+}
+
+void DebugDrawer::drawBox(const btVector3 & bbMin, const btVector3 & bbMax, const btTransform & trans, const btVector3 & color)
+{
+ drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), color);
+ drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), color);
+ drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), color);
+ drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), color);
+ drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
+ drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
+ drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
+ drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
+ drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
+ drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
+ drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
+ drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
+}
+void DebugDrawer::reportErrorWarning(const char *warningString)
+{
+ con_warn << warningString << std::endl;
+}
+
+void DebugDrawer::draw3dText(const btVector3 &location, const char *textString)
+{
+}
+
+void DebugDrawer::setDebugMode(int debugMode)
+{
+ debugdrawer_debugmode = debugMode;
+}
+
+int DebugDrawer::getDebugMode() const
+{
+ return debugdrawer_debugmode;
+}
+
+
+} // namespace render \ No newline at end of file
diff --git a/src/render/debugdrawer.h b/src/render/debugdrawer.h
new file mode 100644
index 0000000..a23cecc
--- /dev/null
+++ b/src/render/debugdrawer.h
@@ -0,0 +1,54 @@
+/*
+ render/debugdrawer.h
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#ifndef __INCLUDED_RENDER_DEBUGDRAWER_H__
+#define __INCLUDED_RENDER_DEBUGDRAWER_H__
+
+#include "LinearMath/btIDebugDraw.h"
+
+namespace render {
+
+/**
+ * @brief implementation for the bullet debug draw interface
+ * This class implements the bullet btIDebugDraw interface to
+ * render the world as seen by the bullet physics library
+ */
+class DebugDrawer: public btIDebugDraw
+{
+public:
+ DebugDrawer();
+ virtual ~DebugDrawer();
+
+ virtual void drawLine(const btVector3 & from, const btVector3 & to, const btVector3 & color);
+
+ virtual void drawLine(const btVector3& from, const btVector3 & to, const btVector3 & fromColor, const btVector3 & toColor);
+
+ virtual void drawContactPoint(const btVector3 & point, const btVector3 & normal, btScalar distance, int lifetime, const btVector3 & color);
+
+ virtual void drawSphere(btScalar radius, const btTransform & transform, const btVector3 & color);
+
+ virtual void drawSphere(const btVector3 & p, btScalar radius, const btVector3 & color);
+
+ virtual void drawBox(const btVector3 & bbMin, const btVector3 & bbMax, const btVector3 & color);
+
+ virtual void drawBox(const btVector3 & bbMin, const btVector3 & bbMax, const btTransform & trans, const btVector3 & color);
+
+ virtual void reportErrorWarning(const char *warningString);
+
+ virtual void draw3dText(const btVector3 &location, const char *textString);
+
+ virtual void setDebugMode(int debugMode);
+
+ virtual int getDebugMode() const;
+
+private:
+ int debugdrawer_debugmode;
+};
+
+extern DebugDrawer bullet_debugdrawer;
+} // namespace render
+
+#endif // __INCLUDED_RENDER_DEBUGDRAWER_H__
diff --git a/src/render/draw.cc b/src/render/draw.cc
index d54387a..656653b 100644
--- a/src/render/draw.cc
+++ b/src/render/draw.cc
@@ -15,6 +15,7 @@
#include "model/model.h"
#include "render/render.h"
#include "render/textures.h"
+#include "render/debugdrawer.h"
#include "render/draw.h"
#include "render/dust.h"
#include "render/gl.h"
@@ -1206,12 +1207,17 @@ void draw(float seconds)
glPolygonMode(GL_FRONT, GL_FILL);
draw_pass_sky(); // draw the skybox
+
+ gl::depthmask(GL_TRUE); // enable writing to the depth buffer
+ gl::enable(GL_DEPTH_TEST);
+ gl::enable(GL_CULL_FACE); // enable culling
+ gl::enable(GL_COLOR_MATERIAL); // enable color tracking
// enable wireframe mode if requested
if (r_wireframe && r_wireframe->value()) {
glPolygonMode(GL_FRONT, GL_LINE);
}
-
+
// set vertex array pointers
glInterleavedArrays(GL_T2F_N3F_V3F, 0, core::game()->vertexarray()->ptr());
@@ -1220,12 +1226,6 @@ void draw(float seconds)
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
- gl::depthmask(GL_TRUE); // enable writing to the depth buffer
- gl::enable(GL_DEPTH_TEST);
-
- gl::enable(GL_CULL_FACE); // enable culling
- gl::enable(GL_COLOR_MATERIAL); // enable color tracking
-
if (r_normalize && r_normalize->value()) {
// enable full normalization
gl::enable(GL_NORMALIZE);
@@ -1248,7 +1248,7 @@ void draw(float seconds)
// disable full normalization
gl::disable(GL_NORMALIZE);
} else {
- // disable resaling of normals
+ // disable rescaling of normals
gl::disable(GL_RESCALE_NORMAL);
}
@@ -1294,12 +1294,27 @@ void draw(float seconds)
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
+ gl::depthmask(GL_TRUE); // enable depth buffer writing
+ gl::disable(GL_DEPTH_TEST); // disable depth buffer testing
+
+ // draw physics
+ if (r_physics && r_physics->value()) {
+ if (zone->physics()) {
+ if (!zone->physics()->getDebugDrawer())
+ zone->physics()->setDebugDrawer(&bullet_debugdrawer);
+
+ // draw physics bodies in red
+ gl::color(1.0f, 0.0f, 0.0f, 1.0f);
+ gl::begin(gl::Lines);
+ zone->physics()->debugDrawWorld();
+ gl::end();
+ }
+ }
+
gl::disable(GL_COLOR_MATERIAL); // disable color tracking
gl::disable(GL_CULL_FACE); // disable culling
- gl::depthmask(GL_TRUE); // enable depth buffer writing
- gl::disable(GL_DEPTH_TEST); // disable depth buffer testing
+
// GL_BLEND must be enabled for the GUI
}
diff --git a/src/render/render.cc b/src/render/render.cc
index acc9c86..398cb6b 100644
--- a/src/render/render.cc
+++ b/src/render/render.cc
@@ -36,7 +36,7 @@ core::Cvar *r_radius = 0;
core::Cvar *r_sky = 0;
core::Cvar *r_wireframe = 0;
core::Cvar *r_mipmap = 0;
-core::Cvar *r_collision = 0;
+core::Cvar *r_physics = 0;
core::Cvar *r_normals = 0;
core::Cvar *r_normalize = 0;
@@ -106,10 +106,10 @@ void init(int width, int height)
r_specular = core::Cvar::get("r_specular", "0.2", core::Cvar::Archive);
r_specular->set_info("[float] specular light intensity");
- /*
- r_collision = core::Cvar::get("r_collision", "1", core::Cvar::Archive);
- r_collision->set_info("[bool] render collision (server side only)");
- */
+
+ r_physics = core::Cvar::get("r_physics", "0", core::Cvar::Archive);
+ r_physics->set_info("[bool] render physics (local game only)");
+
Screenshot::screenshotformat = core::Cvar::get("screenshotformat", "jpg", core::Cvar::Archive);
Screenshot::screenshotformat->set_info("[string] screenshot format: jpg png tga");
diff --git a/src/render/render.h b/src/render/render.h
index 190cdb5..5e5f3d1 100644
--- a/src/render/render.h
+++ b/src/render/render.h
@@ -56,8 +56,8 @@ extern core::Cvar *r_sky;
extern core::Cvar *r_wireframe;
/// render vertex normals
extern core::Cvar *r_normals;
-/// render collision
-extern core::Cvar *r_collision;
+/// render physics
+extern core::Cvar *r_physics;
/// use hardware generated mipmaps (requires OpenGL 1.4, does not work on all cards)
extern core::Cvar *r_mipmap;
/// use GL_NORMALIZE instead of GL_RESCALE_NORMAL
diff --git a/src/sys/sys.h b/src/sys/sys.h
index eb9d099..3d94bcb 100644
--- a/src/sys/sys.h
+++ b/src/sys/sys.h
@@ -9,11 +9,6 @@
#include "config.h"
-// disable bullet for now
-#ifdef HAVE_BULLET
-#undef HAVE_BULLET
-#endif
-
#include <string>
/// maximum line size throught the game