1) Improved rockets and sparks for bullet physics
Parameters for rockets etc. can for now be set in data/*.projectile 2) Fixed bugs causing rockets not to explode (and potentialy start rotating) 3) Added (somewhat temporarily) some cheats to get rockets, homing missiles and sparks as F1/2/3 4) Fixed several memory leaks. 5) Fixed (very rare) occurring crash when deleting phsyics. 6) Started to remove non-bullet physics code 7) Bullet physics is now the default, and it can not be disabled anymore!! Important note: From this revision on, non-bullet physics is NOT supported anymore, and will (most likely) not compile. For now a -DBULLET is still necessary (it is added as default), but the code will be cleaned up in the near future. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1325 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
12cee75a0f
commit
7ed846ca3e
@ -1,16 +1,17 @@
|
|||||||
Preliminary support for the bullet physics engine has been
|
Beginning with revision r1325 bullet physics is being used
|
||||||
added, and bullet itself is part of the STK sources by noq.
|
in SuperTuxKart. A copy of bullet is included in
|
||||||
To enable it, use the '--enable-bullet' option in configure,
|
the sources and the STK build environment, so it's
|
||||||
that should be all (though up to now only linux and cygwin
|
not necessary to install your own version.
|
||||||
have been tested with the new, integrated bullet version).
|
|
||||||
|
|
||||||
|
Even though we officiall switched to bullet physics,
|
||||||
|
not all 'old' features of STK are fully supported yet.
|
||||||
For now mainly the race track works as expected, all tracks
|
For now mainly the race track works as expected, all tracks
|
||||||
can be played (though the performance in some tracks is somewhat
|
can be played. Most important bugs:
|
||||||
bad at the moment). Most important bugs:
|
|
||||||
- not all collectable work
|
- not all collectable work
|
||||||
(zippers don't work, homing missiles don't go to the target,
|
(zippers don't do much at the moment, rockets and sparks mostly
|
||||||
sparks won't fly as expected either), but collision with
|
work, but are sometimes too high)
|
||||||
karts work.
|
- karts are not automatically rescued when touching
|
||||||
|
water or lava
|
||||||
- no proper friction handling, so no skidding
|
- no proper friction handling, so no skidding
|
||||||
(though skidding potentially works - if the friction is
|
(though skidding potentially works - if the friction is
|
||||||
set correctly).
|
set correctly).
|
||||||
@ -19,8 +20,6 @@ bad at the moment). Most important bugs:
|
|||||||
- rescuing an upside-down kart will return the kart to the middle
|
- rescuing an upside-down kart will return the kart to the middle
|
||||||
of the track (waypoints) - the kart should be returned to where
|
of the track (waypoints) - the kart should be returned to where
|
||||||
it ended, just with a proper orientation.
|
it ended, just with a proper orientation.
|
||||||
- if a kart is upside down, it will actually hang under the
|
|
||||||
track.
|
|
||||||
- tuxtrack is using real rigid bodies for the roadcone and roadblock,
|
- tuxtrack is using real rigid bodies for the roadcone and roadblock,
|
||||||
so they are pushed around when hit by a kart. Currently, the
|
so they are pushed around when hit by a kart. Currently, the
|
||||||
start orientation is not used, so the heading of the objects
|
start orientation is not used, so the heading of the objects
|
||||||
|
@ -32,11 +32,12 @@ Comments:
|
|||||||
|
|
||||||
Visual C++ Express
|
Visual C++ Express
|
||||||
==================
|
==================
|
||||||
|
There are now project files included for building SuperTuxKart with
|
||||||
|
Visual C++ - have a look at the src/ide/vc8 folder.
|
||||||
Since version r793 SuperTuxKart compiles with Visual C++ Express,
|
Since version r793 SuperTuxKart compiles with Visual C++ Express,
|
||||||
version 8.0, since rev 1267 Visual C++ project files are included.
|
version 8.0, since rev 1267 Visual C++ project files are included.
|
||||||
The main project file is .../src/ide/vc8/supertuxkart.vcproj,
|
The main project file is .../src/ide/vc8/supertuxkart.vcproj,
|
||||||
and it include a sub project for the bullet library. More details
|
and it includes a sub project for the bullet library. More details
|
||||||
can be found in .../src/ide/vc8/README.
|
can be found in .../src/ide/vc8/README.
|
||||||
|
|
||||||
You still have to install all dependencies, and:
|
You still have to install all dependencies, and:
|
||||||
|
34
configure.ac
34
configure.ac
@ -347,34 +347,20 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
|
|||||||
CXXFLAGS="$ORIGCXXFLAGS"
|
CXXFLAGS="$ORIGCXXFLAGS"
|
||||||
AC_SUBST(NOREGMOVE)
|
AC_SUBST(NOREGMOVE)
|
||||||
|
|
||||||
dnl =======================================
|
dnl ==============
|
||||||
dnl Bullet physics - currently experimental
|
dnl Bullet physics
|
||||||
dnl =======================================
|
dnl ==============
|
||||||
dnl Check for bullet physics. Currently, this is optional and needs
|
AC_DEFINE([BULLET], [], [Use the bullet physics engine])
|
||||||
dnl a '--enable-bullet' during configure to be used.
|
CXXFLAGS="$CXXFLAGS -Ibullet/src"
|
||||||
AC_MSG_CHECKING(for bullet physics)
|
AC_CONFIG_FILES([ \
|
||||||
AC_ARG_ENABLE(bullet,
|
|
||||||
AC_HELP_STRING([--enable-bullet], [enable bullet physics]),
|
|
||||||
[enable_bullet="$enableval"],
|
|
||||||
[enable_bullet="no"])
|
|
||||||
if test "x${enable_bullet}" != "xno"; then
|
|
||||||
AC_DEFINE([BULLET], [], [Use the bullet physics engine])
|
|
||||||
AC_MSG_RESULT([enabled])
|
|
||||||
CXXFLAGS="$CXXFLAGS -Ibullet/src"
|
|
||||||
AC_CONFIG_FILES([ \
|
|
||||||
src/bullet/Makefile \
|
src/bullet/Makefile \
|
||||||
src/bullet/src/Makefile \
|
src/bullet/src/Makefile \
|
||||||
src/bullet/Demos/OpenGL/Makefile
|
src/bullet/Demos/OpenGL/Makefile
|
||||||
])
|
])
|
||||||
SUMMARY="$SUMMARY\nUsing bullet physics."
|
SUMMARY="$SUMMARY\nUsing bullet physics."
|
||||||
BULLETTREE="src/bullet"
|
BULLETTREE="src/bullet"
|
||||||
bullet_LIBS="-L bullet/Demos/OpenGL -lbulletopenglsupport -L bullet/src -lbulletdynamics -lbulletcollision -lbulletmath -lglut"
|
bullet_LIBS="-L bullet/Demos/OpenGL -lbulletopenglsupport -L bullet/src -lbulletdynamics -lbulletcollision -lbulletmath -lglut"
|
||||||
else
|
|
||||||
AC_MSG_RESULT([disabled])
|
|
||||||
BULLETTREE=""
|
|
||||||
bullet_LIBS=""
|
|
||||||
|
|
||||||
fi
|
|
||||||
AC_SUBST(BULLETTREE)
|
AC_SUBST(BULLETTREE)
|
||||||
|
|
||||||
dnl ================
|
dnl ================
|
||||||
|
@ -4,7 +4,12 @@
|
|||||||
(name "homing")
|
(name "homing")
|
||||||
(model "homingmissile.ac")
|
(model "homingmissile.ac")
|
||||||
(icon "homingmissile.rgb")
|
(icon "homingmissile.rgb")
|
||||||
(speed 25.0)
|
(speed 35.0)
|
||||||
|
(min-height 0.2)
|
||||||
|
(max-height 1.0)
|
||||||
|
(max-distance 20.0) ;; maximum distance at which a kart is still followed
|
||||||
|
(max-turn-angle 5.0) ;; maximum turn angle when following a kart
|
||||||
|
(force-updown 25.0) ;; force raising/lowering the homing missile if it's too low/high
|
||||||
)
|
)
|
||||||
|
|
||||||
;; EOF ;;
|
;; EOF ;;
|
||||||
|
@ -5,6 +5,9 @@
|
|||||||
(model "missile.ac")
|
(model "missile.ac")
|
||||||
(icon "missile.rgb")
|
(icon "missile.rgb")
|
||||||
(speed 50.0)
|
(speed 50.0)
|
||||||
|
(min-height 0.2)
|
||||||
|
(max-height 1.0)
|
||||||
|
(force-updown 15.0)
|
||||||
)
|
)
|
||||||
|
|
||||||
;; EOF ;;
|
;; EOF ;;
|
||||||
|
@ -5,6 +5,16 @@
|
|||||||
(model "spark.ac")
|
(model "spark.ac")
|
||||||
(icon "spark.rgb")
|
(icon "spark.rgb")
|
||||||
(speed 5.0)
|
(speed 5.0)
|
||||||
|
(min-height 0.2) ; height above terrain below which a spark is
|
||||||
|
; started to be pulled up
|
||||||
|
(max-height 3.0) ; height above terrain at which a spark is
|
||||||
|
; started to be pulled back to ground
|
||||||
|
(force-updown 20.0) ; force pushing the spark down
|
||||||
|
; when it's too high above ground
|
||||||
|
(force-to-target 20) ; force with which a spark flies towards
|
||||||
|
; the nearest kart
|
||||||
|
(max-distance 10) ; maximum distance the spark can be away
|
||||||
|
; from a kart when accelerating towards it
|
||||||
)
|
)
|
||||||
|
|
||||||
;; EOF ;;
|
;; EOF ;;
|
||||||
|
@ -26,7 +26,7 @@ libstatic_ssg_a_CXXFLAGS = @NOREGMOVE@
|
|||||||
AM_CPPFLAGS=-DSUPERTUXKART_DATADIR="\"$(datadir)/games/@PACKAGE@/\""
|
AM_CPPFLAGS=-DSUPERTUXKART_DATADIR="\"$(datadir)/games/@PACKAGE@/\""
|
||||||
|
|
||||||
supertuxkart_SOURCES = main.cpp \
|
supertuxkart_SOURCES = main.cpp \
|
||||||
actionmap.cpp actionmap.hpp \
|
actionmap.cpp actionmap.hpp \
|
||||||
material.cpp material.hpp \
|
material.cpp material.hpp \
|
||||||
material_manager.cpp material_manager.hpp \
|
material_manager.cpp material_manager.hpp \
|
||||||
attachment.cpp attachment.hpp \
|
attachment.cpp attachment.hpp \
|
||||||
@ -38,8 +38,7 @@ supertuxkart_SOURCES = main.cpp \
|
|||||||
music_mikmod.cpp music_mikmod.hpp \
|
music_mikmod.cpp music_mikmod.hpp \
|
||||||
music_ogg.cpp music_ogg.hpp \
|
music_ogg.cpp music_ogg.hpp \
|
||||||
sfx_openal.cpp sfx_openal.hpp \
|
sfx_openal.cpp sfx_openal.hpp \
|
||||||
utils.cpp utils.hpp \
|
input.hpp \
|
||||||
input.hpp \
|
|
||||||
isect.cpp isect.hpp \
|
isect.cpp isect.hpp \
|
||||||
track.cpp track.hpp \
|
track.cpp track.hpp \
|
||||||
herring.cpp herring.hpp \
|
herring.cpp herring.hpp \
|
||||||
@ -68,8 +67,8 @@ supertuxkart_SOURCES = main.cpp \
|
|||||||
shadow.cpp shadow.hpp \
|
shadow.cpp shadow.hpp \
|
||||||
particle_system.cpp particle_system.hpp \
|
particle_system.cpp particle_system.hpp \
|
||||||
game_manager.cpp game_manager.hpp \
|
game_manager.cpp game_manager.hpp \
|
||||||
widget_manager.cpp widget_manager.hpp \
|
widget_manager.cpp widget_manager.hpp \
|
||||||
widget.cpp widget.hpp \
|
widget.cpp widget.hpp \
|
||||||
camera.cpp camera.hpp \
|
camera.cpp camera.hpp \
|
||||||
sdldrv.cpp sdldrv.hpp \
|
sdldrv.cpp sdldrv.hpp \
|
||||||
moveable.cpp moveable.hpp \
|
moveable.cpp moveable.hpp \
|
||||||
@ -77,14 +76,17 @@ supertuxkart_SOURCES = main.cpp \
|
|||||||
kart.cpp kart.hpp \
|
kart.cpp kart.hpp \
|
||||||
auto_kart.hpp \
|
auto_kart.hpp \
|
||||||
player_kart.cpp player_kart.hpp \
|
player_kart.cpp player_kart.hpp \
|
||||||
projectile.cpp projectile.hpp \
|
flyable.cpp flyable.hpp \
|
||||||
|
missile.cpp missile.hpp \
|
||||||
|
homing.cpp homing.hpp \
|
||||||
|
spark.cpp spark.hpp \
|
||||||
history.cpp history.hpp \
|
history.cpp history.hpp \
|
||||||
scene.hpp scene.cpp \
|
scene.hpp scene.cpp \
|
||||||
race_setup.hpp no_copy.hpp \
|
race_setup.hpp no_copy.hpp \
|
||||||
constants.hpp \
|
constants.hpp \
|
||||||
translation.hpp \
|
translation.hpp \
|
||||||
traffic.cpp \
|
traffic.cpp \
|
||||||
player.hpp \
|
player.hpp \
|
||||||
lisp/lisp.cpp lisp/lisp.hpp \
|
lisp/lisp.cpp lisp/lisp.hpp \
|
||||||
lisp/lexer.cpp lisp/lexer.hpp \
|
lisp/lexer.cpp lisp/lexer.hpp \
|
||||||
lisp/parser.cpp lisp/parser.hpp \
|
lisp/parser.cpp lisp/parser.hpp \
|
||||||
@ -111,12 +113,12 @@ supertuxkart_SOURCES = main.cpp \
|
|||||||
gui/credits_menu.cpp gui/credits_menu.hpp \
|
gui/credits_menu.cpp gui/credits_menu.hpp \
|
||||||
gui/grand_prix_select.cpp gui/grand_prix_select.hpp \
|
gui/grand_prix_select.cpp gui/grand_prix_select.hpp \
|
||||||
gui/font.hpp gui/font.cpp \
|
gui/font.hpp gui/font.cpp \
|
||||||
robots/default_robot.cpp robots/default_robot.hpp \
|
robots/default_robot.cpp robots/default_robot.hpp \
|
||||||
replay_buffer_tpl.hpp \
|
replay_buffer_tpl.hpp \
|
||||||
replay_buffers.hpp replay_buffers.cpp \
|
replay_buffers.hpp replay_buffers.cpp \
|
||||||
replay_base.hpp replay_base.cpp \
|
replay_base.hpp replay_base.cpp \
|
||||||
replay_player.hpp replay_player.cpp \
|
replay_player.hpp replay_player.cpp \
|
||||||
replay_recorder.hpp replay_recorder.cpp
|
replay_recorder.hpp replay_recorder.cpp
|
||||||
|
|
||||||
|
|
||||||
# Link in the specific gcc 4.1 bug work around
|
# Link in the specific gcc 4.1 bug work around
|
||||||
|
@ -36,7 +36,7 @@ Attachment::Attachment(Kart* _kart)
|
|||||||
m_kart = _kart;
|
m_kart = _kart;
|
||||||
m_holder = new ssgSelector();
|
m_holder = new ssgSelector();
|
||||||
m_previous_owner = NULL;
|
m_previous_owner = NULL;
|
||||||
m_kart->getModel()->addKid(m_holder);
|
m_kart->getModelTransform()->addKid(m_holder);
|
||||||
|
|
||||||
for(int i=ATTACH_PARACHUTE; i<=ATTACH_TINYTUX; i++)
|
for(int i=ATTACH_PARACHUTE; i<=ATTACH_TINYTUX; i++)
|
||||||
{
|
{
|
||||||
|
@ -58,6 +58,7 @@ public:
|
|||||||
}
|
}
|
||||||
attachmentType getType () const { return m_type; }
|
attachmentType getType () const { return m_type; }
|
||||||
float getTimeLeft () const { return m_time_left; }
|
float getTimeLeft () const { return m_time_left; }
|
||||||
|
void setTimeLeft (float t){ m_time_left = t; }
|
||||||
Kart* getPreviousOwner () const { return m_previous_owner; }
|
Kart* getPreviousOwner () const { return m_previous_owner; }
|
||||||
float WeightAdjust () const {
|
float WeightAdjust () const {
|
||||||
return m_type==ATTACH_ANVIL
|
return m_type==ATTACH_ANVIL
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include "callback_manager.hpp"
|
#include "callback_manager.hpp"
|
||||||
|
#include "moving_physics.hpp"
|
||||||
|
|
||||||
CallbackManager *callback_manager=NULL;
|
CallbackManager *callback_manager=NULL;
|
||||||
|
|
||||||
|
@ -28,21 +28,21 @@
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
Collectable::Collectable(Kart* kart_)
|
Collectable::Collectable(Kart* kart_)
|
||||||
{
|
{
|
||||||
owner = kart_;
|
m_owner = kart_;
|
||||||
type = COLLECT_NOTHING;
|
m_type = COLLECT_NOTHING;
|
||||||
number = 0;
|
m_number = 0;
|
||||||
} // Collectable
|
} // Collectable
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void Collectable::set(collectableType _type, int n)
|
void Collectable::set(CollectableType type, int n)
|
||||||
{
|
{
|
||||||
if (type==_type)
|
if (m_type==type)
|
||||||
{
|
{
|
||||||
number+=n;
|
m_number+=n;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
type=_type;
|
m_type=type;
|
||||||
number=n;
|
m_number=n;
|
||||||
} // set
|
} // set
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -50,7 +50,7 @@ Material *Collectable::getIcon()
|
|||||||
{
|
{
|
||||||
// Check if it's one of the types which have a separate
|
// Check if it's one of the types which have a separate
|
||||||
// data file which includes the icon:
|
// data file which includes the icon:
|
||||||
return collectable_manager->getIcon(type);
|
return collectable_manager->getIcon(m_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -70,22 +70,22 @@ void Collectable::use()
|
|||||||
} // if MAGNET_BZZT
|
} // if MAGNET_BZZT
|
||||||
} // user_config->disableMagnet
|
} // user_config->disableMagnet
|
||||||
#endif
|
#endif
|
||||||
number--;
|
m_number--;
|
||||||
switch (type)
|
switch (m_type)
|
||||||
{
|
{
|
||||||
#ifdef USE_MAGNET
|
#ifdef USE_MAGNET
|
||||||
case COLLECT_MAGNET: owner->attach(ATTACH_MAGNET_BZZT, stk_config->m_magnet_time);
|
case COLLECT_MAGNET: m_owner->attach(ATTACH_MAGNET_BZZT, stk_config->m_magnet_time);
|
||||||
break ;
|
break ;
|
||||||
#endif
|
#endif
|
||||||
case COLLECT_ZIPPER: owner->handleZipper();
|
case COLLECT_ZIPPER: m_owner->handleZipper();
|
||||||
break ;
|
break ;
|
||||||
case COLLECT_HOMING_MISSILE:
|
case COLLECT_HOMING:
|
||||||
case COLLECT_SPARK:
|
case COLLECT_SPARK:
|
||||||
case COLLECT_MISSILE:
|
case COLLECT_MISSILE:
|
||||||
if(owner->isPlayerKart())
|
if(m_owner->isPlayerKart())
|
||||||
sound_manager->playSfx(SOUND_SHOT);
|
sound_manager->playSfx(SOUND_SHOT);
|
||||||
|
|
||||||
projectile_manager->newProjectile(owner, type);
|
projectile_manager->newProjectile(m_owner, m_type);
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
case COLLECT_ANVIL:
|
case COLLECT_ANVIL:
|
||||||
@ -93,7 +93,7 @@ void Collectable::use()
|
|||||||
//by the bananas) to the kart in the 1st position.
|
//by the bananas) to the kart in the 1st position.
|
||||||
for(unsigned int i = 0 ; i < world->getNumKarts(); ++i)
|
for(unsigned int i = 0 ; i < world->getNumKarts(); ++i)
|
||||||
{
|
{
|
||||||
if(world->getKart(i) == owner) continue;
|
if(world->getKart(i) == m_owner) continue;
|
||||||
if(world->getKart(i)->getPosition() == 1)
|
if(world->getKart(i)->getPosition() == 1)
|
||||||
{
|
{
|
||||||
world->getKart(i)->
|
world->getKart(i)->
|
||||||
@ -117,8 +117,8 @@ void Collectable::use()
|
|||||||
//are in front of this one.
|
//are in front of this one.
|
||||||
for(unsigned int i = 0 ; i < world->getNumKarts(); ++i)
|
for(unsigned int i = 0 ; i < world->getNumKarts(); ++i)
|
||||||
{
|
{
|
||||||
if(world->getKart(i) == owner) continue;
|
if(world->getKart(i) == m_owner) continue;
|
||||||
if(owner->getPosition() > world->
|
if(m_owner->getPosition() > world->
|
||||||
getKart(i)->getPosition())
|
getKart(i)->getPosition())
|
||||||
{
|
{
|
||||||
world->getKart(i)->attach(
|
world->getKart(i)->attach(
|
||||||
@ -139,7 +139,7 @@ void Collectable::use()
|
|||||||
default : break ;
|
default : break ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( number <= 0 )
|
if ( m_number <= 0 )
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
@ -152,10 +152,10 @@ void Collectable::hitRedHerring(int n)
|
|||||||
//depending on how bad the owner's position is. For the first
|
//depending on how bad the owner's position is. For the first
|
||||||
//driver the posibility is none, for the last player is 15 %.
|
//driver the posibility is none, for the last player is 15 %.
|
||||||
|
|
||||||
if(owner->getPosition() != 1 && type == COLLECT_NOTHING)
|
if(m_owner->getPosition() != 1 && m_type == COLLECT_NOTHING)
|
||||||
{
|
{
|
||||||
const int SPECIAL_PROB = (int)(15.0 / ((float)world->getNumKarts() /
|
const int SPECIAL_PROB = (int)(15.0 / ((float)world->getNumKarts() /
|
||||||
(float)owner->getPosition()));
|
(float)m_owner->getPosition()));
|
||||||
const int RAND_NUM = rand()%100;
|
const int RAND_NUM = rand()%100;
|
||||||
if(RAND_NUM <= SPECIAL_PROB)
|
if(RAND_NUM <= SPECIAL_PROB)
|
||||||
{
|
{
|
||||||
@ -163,18 +163,18 @@ void Collectable::hitRedHerring(int n)
|
|||||||
//the parachute.
|
//the parachute.
|
||||||
for(unsigned int i=0; i < world->getNumKarts(); ++i)
|
for(unsigned int i=0; i < world->getNumKarts(); ++i)
|
||||||
{
|
{
|
||||||
if(world->getKart(i) == owner) continue;
|
if(world->getKart(i) == m_owner) continue;
|
||||||
if(world->getKart(i)->getPosition() == 1 && world->getKart(i)->
|
if(world->getKart(i)->getPosition() == 1 && world->getKart(i)->
|
||||||
raceIsFinished())
|
raceIsFinished())
|
||||||
{
|
{
|
||||||
type = COLLECT_PARACHUTE;
|
m_type = COLLECT_PARACHUTE;
|
||||||
number = 1;
|
m_number = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type = rand()%(2) == 0 ? COLLECT_ANVIL : COLLECT_PARACHUTE;
|
m_type = rand()%(2) == 0 ? COLLECT_ANVIL : COLLECT_PARACHUTE;
|
||||||
number = 1;
|
m_number = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -182,7 +182,7 @@ void Collectable::hitRedHerring(int n)
|
|||||||
//rand() is moduled by COLLECT_MAX - 1 - 2 because because we have to
|
//rand() is moduled by COLLECT_MAX - 1 - 2 because because we have to
|
||||||
//exclude the anvil and the parachute, but later we have to add 1 to prevent
|
//exclude the anvil and the parachute, but later we have to add 1 to prevent
|
||||||
//having a value of 0 since that isn't a valid collectable.
|
//having a value of 0 since that isn't a valid collectable.
|
||||||
collectableType newC;
|
CollectableType newC;
|
||||||
if(!user_config->m_profile)
|
if(!user_config->m_profile)
|
||||||
{
|
{
|
||||||
// A zipper should not be used during time trial, since it
|
// A zipper should not be used during time trial, since it
|
||||||
@ -190,24 +190,24 @@ void Collectable::hitRedHerring(int n)
|
|||||||
// in time trail, but only the top 2 in any other mode
|
// in time trail, but only the top 2 in any other mode
|
||||||
int nIgnore = (world->m_race_setup.m_mode == RaceSetup::RM_TIME_TRIAL)
|
int nIgnore = (world->m_race_setup.m_mode == RaceSetup::RM_TIME_TRIAL)
|
||||||
? 3 : 2;
|
? 3 : 2;
|
||||||
newC = (collectableType)(rand()%(COLLECT_MAX - 1 - nIgnore) + 1);
|
newC = (CollectableType)(rand()%(COLLECT_MAX - 1 - nIgnore) + 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// No random effects when profiling!
|
// No random effects when profiling!
|
||||||
static int simpleCounter=-1;
|
static int simpleCounter=-1;
|
||||||
simpleCounter++;
|
simpleCounter++;
|
||||||
newC = (collectableType)(simpleCounter%(COLLECT_MAX - 1 - 2) + 1);
|
newC = (CollectableType)(simpleCounter%(COLLECT_MAX - 1 - 2) + 1);
|
||||||
}
|
}
|
||||||
if(type==COLLECT_NOTHING)
|
if(m_type==COLLECT_NOTHING)
|
||||||
{
|
{
|
||||||
type=newC;
|
m_type=newC;
|
||||||
number = n;
|
m_number = n;
|
||||||
}
|
}
|
||||||
else if(newC==type)
|
else if(newC==m_type)
|
||||||
{
|
{
|
||||||
number+=n;
|
m_number+=n;
|
||||||
if(number > MAX_COLLECTABLES) number = MAX_COLLECTABLES;
|
if(m_number > MAX_COLLECTABLES) m_number = MAX_COLLECTABLES;
|
||||||
}
|
}
|
||||||
// Ignore new collectable if it is different from the current one
|
// Ignore new collectable if it is different from the current one
|
||||||
} // hitRedHerring
|
} // hitRedHerring
|
||||||
|
@ -29,16 +29,16 @@ class Kart;
|
|||||||
class Collectable
|
class Collectable
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Kart* owner;
|
Kart* m_owner;
|
||||||
collectableType type;
|
CollectableType m_type;
|
||||||
int number;
|
int m_number;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Collectable (Kart* kart_);
|
Collectable (Kart* kart_);
|
||||||
void set (collectableType _type, int n=1);
|
void set (CollectableType _type, int n=1);
|
||||||
void clear () {type=COLLECT_NOTHING; number=0;}
|
void clear () {m_type=COLLECT_NOTHING; m_number=0;}
|
||||||
int getNum () const {return number;}
|
int getNum () const {return m_number;}
|
||||||
collectableType getType () {return type;}
|
CollectableType getType () {return m_type;}
|
||||||
void hitRedHerring(int n);
|
void hitRedHerring(int n);
|
||||||
Material* getIcon ();
|
Material* getIcon ();
|
||||||
void use ();
|
void use ();
|
||||||
|
@ -24,29 +24,32 @@
|
|||||||
#include "material_manager.hpp"
|
#include "material_manager.hpp"
|
||||||
#include "material.hpp"
|
#include "material.hpp"
|
||||||
#include "translation.hpp"
|
#include "translation.hpp"
|
||||||
|
#include "spark.hpp"
|
||||||
|
#include "missile.hpp"
|
||||||
|
#include "homing.hpp"
|
||||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||||
# define snprintf _snprintf
|
# define snprintf _snprintf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
collectableType collectable;
|
CollectableType collectable;
|
||||||
const char*const dataFile;
|
const char*const dataFile;
|
||||||
}
|
}
|
||||||
initCollectableType;
|
initCollectableType;
|
||||||
|
|
||||||
initCollectableType ict[]=
|
initCollectableType ict[]=
|
||||||
{
|
{
|
||||||
{COLLECT_ZIPPER, "zipper.collectable" },
|
{COLLECT_ZIPPER, "zipper.collectable" },
|
||||||
#ifdef USE_MAGNETS
|
#ifdef USE_MAGNETS
|
||||||
{COLLECT_MAGNET, "magnet.collectable" },
|
{COLLECT_MAGNET, "magnet.collectable" },
|
||||||
#endif
|
#endif
|
||||||
{COLLECT_SPARK, "spark.projectile" },
|
{COLLECT_SPARK, "spark.projectile" },
|
||||||
{COLLECT_MISSILE, "missile.projectile" },
|
{COLLECT_MISSILE, "missile.projectile" },
|
||||||
{COLLECT_HOMING_MISSILE, "homingmissile.projectile" },
|
{COLLECT_HOMING, "homingmissile.projectile" },
|
||||||
{COLLECT_ANVIL, "anvil.collectable" },
|
{COLLECT_ANVIL, "anvil.collectable" },
|
||||||
{COLLECT_PARACHUTE, "parachute.collectable" },
|
{COLLECT_PARACHUTE, "parachute.collectable" },
|
||||||
{COLLECT_MAX, "" },
|
{COLLECT_MAX, "" },
|
||||||
};
|
};
|
||||||
|
|
||||||
CollectableManager* collectable_manager=0;
|
CollectableManager* collectable_manager=0;
|
||||||
@ -109,23 +112,13 @@ void CollectableManager::Load(int collectType, const char* filename)
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void CollectableManager::LoadNode(const lisp::Lisp* lisp, int collectType )
|
void CollectableManager::LoadNode(const lisp::Lisp* lisp, int collectType )
|
||||||
{
|
{
|
||||||
std::string sName, sModel, sIconFile;
|
std::string sName, sModel, sIconFile;
|
||||||
int dummy;
|
lisp->get("name", sName );
|
||||||
lisp->get("name", sName ); // the name is actually ignored
|
lisp->get("model", sModel );
|
||||||
lisp->get("model", sModel );
|
lisp->get("icon", sIconFile );
|
||||||
lisp->get("icon", sIconFile );
|
|
||||||
// If the speed value is an integer (e.g. no "."), an uninitialised
|
|
||||||
// value will be returned. In this case try reading the speed as
|
|
||||||
// an integer value.
|
|
||||||
if(!lisp->get("speed", m_all_speeds[collectType]))
|
|
||||||
{
|
|
||||||
dummy=-1;
|
|
||||||
lisp->get("speed", dummy);
|
|
||||||
m_all_speeds[collectType]=(float)dummy;
|
|
||||||
}
|
|
||||||
|
|
||||||
// load material
|
// load material
|
||||||
m_all_icons [collectType] = material_manager->getMaterial(sIconFile);
|
m_all_icons[collectType] = material_manager->getMaterial(sIconFile);
|
||||||
m_all_icons[collectType]->getState()->ref();
|
m_all_icons[collectType]->getState()->ref();
|
||||||
|
|
||||||
//FIXME: something probably forgets to disable GL_CULL_FACE after enabling it,
|
//FIXME: something probably forgets to disable GL_CULL_FACE after enabling it,
|
||||||
@ -142,6 +135,21 @@ void CollectableManager::LoadNode(const lisp::Lisp* lisp, int collectType )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_all_models[collectType] = 0;
|
m_all_models[collectType] = 0;
|
||||||
|
#ifdef BULLET
|
||||||
|
m_all_extends[collectType] = btVector3(0.0f,0.0f,0.0f);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load special attributes for certain collectables
|
||||||
|
switch (collectType) {
|
||||||
|
case COLLECT_SPARK:
|
||||||
|
Spark::init (lisp, m_all_models[collectType]); break;
|
||||||
|
case COLLECT_MISSILE:
|
||||||
|
Missile::init(lisp, m_all_models[collectType]); break;
|
||||||
|
case COLLECT_HOMING:
|
||||||
|
Homing::init (lisp, m_all_models[collectType]); break;
|
||||||
|
default:;
|
||||||
|
} // switch
|
||||||
|
|
||||||
} // LoadNode
|
} // LoadNode
|
||||||
|
|
||||||
|
@ -22,14 +22,18 @@
|
|||||||
|
|
||||||
#include "lisp/parser.hpp"
|
#include "lisp/parser.hpp"
|
||||||
#include "lisp/lisp.hpp"
|
#include "lisp/lisp.hpp"
|
||||||
|
#ifdef BULLET
|
||||||
|
#include "btBulletDynamicsCommon.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
class Material;
|
class Material;
|
||||||
class ssgEntity;
|
class ssgEntity;
|
||||||
|
|
||||||
// The anvil and parachute must be at the end of the enum, and the
|
// The anvil and parachute must be at the end of the enum, and the
|
||||||
// zipper just before them (see collectable::hitRedHerring).
|
// zipper just before them (see collectable::hitRedHerring).
|
||||||
enum collectableType {COLLECT_NOTHING,
|
enum CollectableType {COLLECT_NOTHING,
|
||||||
COLLECT_MISSILE, COLLECT_HOMING_MISSILE,
|
COLLECT_MISSILE, COLLECT_HOMING,
|
||||||
COLLECT_SPARK, COLLECT_ZIPPER,
|
COLLECT_SPARK, COLLECT_ZIPPER,
|
||||||
COLLECT_PARACHUTE, COLLECT_ANVIL,
|
COLLECT_PARACHUTE, COLLECT_ANVIL,
|
||||||
#ifdef USE_MAGNETS
|
#ifdef USE_MAGNETS
|
||||||
@ -41,17 +45,26 @@ class CollectableManager
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Material* m_all_icons [COLLECT_MAX];
|
Material* m_all_icons [COLLECT_MAX];
|
||||||
float m_all_speeds[COLLECT_MAX];
|
float m_all_max_distance[COLLECT_MAX]; // if a target is closer than this
|
||||||
|
float m_all_force_to_target[COLLECT_MAX]; // apply this force to move towards
|
||||||
|
// the target
|
||||||
|
float m_all_max_turn_angle[COLLECT_MAX]; // maximum turn angle for homing
|
||||||
ssgEntity* m_all_models[COLLECT_MAX];
|
ssgEntity* m_all_models[COLLECT_MAX];
|
||||||
|
btVector3 m_all_extends[COLLECT_MAX];
|
||||||
void LoadNode (const lisp::Lisp* lisp, int collectType);
|
void LoadNode (const lisp::Lisp* lisp, int collectType);
|
||||||
public:
|
public:
|
||||||
CollectableManager ();
|
CollectableManager ();
|
||||||
void loadCollectables();
|
void loadCollectables();
|
||||||
void removeTextures ();
|
void removeTextures ();
|
||||||
void Load (int collectType, const char* filename);
|
void Load (int collectType, const char* filename);
|
||||||
Material* getIcon (int type) {return m_all_icons [type];}
|
Material* getIcon (int type) const {return m_all_icons [type]; }
|
||||||
float getSpeed (int type) {return m_all_speeds[type];}
|
ssgEntity* getModel (int type) const {return m_all_models[type]; }
|
||||||
ssgEntity* getModel (int type) {return m_all_models[type];}
|
float getForceToTarget(int type) const {return m_all_force_to_target[type]; }
|
||||||
|
float getMaxDistance (int type) const {return m_all_max_distance[type];}
|
||||||
|
float getMaxTurnAngle (int type) const {return m_all_max_turn_angle[type];}
|
||||||
|
#ifdef BULLET
|
||||||
|
const btVector3& getExtend (int type) const {return m_all_extends[type]; }
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern CollectableManager* collectable_manager;
|
extern CollectableManager* collectable_manager;
|
||||||
|
@ -74,5 +74,6 @@
|
|||||||
|
|
||||||
#define NINETY_DEGREE_RAD (M_PI/2.0f)
|
#define NINETY_DEGREE_RAD (M_PI/2.0f)
|
||||||
#define DEGREE_TO_RAD(x) ((x)*M_PI/180.0f)
|
#define DEGREE_TO_RAD(x) ((x)*M_PI/180.0f)
|
||||||
|
#define RAD_TO_DEGREE(x) ((x)*180.0f/M_PI)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -26,12 +26,9 @@
|
|||||||
|
|
||||||
Explosion::Explosion(sgCoord* coord) : ssgTransform()
|
Explosion::Explosion(sgCoord* coord) : ssgTransform()
|
||||||
{
|
{
|
||||||
|
this->ref();
|
||||||
ssgCutout *cut = new ssgCutout();
|
ssgCutout *cut = new ssgCutout();
|
||||||
addKid(cut);
|
addKid(cut); // derefing the explosion will free the cutout
|
||||||
// Make sure that the transform object does not get deleted when it is
|
|
||||||
// removed from the scene graphs. This can happen when the explosion is
|
|
||||||
// moved to the deletedExplosion list in the projecile_manager.
|
|
||||||
ref();
|
|
||||||
m_seq = projectile_manager->getExplosionModel();
|
m_seq = projectile_manager->getExplosionModel();
|
||||||
cut->addKid(m_seq);
|
cut->addKid(m_seq);
|
||||||
init(coord);
|
init(coord);
|
||||||
@ -45,6 +42,7 @@ void Explosion::init(sgCoord* coord)
|
|||||||
setTransform(coord);
|
setTransform(coord);
|
||||||
m_step = -1;
|
m_step = -1;
|
||||||
scene->add(this);
|
scene->add(this);
|
||||||
|
printf("explosion\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -53,8 +51,8 @@ void Explosion::update (float dt)
|
|||||||
|
|
||||||
if ( ++m_step >= m_seq->getNumKids() )
|
if ( ++m_step >= m_seq->getNumKids() )
|
||||||
{
|
{
|
||||||
projectile_manager->FinishedExplosion();
|
|
||||||
scene->remove((ssgTransform*)this);
|
scene->remove((ssgTransform*)this);
|
||||||
|
projectile_manager->FinishedExplosion();
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,10 +29,10 @@ public:
|
|||||||
ssgSelector *m_seq ;
|
ssgSelector *m_seq ;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Explosion(sgCoord* coord);
|
Explosion(sgCoord* coord);
|
||||||
int inUse () {return (m_step >= 0); }
|
|
||||||
void init (sgCoord *coord);
|
void init (sgCoord *coord);
|
||||||
void update (float delta_t);
|
void update (float delta_t);
|
||||||
|
int inUse () {return (m_step >= 0); }
|
||||||
bool hasEnded () {return m_step >= m_seq->getNumKids(); }
|
bool hasEnded () {return m_step >= m_seq->getNumKids(); }
|
||||||
|
|
||||||
} ;
|
} ;
|
||||||
|
@ -286,7 +286,7 @@ void HelpMenu::switch_to_second_screen()
|
|||||||
|
|
||||||
widget_manager->add_wgt(WTOK_ITEMIMG2, 10, 13);
|
widget_manager->add_wgt(WTOK_ITEMIMG2, 10, 13);
|
||||||
widget_manager->set_wgt_texture(WTOK_ITEMIMG2,
|
widget_manager->set_wgt_texture(WTOK_ITEMIMG2,
|
||||||
collectable_manager->getIcon(COLLECT_HOMING_MISSILE)->getState()->getTextureHandle());
|
collectable_manager->getIcon(COLLECT_HOMING)->getState()->getTextureHandle());
|
||||||
widget_manager->set_wgt_color(WTOK_ITEMIMG2, WGT_WHITE);
|
widget_manager->set_wgt_color(WTOK_ITEMIMG2, WGT_WHITE);
|
||||||
widget_manager->show_wgt_texture( WTOK_ITEMIMG2 );
|
widget_manager->show_wgt_texture( WTOK_ITEMIMG2 );
|
||||||
widget_manager->set_wgt_round_corners(WTOK_ITEMIMG2, WGT_AREA_NONE);
|
widget_manager->set_wgt_round_corners(WTOK_ITEMIMG2, WGT_AREA_NONE);
|
||||||
|
@ -100,11 +100,25 @@ RaceGUI::handle(GameAction ga, int value)
|
|||||||
|
|
||||||
switch (ga)
|
switch (ga)
|
||||||
{
|
{
|
||||||
|
case GA_DEBUG_ADD_SPARK:
|
||||||
|
if (world->m_race_setup.getNumPlayers() ==1 )
|
||||||
|
{
|
||||||
|
Kart* kart = world->getPlayerKart(0);
|
||||||
|
kart->setCollectable(COLLECT_SPARK, 10000);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case GA_DEBUG_ADD_MISSILE:
|
case GA_DEBUG_ADD_MISSILE:
|
||||||
if (world->m_race_setup.getNumPlayers() ==1 )
|
if (world->m_race_setup.getNumPlayers() ==1 )
|
||||||
{
|
{
|
||||||
Kart* kart = world->getPlayerKart(0);
|
Kart* kart = world->getPlayerKart(0);
|
||||||
kart->setCollectable((rand()%2)?COLLECT_MISSILE :COLLECT_HOMING_MISSILE, 10000);
|
kart->setCollectable(COLLECT_MISSILE, 10000);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GA_DEBUG_ADD_HOMING:
|
||||||
|
if (world->m_race_setup.getNumPlayers() ==1 )
|
||||||
|
{
|
||||||
|
Kart* kart = world->getPlayerKart(0);
|
||||||
|
kart->setCollectable(COLLECT_HOMING, 10000);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GA_DEBUG_TOGGLE_FPS:
|
case GA_DEBUG_TOGGLE_FPS:
|
||||||
@ -708,7 +722,7 @@ void RaceGUI::drawSpeed(Kart* kart, int offset_x, int offset_y,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
glTexCoord2f(0, 1);glVertex2i(offset_x, offset_y+width);
|
glTexCoord2f(0, 1);glVertex2i(offset_x, offset_y+width);
|
||||||
glTexCoord2f((speedRatio-0.5)*2, 1);glVertex2i((int)(offset_x+height*(speedRatio-0.5)*2), offset_y+height);
|
glTexCoord2f((speedRatio-0.5f)*2, 1);glVertex2i((int)(offset_x+height*(speedRatio-0.5f)*2), offset_y+height);
|
||||||
}
|
}
|
||||||
|
|
||||||
glEnd () ;
|
glEnd () ;
|
||||||
|
@ -105,7 +105,7 @@
|
|||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
WholeProgramOptimization="true"
|
WholeProgramOptimization="false"
|
||||||
AdditionalIncludeDirectories="..\..\bullet\src;"$(GLUT_PATH)\include""
|
AdditionalIncludeDirectories="..\..\bullet\src;"$(GLUT_PATH)\include""
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG"
|
PreprocessorDefinitions="WIN32;NDEBUG"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
|
@ -704,6 +704,10 @@
|
|||||||
RelativePath="../../../src\explosion.cpp"
|
RelativePath="../../../src\explosion.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\flyable.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="../../../src\game_manager.cpp"
|
RelativePath="../../../src\game_manager.cpp"
|
||||||
>
|
>
|
||||||
@ -728,6 +732,10 @@
|
|||||||
RelativePath="../../../src\history.cpp"
|
RelativePath="../../../src\history.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\homing.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="../../../src\isect.cpp"
|
RelativePath="../../../src\isect.cpp"
|
||||||
>
|
>
|
||||||
@ -760,6 +768,10 @@
|
|||||||
RelativePath="../../../src\material_manager.cpp"
|
RelativePath="../../../src\material_manager.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\missile.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="../../../src\moveable.cpp"
|
RelativePath="../../../src\moveable.cpp"
|
||||||
>
|
>
|
||||||
@ -792,10 +804,6 @@
|
|||||||
RelativePath="../../../src\player_kart.cpp"
|
RelativePath="../../../src\player_kart.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="../../../src\projectile.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="../../../src\projectile_manager.cpp"
|
RelativePath="../../../src\projectile_manager.cpp"
|
||||||
>
|
>
|
||||||
@ -848,6 +856,10 @@
|
|||||||
RelativePath="../../../src\sound_plib.cpp"
|
RelativePath="../../../src\sound_plib.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\spark.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="../../../src\ssg_help.cpp"
|
RelativePath="../../../src\ssg_help.cpp"
|
||||||
>
|
>
|
||||||
@ -880,10 +892,6 @@
|
|||||||
RelativePath="../../../src\user_config.cpp"
|
RelativePath="../../../src\user_config.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="../../../src\utils.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\widget.cpp"
|
RelativePath="..\..\widget.cpp"
|
||||||
>
|
>
|
||||||
@ -1070,6 +1078,10 @@
|
|||||||
RelativePath="../../../src\explosion.hpp"
|
RelativePath="../../../src\explosion.hpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\flyable.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="../../../src\game_manager.hpp"
|
RelativePath="../../../src\game_manager.hpp"
|
||||||
>
|
>
|
||||||
@ -1094,6 +1106,14 @@
|
|||||||
RelativePath="../../../src\history.hpp"
|
RelativePath="../../../src\history.hpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\homing.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\input.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="../../../src\isect.hpp"
|
RelativePath="../../../src\isect.hpp"
|
||||||
>
|
>
|
||||||
@ -1122,6 +1142,10 @@
|
|||||||
RelativePath="../../../src\material_manager.hpp"
|
RelativePath="../../../src\material_manager.hpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\missile.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="../../../src\moveable.hpp"
|
RelativePath="../../../src\moveable.hpp"
|
||||||
>
|
>
|
||||||
@ -1166,10 +1190,6 @@
|
|||||||
RelativePath="../../../src\player_kart.hpp"
|
RelativePath="../../../src\player_kart.hpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="../../../src\projectile.hpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="../../../src\projectile_manager.hpp"
|
RelativePath="../../../src\projectile_manager.hpp"
|
||||||
>
|
>
|
||||||
@ -1234,6 +1254,10 @@
|
|||||||
RelativePath="../../../src\sound_plib.hpp"
|
RelativePath="../../../src\sound_plib.hpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\spark.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="../../../src\ssg_help.hpp"
|
RelativePath="../../../src\ssg_help.hpp"
|
||||||
>
|
>
|
||||||
@ -1266,10 +1290,6 @@
|
|||||||
RelativePath="../../../src\user_config.hpp"
|
RelativePath="../../../src\user_config.hpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="../../../src\utils.hpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\widget.hpp"
|
RelativePath="..\..\widget.hpp"
|
||||||
>
|
>
|
||||||
|
@ -155,6 +155,8 @@ enum GameAction
|
|||||||
GA_LEAVE_RACE, // Switch from race to menu.
|
GA_LEAVE_RACE, // Switch from race to menu.
|
||||||
|
|
||||||
GA_DEBUG_ADD_MISSILE,
|
GA_DEBUG_ADD_MISSILE,
|
||||||
|
GA_DEBUG_ADD_SPARK,
|
||||||
|
GA_DEBUG_ADD_HOMING,
|
||||||
GA_DEBUG_TOGGLE_FPS,
|
GA_DEBUG_TOGGLE_FPS,
|
||||||
GA_DEBUG_BULLET,
|
GA_DEBUG_BULLET,
|
||||||
GA_DEBUG_TOGGLE_WIREFRAME,
|
GA_DEBUG_TOGGLE_WIREFRAME,
|
||||||
|
225
src/kart.cpp
225
src/kart.cpp
@ -349,6 +349,7 @@ void Kart::reset()
|
|||||||
|
|
||||||
m_race_lap = -1;
|
m_race_lap = -1;
|
||||||
m_lap_start_time = -1.0f;
|
m_lap_start_time = -1.0f;
|
||||||
|
m_time_at_last_lap = 99999.9f;
|
||||||
m_shortcut_count = 0;
|
m_shortcut_count = 0;
|
||||||
m_shortcut_sector = Track::UNKNOWN_SECTOR;
|
m_shortcut_sector = Track::UNKNOWN_SECTOR;
|
||||||
m_shortcut_type = SC_NONE;
|
m_shortcut_type = SC_NONE;
|
||||||
@ -927,8 +928,6 @@ float Kart::handleWheelie(float dt)
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
void Kart::updatePhysics (float dt)
|
void Kart::updatePhysics (float dt)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef BULLET
|
|
||||||
float engine_power = getActualWheelForce() + handleWheelie(dt);
|
float engine_power = getActualWheelForce() + handleWheelie(dt);
|
||||||
if(m_attachment.getType()==ATTACH_PARACHUTE) engine_power*=0.2f;
|
if(m_attachment.getType()==ATTACH_PARACHUTE) engine_power*=0.2f;
|
||||||
|
|
||||||
@ -1011,222 +1010,6 @@ void Kart::updatePhysics (float dt)
|
|||||||
//at low velocity, forces on kart push it back and forth so we ignore this
|
//at low velocity, forces on kart push it back and forth so we ignore this
|
||||||
if(fabsf(m_speed) < 0.2f) // quick'n'dirty workaround for bug 1776883
|
if(fabsf(m_speed) < 0.2f) // quick'n'dirty workaround for bug 1776883
|
||||||
m_speed = 0;
|
m_speed = 0;
|
||||||
|
|
||||||
#else // ! BULLET
|
|
||||||
m_skid_front = m_skid_rear = false;
|
|
||||||
sgVec3 AirResistance, SysResistance;
|
|
||||||
// Get some values once, to avoid calling them more than once.
|
|
||||||
const float WORLD_GRAVITY = world->getGravity();
|
|
||||||
const float WHEEL_BASE = getWheelBase();
|
|
||||||
const float MASS = getMass(); // includes m_attachment.WeightAdjust
|
|
||||||
const float AIR_FRICTION = getAirResistance(); // includes attachmetn.AirFrictAdjust
|
|
||||||
const float ROLL_RESIST = getRollResistance();
|
|
||||||
|
|
||||||
if(m_wheelie_angle>0.0f)
|
|
||||||
{
|
|
||||||
m_velocity.xyz[1]-=getWheelieSpeedBoost()*m_wheelie_angle/getWheelieMaxPitch();
|
|
||||||
if(m_velocity.xyz[1]<0) m_velocity.xyz[1]=0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Handle throttle and brakes
|
|
||||||
// ==========================
|
|
||||||
float throttle;
|
|
||||||
|
|
||||||
if(m_on_ground)
|
|
||||||
{
|
|
||||||
if(m_controls.brake)
|
|
||||||
{
|
|
||||||
throttle = m_velocity.xyz[1]<0.0f ? -1.0f : -getBrakeFactor();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // not braking
|
|
||||||
throttle = m_velocity.xyz[1]<0.0f ? getBrakeFactor()
|
|
||||||
: m_controls.accel*m_current_friction*m_current_friction;
|
|
||||||
}
|
|
||||||
// Handle wheelies
|
|
||||||
// ===============
|
|
||||||
if ( m_controls.wheelie && m_velocity.xyz[1] >=
|
|
||||||
getMaxSpeed()*getWheelieMaxSpeedRatio())
|
|
||||||
{
|
|
||||||
m_velocity.hpr[0]=0.0;
|
|
||||||
if ( m_wheelie_angle < getWheelieMaxPitch() )
|
|
||||||
m_wheelie_angle += getWheeliePitchRate() * dt;
|
|
||||||
else
|
|
||||||
m_wheelie_angle = getWheelieMaxPitch();
|
|
||||||
}
|
|
||||||
else if ( m_wheelie_angle > 0.0f )
|
|
||||||
{
|
|
||||||
m_wheelie_angle -= getWheelieRestoreRate() * dt;
|
|
||||||
if ( m_wheelie_angle <= 0.0f ) m_wheelie_angle = 0.0f ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // not on ground
|
|
||||||
throttle = 0.0;
|
|
||||||
} // if !m_on_ground
|
|
||||||
|
|
||||||
float ForceLong = throttle * getMaxPower();
|
|
||||||
// apply air friction and system friction
|
|
||||||
AirResistance[0] = 0.0f;
|
|
||||||
AirResistance[1] = AIR_FRICTION*m_velocity.xyz[1]*fabs(m_velocity.xyz[1]);
|
|
||||||
AirResistance[2] = 0.0f;
|
|
||||||
SysResistance[0] = ROLL_RESIST*m_velocity.xyz[0];;
|
|
||||||
SysResistance[1] = ROLL_RESIST*m_velocity.xyz[1];
|
|
||||||
SysResistance[2] = 0.0f;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Compute longitudinal acceleration for slipping
|
|
||||||
// ----------------------------------------------
|
|
||||||
const float FORCE_ON_REAR_TIRE = 0.5f*MASS*WORLD_GRAVITY + m_prev_accel*MASS*getHeightCOG()/WHEEL_BASE;
|
|
||||||
const float FORCE_ON_FRONT_TIRE = MASS*WORLD_GRAVITY - FORCE_ON_REAR_TIRE;
|
|
||||||
float maxGrip = std::max(FORCE_ON_REAR_TIRE,FORCE_ON_FRONT_TIRE)*getTireGrip();
|
|
||||||
|
|
||||||
// If the kart is on ground, modify the grip by the friction
|
|
||||||
// modifier for the texture/terrain.
|
|
||||||
if(m_on_ground && m_material_hot) maxGrip *= m_material_hot->getFriction();
|
|
||||||
|
|
||||||
// Gravity handling
|
|
||||||
// ================
|
|
||||||
float ForceGravity;
|
|
||||||
if(m_on_ground)
|
|
||||||
{
|
|
||||||
if(m_normal_hot)
|
|
||||||
{
|
|
||||||
// Adjust pitch and roll according to the current terrain. To compute
|
|
||||||
// the correspondant angles, we consider first a normalised line
|
|
||||||
// pointing into the direction the kart is facing (pointing from (0,0,0)
|
|
||||||
// to (x,y,0)). The angle between this line and the triangle the kart is
|
|
||||||
// on determines the pitch. Similartly the roll is computed, using a
|
|
||||||
// normalised line pointing to the right of the kart, for which we simply
|
|
||||||
// use (-y,x,0).
|
|
||||||
const float kartAngle = m_curr_pos.hpr[0]*M_PI/180.0f;
|
|
||||||
const float X = -sin(kartAngle);
|
|
||||||
const float Y = cos(kartAngle);
|
|
||||||
// Compute the angle between the normal of the plane and the line to
|
|
||||||
// (x,y,0). (x,y,0) is normalised, so are the coordinates of the plane,
|
|
||||||
// simplifying the computation of the scalar product.
|
|
||||||
float pitch = ( (*m_normal_hot)[0]*X + (*m_normal_hot)[1]*Y ); // use ( x,y,0)
|
|
||||||
float roll = (-(*m_normal_hot)[0]*Y + (*m_normal_hot)[1]*X ); // use (-y,x,0)
|
|
||||||
|
|
||||||
// The actual angle computed above is between the normal and the (x,y,0)
|
|
||||||
// line, so to compute the actual angles 90 degrees must be subtracted.
|
|
||||||
pitch = acosf(pitch)/M_PI*180.0f-90.0f;
|
|
||||||
roll = acosf(roll )/M_PI*180.0f-90.0f;
|
|
||||||
// if dt is too big, the relaxation will overshoot, and the
|
|
||||||
// karts will either be hopping, or even turn upside down etc.
|
|
||||||
if(dt<=0.05)
|
|
||||||
{
|
|
||||||
# define RELAX(oldVal, newVal) (oldVal + (newVal-oldVal)*dt*20.0f)
|
|
||||||
m_curr_pos.hpr[1] = RELAX(m_curr_pos.hpr[1],pitch);
|
|
||||||
m_curr_pos.hpr[2] = RELAX(m_curr_pos.hpr[2],roll );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_curr_pos.hpr[1] = pitch;
|
|
||||||
m_curr_pos.hpr[2] = roll ;
|
|
||||||
}
|
|
||||||
if(fabsf(m_curr_pos.hpr[1])>fabsf(pitch)) m_curr_pos.hpr[1]=pitch;
|
|
||||||
if(fabsf(m_curr_pos.hpr[2])>fabsf(roll )) m_curr_pos.hpr[2]=roll;
|
|
||||||
}
|
|
||||||
if(m_controls.jump)
|
|
||||||
{ // ignore gravity down when jumping
|
|
||||||
ForceGravity = stk_config->m_jump_impulse*WORLD_GRAVITY;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // kart is on groud and not jumping
|
|
||||||
if(user_config->m_improved_physics)
|
|
||||||
{
|
|
||||||
// FIXME:
|
|
||||||
// While these physics computation is correct, it is very difficult
|
|
||||||
// to drive, esp. the sandtrack: the grades (with the current
|
|
||||||
// physics parameters) are too steep, so the kart needs a very high
|
|
||||||
// initial velocity to be able to reach the top. Especially the
|
|
||||||
// AI gets stuck very easily! Perhaps reduce the forces somewhat?
|
|
||||||
const float PITCH_IN_RAD = m_curr_pos.hpr[1]*M_PI/180.0f;
|
|
||||||
ForceGravity = -WORLD_GRAVITY * MASS * cos(PITCH_IN_RAD);
|
|
||||||
ForceLong -= WORLD_GRAVITY * MASS * sin(PITCH_IN_RAD);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ForceGravity = -WORLD_GRAVITY * MASS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // kart is not on ground, gravity applies all to z axis.
|
|
||||||
ForceGravity = -WORLD_GRAVITY * MASS;
|
|
||||||
}
|
|
||||||
m_velocity.xyz[2] += ForceGravity / MASS * dt;
|
|
||||||
|
|
||||||
|
|
||||||
if(m_wheelie_angle <= 0.0f && m_on_ground)
|
|
||||||
{
|
|
||||||
// At low speed, the advanced turning mode can result in 'flickering', i.e.
|
|
||||||
// very quick left/right movements. The reason might be:
|
|
||||||
// 1) integration timestep to big
|
|
||||||
// 2) the kart turning too much, thus 'oversteering', which then gets
|
|
||||||
// corrected (which might be caused by wrongly tuned physics parameters,
|
|
||||||
// or the too big timestep mentioned above
|
|
||||||
// Since at lower speed the simple turning algorithm is good enough,
|
|
||||||
// the advanced sliding turn algorithm is only used at higher speeds.
|
|
||||||
|
|
||||||
// FIXME: for now, only use the simple steering algorithm.
|
|
||||||
// so the test for 'lower speed' is basically disabled for now,
|
|
||||||
// since the velocity will always be lower than 1.5*100000.0f
|
|
||||||
if(fabsf(m_velocity.xyz[1])<150000.0f)
|
|
||||||
{
|
|
||||||
const float MSA = getMaxSteerAngle();
|
|
||||||
m_velocity.hpr[0] = m_controls.lr * ((m_velocity.xyz[1]>=0.0f) ? MSA : -MSA);
|
|
||||||
if(m_velocity.hpr[0]> MSA) m_velocity.hpr[0] = MSA; // In case the AI sets
|
|
||||||
if(m_velocity.hpr[0]<-MSA) m_velocity.hpr[0] = -MSA; // m_controls.lr >1 or <-1
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const float STEER_ANGLE = m_controls.lr*getMaxSteerAngle()*M_PI/180.0f;
|
|
||||||
const float TURN_DISTANCE = m_velocity.hpr[0]*M_PI/180.0f * WHEEL_BASE/2.0f;
|
|
||||||
const float SLIP_ANGLE_FRONT = atan((m_velocity.xyz[0]+TURN_DISTANCE)
|
|
||||||
/fabsf(m_velocity.xyz[1]))
|
|
||||||
- sgn(m_velocity.xyz[1])*STEER_ANGLE;
|
|
||||||
const float SLIP_ANGLE_REAR = atan((m_velocity.xyz[0]-TURN_DISTANCE)
|
|
||||||
/fabsf(m_velocity.xyz[1]));
|
|
||||||
const float FORCE_LAT_FRONT = NormalizedLateralForce(SLIP_ANGLE_FRONT, getCornerStiffF())
|
|
||||||
* FORCE_ON_FRONT_TIRE - SysResistance[0]*0.5f;
|
|
||||||
const float FORCE_LAT_REAR = NormalizedLateralForce(SLIP_ANGLE_REAR, getCornerStiffR())
|
|
||||||
* FORCE_ON_REAR_TIRE - SysResistance[0]*0.5f;
|
|
||||||
const float CORNER_FORCE = FORCE_LAT_REAR + cos(STEER_ANGLE)*FORCE_LAT_FRONT;
|
|
||||||
m_velocity.xyz[0] = CORNER_FORCE/MASS*dt;
|
|
||||||
const float TORQUE = FORCE_LAT_REAR *WHEEL_BASE/2
|
|
||||||
- cos(STEER_ANGLE)*FORCE_LAT_FRONT*WHEEL_BASE/2;
|
|
||||||
const float ANGLE_ACCELERATION = TORQUE/getInertia();
|
|
||||||
|
|
||||||
m_velocity.hpr[0] += ANGLE_ACCELERATION*dt*180.0f/M_PI;
|
|
||||||
} // fabsf(m_velocity.xyz[1])<0.5
|
|
||||||
} // m_wheelie_angle <=0.0f && m_on_ground
|
|
||||||
|
|
||||||
// Longitudinal accelleration
|
|
||||||
// ==========================
|
|
||||||
const float EFECTIVE_FORCE = (ForceLong-AirResistance[1]-SysResistance[1]);
|
|
||||||
// Slipping: more force than what can be supported by the back wheels
|
|
||||||
// --> reduce the effective force acting on the kart - currently
|
|
||||||
// by an arbitrary value.
|
|
||||||
if(fabs(EFECTIVE_FORCE)>maxGrip)
|
|
||||||
{
|
|
||||||
// EFECTIVE_FORCE *= 0.4f;
|
|
||||||
// m_skid_rear = true;
|
|
||||||
} // while EFECTIVE_FORCE>maxGrip
|
|
||||||
float ACCELERATION = EFECTIVE_FORCE / MASS;
|
|
||||||
|
|
||||||
m_velocity.xyz[1] += ACCELERATION * dt;
|
|
||||||
m_prev_accel = ACCELERATION;
|
|
||||||
|
|
||||||
if(m_wheelie_angle>0.0f)
|
|
||||||
{
|
|
||||||
m_velocity.xyz[1]+=
|
|
||||||
getWheelieSpeedBoost()*m_wheelie_angle/getWheelieMaxPitch();
|
|
||||||
if(m_velocity.xyz[1]<0) m_velocity.xyz[1]=0.0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} // updatePhysics
|
} // updatePhysics
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -1478,7 +1261,7 @@ void Kart::loadData()
|
|||||||
lod -> addKid ( obj ) ;
|
lod -> addKid ( obj ) ;
|
||||||
lod -> setRanges ( r, 2 ) ;
|
lod -> setRanges ( r, 2 ) ;
|
||||||
|
|
||||||
this-> getModel() -> addKid ( lod ) ;
|
this-> getModelTransform() -> addKid ( lod ) ;
|
||||||
|
|
||||||
// Attach Particle System
|
// Attach Particle System
|
||||||
//JH sgCoord pipe_pos = {{0, 0, .3}, {0, 0, 0}} ;
|
//JH sgCoord pipe_pos = {{0, 0, .3}, {0, 0, 0}} ;
|
||||||
@ -1495,7 +1278,7 @@ void Kart::loadData()
|
|||||||
|
|
||||||
m_shadow = createShadow(m_kart_properties->getShadowFile(), -1, 1, -1, 1);
|
m_shadow = createShadow(m_kart_properties->getShadowFile(), -1, 1, -1, 1);
|
||||||
m_shadow->ref();
|
m_shadow->ref();
|
||||||
m_model->addKid ( m_shadow );
|
m_model_transform->addKid ( m_shadow );
|
||||||
} // loadData
|
} // loadData
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -1548,7 +1331,7 @@ void Kart::placeModel ()
|
|||||||
// c.xyz[2] += 0.3f*fabs(sin(m_wheelie_angle*SG_DEGREES_TO_RADIANS));
|
// c.xyz[2] += 0.3f*fabs(sin(m_wheelie_angle*SG_DEGREES_TO_RADIANS));
|
||||||
const float CENTER_SHIFT = getGravityCenterShift();
|
const float CENTER_SHIFT = getGravityCenterShift();
|
||||||
c.xyz[2] -= (0.5f-CENTER_SHIFT)*m_kart_height; // adjust for center of gravity
|
c.xyz[2] -= (0.5f-CENTER_SHIFT)*m_kart_height; // adjust for center of gravity
|
||||||
m_model->setTransform(&c);
|
m_model_transform->setTransform(&c);
|
||||||
|
|
||||||
// Check if a kart needs to be rescued.
|
// Check if a kart needs to be rescued.
|
||||||
if((fabs(m_curr_pos.hpr[2])>60 &&
|
if((fabs(m_curr_pos.hpr[2])>60 &&
|
||||||
|
@ -163,8 +163,8 @@ public:
|
|||||||
m_wheelie_angle=angle;
|
m_wheelie_angle=angle;
|
||||||
m_zipper_time_left=time;
|
m_zipper_time_left=time;
|
||||||
}
|
}
|
||||||
void setCollectable (collectableType t, int n)
|
void setCollectable (CollectableType t, int n)
|
||||||
{ m_collectable.set(t, n); }
|
{ m_collectable.set(t, n); }
|
||||||
void setPosition (int p) {m_race_position = p; }
|
void setPosition (int p) {m_race_position = p; }
|
||||||
int getSector () { return m_track_sector; }
|
int getSector () { return m_track_sector; }
|
||||||
float getDistanceDownTrack() { return m_curr_track_coords[1]; }
|
float getDistanceDownTrack() { return m_curr_track_coords[1]; }
|
||||||
|
@ -42,7 +42,7 @@ public:
|
|||||||
const int getKartId (const std::string IDENT);
|
const int getKartId (const std::string IDENT);
|
||||||
void loadKartData (bool dont_load_models=false);
|
void loadKartData (bool dont_load_models=false);
|
||||||
const float getMaximumSteeringAngle() {return m_max_steer_angle;}
|
const float getMaximumSteeringAngle() {return m_max_steer_angle;}
|
||||||
const unsigned int getNumberOfKarts () {return m_karts_properties.size();}
|
const unsigned int getNumberOfKarts () {return (unsigned int)m_karts_properties.size();}
|
||||||
|
|
||||||
/** Return len random karts */
|
/** Return len random karts */
|
||||||
std::vector<std::string> getRandomKarts (int len);
|
std::vector<std::string> getRandomKarts (int len);
|
||||||
|
@ -32,10 +32,8 @@
|
|||||||
#include "plib/ul.h"
|
#include "plib/ul.h"
|
||||||
#include "loader.hpp"
|
#include "loader.hpp"
|
||||||
#include "world.hpp"
|
#include "world.hpp"
|
||||||
#ifdef BULLET
|
|
||||||
#include "btBulletDynamicsCommon.h"
|
#include "btBulletDynamicsCommon.h"
|
||||||
#include "moving_physics.hpp"
|
#include "moving_physics.hpp"
|
||||||
#endif
|
|
||||||
#include "moving_texture.hpp"
|
#include "moving_texture.hpp"
|
||||||
#include "translation.hpp"
|
#include "translation.hpp"
|
||||||
#include "material_manager.hpp"
|
#include "material_manager.hpp"
|
||||||
@ -361,20 +359,16 @@ ssgBranch *Loader::createBranch(char *data) const
|
|||||||
{
|
{
|
||||||
ssgTexTrans *br = new ssgTexTrans();
|
ssgTexTrans *br = new ssgTexTrans();
|
||||||
Callback *c = new MovingTexture(data, br);
|
Callback *c = new MovingTexture(data, br);
|
||||||
br->setUserData(new ssgBase());
|
|
||||||
br->setName("MovingTexture");
|
|
||||||
callback_manager->addCallback(c, m_current_callback_type);
|
callback_manager->addCallback(c, m_current_callback_type);
|
||||||
return br;
|
return br;
|
||||||
}
|
}
|
||||||
if(strncmp("physics", data, strlen("physics")) == 0)
|
if(strncmp("physics", data, strlen("physics")) == 0)
|
||||||
{
|
{
|
||||||
#ifdef BULLET
|
ssgTransform *tr = new ssgTransform();
|
||||||
MovingPhysics *mp = new MovingPhysics(std::string(data));
|
MovingPhysics *mp = new MovingPhysics(std::string(data), tr);
|
||||||
callback_manager->addCallback(mp, m_current_callback_type);
|
callback_manager->addCallback(mp, m_current_callback_type);
|
||||||
return mp;
|
|
||||||
#else
|
return tr;
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
fprintf(stderr, "Warning: Ignoring userdata '%s'\n", data);
|
fprintf(stderr, "Warning: Ignoring userdata '%s'\n", data);
|
||||||
return NULL ;
|
return NULL ;
|
||||||
|
@ -27,15 +27,13 @@
|
|||||||
|
|
||||||
Moveable::Moveable (bool bHasHistory)
|
Moveable::Moveable (bool bHasHistory)
|
||||||
{
|
{
|
||||||
#ifdef BULLET
|
m_body = 0;
|
||||||
m_body = 0;
|
m_motion_state = 0;
|
||||||
m_motion_state = 0;
|
m_shadow = 0;
|
||||||
#endif
|
m_first_time = true ;
|
||||||
m_shadow = 0;
|
m_model_transform = new ssgTransform();
|
||||||
m_first_time = true ;
|
|
||||||
m_model = new ssgTransform();
|
|
||||||
|
|
||||||
m_model->ref();
|
m_model_transform->ref();
|
||||||
|
|
||||||
sgZeroVec3 ( m_reset_pos.xyz ) ; sgZeroVec3 ( m_reset_pos.hpr ) ;
|
sgZeroVec3 ( m_reset_pos.xyz ) ; sgZeroVec3 ( m_reset_pos.hpr ) ;
|
||||||
|
|
||||||
@ -55,11 +53,9 @@ Moveable::Moveable (bool bHasHistory)
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
Moveable::~Moveable()
|
Moveable::~Moveable()
|
||||||
{
|
{
|
||||||
#ifdef BULLET
|
|
||||||
// The body is being removed from the world in kart/projectile
|
// The body is being removed from the world in kart/projectile
|
||||||
if(m_body) delete m_body;
|
if(m_body) delete m_body;
|
||||||
if(m_motion_state) delete m_motion_state;
|
if(m_motion_state) delete m_motion_state;
|
||||||
#endif
|
|
||||||
if(m_history_velocity)
|
if(m_history_velocity)
|
||||||
{
|
{
|
||||||
delete [] m_history_velocity;
|
delete [] m_history_velocity;
|
||||||
@ -71,9 +67,6 @@ Moveable::~Moveable()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void Moveable::reset ()
|
void Moveable::reset ()
|
||||||
{
|
{
|
||||||
#ifndef BULLET
|
|
||||||
m_on_ground = true;
|
|
||||||
#endif
|
|
||||||
m_collided = false;
|
m_collided = false;
|
||||||
m_crashed = false;
|
m_crashed = false;
|
||||||
m_material_hot = NULL;
|
m_material_hot = NULL;
|
||||||
@ -87,7 +80,6 @@ void Moveable::reset ()
|
|||||||
} // reset
|
} // reset
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
#ifdef BULLET
|
|
||||||
void Moveable::createBody(float mass, btTransform& trans,
|
void Moveable::createBody(float mass, btTransform& trans,
|
||||||
btCollisionShape *shape, MoveableType m) {
|
btCollisionShape *shape, MoveableType m) {
|
||||||
|
|
||||||
@ -102,7 +94,7 @@ void Moveable::createBody(float mass, btTransform& trans,
|
|||||||
m_body->setUserPointer(this);
|
m_body->setUserPointer(this);
|
||||||
setMoveableType(m);
|
setMoveableType(m);
|
||||||
} // createBody
|
} // createBody
|
||||||
#endif
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void Moveable::update (float dt)
|
void Moveable::update (float dt)
|
||||||
{
|
{
|
||||||
@ -140,7 +132,6 @@ void Moveable::update (float dt)
|
|||||||
sgVec3 start ; sgCopyVec3 (start, m_curr_pos.xyz );
|
sgVec3 start ; sgCopyVec3 (start, m_curr_pos.xyz );
|
||||||
sgVec3 end ; sgCopyVec3 (end , result[3] );
|
sgVec3 end ; sgCopyVec3 (end , result[3] );
|
||||||
|
|
||||||
const float HOT = collectIsectData(start, end );
|
|
||||||
|
|
||||||
sgCopyVec3 (result[3], end) ;
|
sgCopyVec3 (result[3], end) ;
|
||||||
|
|
||||||
@ -177,13 +168,7 @@ void Moveable::update (float dt)
|
|||||||
sgCopyCoord(&(m_history_position[history->GetCurrentIndex()]), &m_curr_pos);
|
sgCopyCoord(&(m_history_position[history->GetCurrentIndex()]), &m_curr_pos);
|
||||||
}
|
}
|
||||||
} // if m_history_position
|
} // if m_history_position
|
||||||
const float HAT = m_curr_pos.xyz[2]-HOT;
|
|
||||||
|
|
||||||
#ifndef BULLET
|
|
||||||
m_on_ground = ( HAT <= 0.01 );
|
|
||||||
doCollisionAnalysis(dt, HOT);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
placeModel () ;
|
placeModel () ;
|
||||||
|
|
||||||
m_first_time = false ;
|
m_first_time = false ;
|
||||||
@ -250,10 +235,6 @@ void Moveable::ReadHistory(char* s, int kartNumber, int indx)
|
|||||||
} // ReadHistory
|
} // ReadHistory
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
#ifndef BULLET
|
|
||||||
void Moveable::doCollisionAnalysis ( float,float ) { /* Empty by Default. */ }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ISECT_STEP_SIZE 0.4f
|
#define ISECT_STEP_SIZE 0.4f
|
||||||
#define COLLISION_SPHERE_RADIUS 0.6f
|
#define COLLISION_SPHERE_RADIUS 0.6f
|
||||||
|
|
||||||
@ -371,8 +352,7 @@ float Moveable::getIsectData ( sgVec3 start, sgVec3 end )
|
|||||||
m_material_hot = material_manager->getMaterial(m_leaf);
|
m_material_hot = material_manager->getMaterial(m_leaf);
|
||||||
// Only rescue the kart if it (nearly) touches the reset-material,
|
// Only rescue the kart if it (nearly) touches the reset-material,
|
||||||
// not only when it is above it. The condition for touching
|
// not only when it is above it. The condition for touching
|
||||||
// a material is coarser then for the m_on_ground condition
|
// a material is somewha coars, since the kart might have been falling
|
||||||
// (which tests for <0.01) - since the kart might have been falling
|
|
||||||
// for quite some time, it might be really fast, so I guess a somewhat
|
// for quite some time, it might be really fast, so I guess a somewhat
|
||||||
// coarser test is better for that case.
|
// coarser test is better for that case.
|
||||||
if(m_material_hot->isReset() &&
|
if(m_material_hot->isReset() &&
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
class Moveable
|
class Moveable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum MoveableType {MOV_KART, MOV_PROJECTILE} ;
|
enum MoveableType {MOV_KART, MOV_PROJECTILE, MOV_TRACK} ;
|
||||||
protected:
|
protected:
|
||||||
MoveableType m_moveable_type; /* used when upcasting bullet user pointers */
|
MoveableType m_moveable_type; /* used when upcasting bullet user pointers */
|
||||||
sgCoord m_reset_pos; /* Where to start in case of a reset */
|
sgCoord m_reset_pos; /* Where to start in case of a reset */
|
||||||
@ -50,15 +50,12 @@ protected:
|
|||||||
sgVec3 m_abs_velocity; /* world coordinates' velocity vector */
|
sgVec3 m_abs_velocity; /* world coordinates' velocity vector */
|
||||||
sgVec4* m_normal_hot; /* plane on which HOT was computed */
|
sgVec4* m_normal_hot; /* plane on which HOT was computed */
|
||||||
Material* m_material_hot; /* Material at HOT */
|
Material* m_material_hot; /* Material at HOT */
|
||||||
ssgTransform* m_model;
|
ssgTransform* m_model_transform; // The transform where the model is under
|
||||||
ssgTransform* m_shadow;
|
ssgTransform* m_shadow;
|
||||||
int m_collided;
|
int m_collided;
|
||||||
int m_crashed;
|
int m_crashed;
|
||||||
sgVec3 m_surface_avoidance_vector ;
|
sgVec3 m_surface_avoidance_vector ;
|
||||||
int m_first_time ;
|
int m_first_time ;
|
||||||
#ifndef BULLET
|
|
||||||
int m_on_ground ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
float collectIsectData ( sgVec3 start, sgVec3 end ) ;
|
float collectIsectData ( sgVec3 start, sgVec3 end ) ;
|
||||||
sgCoord* m_history_velocity;
|
sgCoord* m_history_velocity;
|
||||||
@ -76,10 +73,7 @@ public:
|
|||||||
Moveable (bool bHasHistory=false);
|
Moveable (bool bHasHistory=false);
|
||||||
virtual ~Moveable();
|
virtual ~Moveable();
|
||||||
|
|
||||||
ssgTransform* getModel () {return m_model ; }
|
ssgTransform* getModelTransform() {return m_model_transform; }
|
||||||
#ifndef BULLET
|
|
||||||
int isOnGround () {return m_on_ground; }
|
|
||||||
#endif
|
|
||||||
MoveableType getMoveableType() const {return m_moveable_type; }
|
MoveableType getMoveableType() const {return m_moveable_type; }
|
||||||
void setMoveableType(MoveableType m){m_moveable_type=m; }
|
void setMoveableType(MoveableType m){m_moveable_type=m; }
|
||||||
sgCoord* getVelocity () {return & m_velocity; }
|
sgCoord* getVelocity () {return & m_velocity; }
|
||||||
@ -87,7 +81,7 @@ public:
|
|||||||
const sgCoord* getCoord () const {return &m_curr_pos; }
|
const sgCoord* getCoord () const {return &m_curr_pos; }
|
||||||
const sgVec4* getNormalHOT () const {return m_normal_hot; }
|
const sgVec4* getNormalHOT () const {return m_normal_hot; }
|
||||||
void setCoord (sgCoord* pos) {sgCopyCoord ( &m_curr_pos,pos); }
|
void setCoord (sgCoord* pos) {sgCopyCoord ( &m_curr_pos,pos); }
|
||||||
virtual void placeModel () {m_model->setTransform(&m_curr_pos); }
|
virtual void placeModel () {m_model_transform->setTransform(&m_curr_pos); }
|
||||||
virtual void handleZipper () {};
|
virtual void handleZipper () {};
|
||||||
virtual void reset ();
|
virtual void reset ();
|
||||||
virtual void update (float dt) ;
|
virtual void update (float dt) ;
|
||||||
@ -104,14 +98,12 @@ public:
|
|||||||
float getIsectData (sgVec3 start, sgVec3 end );
|
float getIsectData (sgVec3 start, sgVec3 end );
|
||||||
void WriteHistory (char* s, int kartNumber, int indx);
|
void WriteHistory (char* s, int kartNumber, int indx);
|
||||||
void ReadHistory (char* s, int kartNumber, int indx);
|
void ReadHistory (char* s, int kartNumber, int indx);
|
||||||
#ifdef BULLET
|
|
||||||
btRigidBody* getBody () const {return m_body; }
|
btRigidBody* getBody () const {return m_body; }
|
||||||
void createBody(float mass, btTransform& trans,
|
void createBody(float mass, btTransform& trans,
|
||||||
btCollisionShape *shape, MoveableType m);
|
btCollisionShape *shape, MoveableType m);
|
||||||
void getTrans (btTransform* t) const
|
void getTrans (btTransform* t) const
|
||||||
{m_motion_state->getWorldTransform(*t);}
|
{m_motion_state->getWorldTransform(*t);}
|
||||||
void setTrans (btTransform& t){m_motion_state->setWorldTransform(t);}
|
void setTrans (btTransform& t){m_motion_state->setWorldTransform(t);}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
; // class Moveable
|
; // class Moveable
|
||||||
|
|
||||||
|
@ -26,17 +26,16 @@
|
|||||||
#include "ssg_help.hpp"
|
#include "ssg_help.hpp"
|
||||||
#include "scene.hpp"
|
#include "scene.hpp"
|
||||||
|
|
||||||
#ifdef BULLET
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
MovingPhysics::MovingPhysics(const std::string data)
|
MovingPhysics::MovingPhysics(const std::string data, ssgTransform* trans)
|
||||||
: ssgTransform(), Callback()
|
: Callback()
|
||||||
{
|
{
|
||||||
|
m_trans = trans;
|
||||||
m_shape = NULL;
|
m_shape = NULL;
|
||||||
m_body = NULL;
|
m_body = NULL;
|
||||||
m_motion_state = NULL;
|
m_motion_state = NULL;
|
||||||
m_mass = 1;
|
m_mass = 1;
|
||||||
setUserData(new ssgBase());
|
m_trans->setUserData(new ssgBase()); // prevent tree optimisations to remove this node
|
||||||
ref();
|
|
||||||
|
|
||||||
std::vector<std::string> parameters = StringUtils::split(data, ' ');
|
std::vector<std::string> parameters = StringUtils::split(data, ' ');
|
||||||
if(parameters.size()<2)
|
if(parameters.size()<2)
|
||||||
@ -81,8 +80,8 @@ MovingPhysics::MovingPhysics(const std::string data)
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
MovingPhysics::~MovingPhysics()
|
MovingPhysics::~MovingPhysics()
|
||||||
{
|
{
|
||||||
world->getPhysics()->getPhysicsWorld()->removeRigidBody(m_body);
|
scene->remove(m_trans);
|
||||||
deRef();
|
world->getPhysics()->removeBody(m_body);
|
||||||
delete m_shape;
|
delete m_shape;
|
||||||
delete m_motion_state;
|
delete m_motion_state;
|
||||||
delete m_body;
|
delete m_body;
|
||||||
@ -104,15 +103,15 @@ void MovingPhysics::init()
|
|||||||
|
|
||||||
// 1. Remove the object from the graph and attach it to the root
|
// 1. Remove the object from the graph and attach it to the root
|
||||||
// -------------------------------------------------------------
|
// -------------------------------------------------------------
|
||||||
if(getNumParents()>1)
|
if(m_trans->getNumParents()>1)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "WARNING: physical object with more than one parent!!\n");
|
fprintf(stderr, "WARNING: physical object with more than one parent!!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ssgBranch *parent = getParent(0);
|
ssgBranch *parent = m_trans->getParent(0);
|
||||||
|
|
||||||
parent->removeKid(this);
|
scene->add(m_trans);
|
||||||
scene->add(this);
|
parent->removeKid(m_trans);
|
||||||
|
|
||||||
// 2. Determine the original position of the object
|
// 2. Determine the original position of the object
|
||||||
// ------------------------------------------------
|
// ------------------------------------------------
|
||||||
@ -161,18 +160,18 @@ void MovingPhysics::init()
|
|||||||
// 3. Determine size of the object
|
// 3. Determine size of the object
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
float x_min, x_max, y_min, y_max, z_min, z_max, radius;
|
float x_min, x_max, y_min, y_max, z_min, z_max, radius;
|
||||||
MinMax(this, &x_min, &x_max, &y_min, &y_max, &z_min, &z_max);
|
MinMax(m_trans, &x_min, &x_max, &y_min, &y_max, &z_min, &z_max);
|
||||||
m_half_height = 0.5f*(z_max-z_min);
|
m_half_height = 0.5f*(z_max-z_min);
|
||||||
switch (m_body_type)
|
switch (m_body_type)
|
||||||
{
|
{
|
||||||
case BODY_CONE: radius = 0.5f*std::max(x_max-x_min, y_max-y_min);
|
case BODY_CONE: radius = 0.5f*std::max(x_max-x_min, y_max-y_min);
|
||||||
m_shape = new btConeShape(radius, z_max-z_min);
|
m_shape = new btConeShape(radius, z_max-z_min);
|
||||||
setName("cone");
|
m_trans->setName("cone");
|
||||||
break;
|
break;
|
||||||
case BODY_BOX: m_shape = new btBoxShape(btVector3(0.5f*(x_max-x_min),
|
case BODY_BOX: m_shape = new btBoxShape(btVector3(0.5f*(x_max-x_min),
|
||||||
0.5f*(y_max-y_min),
|
0.5f*(y_max-y_min),
|
||||||
0.5f*(z_max-z_min) ) );
|
0.5f*(z_max-z_min) ) );
|
||||||
setName("box");
|
m_trans->setName("box");
|
||||||
break;
|
break;
|
||||||
case BODY_NONE: fprintf(stderr, "WARNING: Uninitialised moving shape\n");
|
case BODY_NONE: fprintf(stderr, "WARNING: Uninitialised moving shape\n");
|
||||||
break;
|
break;
|
||||||
@ -204,10 +203,9 @@ void MovingPhysics::update(float dt)
|
|||||||
// Transfer the new position and hpr to m_curr_pos
|
// Transfer the new position and hpr to m_curr_pos
|
||||||
sgCoord m_curr_pos;
|
sgCoord m_curr_pos;
|
||||||
sgSetCoord(&m_curr_pos, m);
|
sgSetCoord(&m_curr_pos, m);
|
||||||
setTransform(&m_curr_pos);
|
m_trans->setTransform(&m_curr_pos);
|
||||||
} // update
|
} // update
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
#endif
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
||||||
|
@ -24,20 +24,21 @@
|
|||||||
#include "btBulletDynamicsCommon.h"
|
#include "btBulletDynamicsCommon.h"
|
||||||
#include "callback.hpp"
|
#include "callback.hpp"
|
||||||
|
|
||||||
class MovingPhysics : public ssgTransform, public Callback
|
class MovingPhysics : public Callback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum bodyTypes {BODY_NONE, BODY_CONE, BODY_BOX};
|
enum bodyTypes {BODY_NONE, BODY_CONE, BODY_BOX};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bodyTypes m_body_type;
|
bodyTypes m_body_type;
|
||||||
|
ssgTransform *m_trans;
|
||||||
btCollisionShape *m_shape;
|
btCollisionShape *m_shape;
|
||||||
btRigidBody *m_body;
|
btRigidBody *m_body;
|
||||||
btDefaultMotionState *m_motion_state;
|
btDefaultMotionState *m_motion_state;
|
||||||
float m_half_height;
|
float m_half_height;
|
||||||
float m_mass;
|
float m_mass;
|
||||||
public:
|
public:
|
||||||
MovingPhysics (const std::string data);
|
MovingPhysics (const std::string data, ssgTransform *trans);
|
||||||
~MovingPhysics ();
|
~MovingPhysics ();
|
||||||
void update (float dt);
|
void update (float dt);
|
||||||
void init ();
|
void init ();
|
||||||
|
@ -26,6 +26,9 @@
|
|||||||
MovingTexture::MovingTexture(char *data, ssgBranch *branch)
|
MovingTexture::MovingTexture(char *data, ssgBranch *branch)
|
||||||
{
|
{
|
||||||
m_branch = branch;
|
m_branch = branch;
|
||||||
|
branch->setUserData(new ssgBase());
|
||||||
|
branch->setName("MovingTexture");
|
||||||
|
|
||||||
m_branch->ref();
|
m_branch->ref();
|
||||||
m_phase = 0.0f;
|
m_phase = 0.0f;
|
||||||
m_mode = MODE_FORWARD;
|
m_mode = MODE_FORWARD;
|
||||||
|
197
src/physics.cpp
197
src/physics.cpp
@ -25,7 +25,7 @@
|
|||||||
#include "physics.hpp"
|
#include "physics.hpp"
|
||||||
#include "ssg_help.hpp"
|
#include "ssg_help.hpp"
|
||||||
#include "world.hpp"
|
#include "world.hpp"
|
||||||
#include "projectile.hpp"
|
#include "flyable.hpp"
|
||||||
|
|
||||||
#include "moving_physics.hpp"
|
#include "moving_physics.hpp"
|
||||||
#include "user_config.hpp"
|
#include "user_config.hpp"
|
||||||
@ -34,22 +34,19 @@
|
|||||||
|
|
||||||
/** Initialise physics. */
|
/** Initialise physics. */
|
||||||
|
|
||||||
float Physics::NOHIT=-99999.9f;
|
float const Physics::NOHIT=-99999.9f;
|
||||||
|
|
||||||
Physics::Physics(float gravity)
|
Physics::Physics(float gravity) : btSequentialImpulseConstraintSolver()
|
||||||
{
|
{
|
||||||
|
|
||||||
m_collision_conf = new btDefaultCollisionConfiguration();
|
m_collision_conf = new btDefaultCollisionConfiguration();
|
||||||
m_dispatcher = new btCollisionDispatcher(m_collision_conf);
|
m_dispatcher = new btCollisionDispatcher(m_collision_conf);
|
||||||
|
|
||||||
btVector3 worldMin(-1000, -1000, -1000);
|
btVector3 worldMin(-1000, -1000, -1000);
|
||||||
btVector3 worldMax( 1000, 1000, 1000);
|
btVector3 worldMax( 1000, 1000, 1000);
|
||||||
m_axis_sweep = new btAxisSweep3(worldMin, worldMax);
|
m_axis_sweep = new btAxisSweep3(worldMin, worldMax);
|
||||||
|
|
||||||
m_constraint_solver = new btSequentialImpulseConstraintSolver();
|
|
||||||
m_dynamics_world = new btDiscreteDynamicsWorld(m_dispatcher,
|
m_dynamics_world = new btDiscreteDynamicsWorld(m_dispatcher,
|
||||||
m_axis_sweep,
|
m_axis_sweep,
|
||||||
m_constraint_solver,
|
this,
|
||||||
m_collision_conf);
|
m_collision_conf);
|
||||||
m_dynamics_world->setGravity(btVector3(0.0f, 0.0f, -gravity));
|
m_dynamics_world->setGravity(btVector3(0.0f, 0.0f, -gravity));
|
||||||
if(user_config->m_bullet_debug)
|
if(user_config->m_bullet_debug)
|
||||||
@ -63,12 +60,11 @@ Physics::Physics(float gravity)
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
Physics::~Physics()
|
Physics::~Physics()
|
||||||
{
|
{
|
||||||
delete m_dispatcher;
|
if(user_config->m_bullet_debug) delete m_debug_drawer;
|
||||||
delete m_dynamics_world;
|
delete m_dynamics_world;
|
||||||
delete m_axis_sweep;
|
delete m_axis_sweep;
|
||||||
|
delete m_dispatcher;
|
||||||
delete m_collision_conf;
|
delete m_collision_conf;
|
||||||
delete m_constraint_solver;
|
|
||||||
if(user_config->m_bullet_debug) delete m_debug_drawer;
|
|
||||||
|
|
||||||
} // ~Physics
|
} // ~Physics
|
||||||
|
|
||||||
@ -178,21 +174,112 @@ void Physics::removeKart(const Kart *kart)
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void Physics::update(float dt)
|
void Physics::update(float dt)
|
||||||
{
|
{
|
||||||
|
// Bullet can report the same collision more than once (up to 4
|
||||||
|
// contact points per collision. Additionally, more than one internal
|
||||||
|
// substep might be taken, resulting in potentially even more
|
||||||
|
// duplicates. To handle this, all collisions (i.e. pair of objects)
|
||||||
|
// are stored in a vector, but only one entry per collision pair
|
||||||
|
// of objects.
|
||||||
|
m_all_collisions.clear();
|
||||||
m_dynamics_world->stepSimulation(dt);
|
m_dynamics_world->stepSimulation(dt);
|
||||||
// ??? m_dynamicsWorld->updateAabbs();
|
|
||||||
handleCollisions();
|
// Now handle the actual collision. Note: rockets can not be removed
|
||||||
|
// inside of this loop, since the same rocket might hit more than one
|
||||||
|
// other object. So, only a flag is set in the rockets, the actual
|
||||||
|
// clean up is then done later in the projectile manager.
|
||||||
|
std::vector<CollisionPair>::iterator p;
|
||||||
|
for(p=m_all_collisions.begin(); p!=m_all_collisions.end(); ++p)
|
||||||
|
{
|
||||||
|
if(p->type_a==Moveable::MOV_KART) { // kart-kart collision
|
||||||
|
Kart *kartA = (Kart*)(p->a);
|
||||||
|
Kart *kartB = (Kart*)(p->b);
|
||||||
|
KartKartCollision(kartA, kartB);
|
||||||
|
} // if kart-kart collision
|
||||||
|
else // now the first object must be a projectile
|
||||||
|
{
|
||||||
|
if(p->type_b==Moveable::MOV_TRACK) // must be projectile hit track
|
||||||
|
{
|
||||||
|
((Flyable*)(p->a))->hitTrack();
|
||||||
|
}
|
||||||
|
else if(p->type_b==Moveable::MOV_KART) // projectile hit kart
|
||||||
|
{
|
||||||
|
Flyable *f=(Flyable*)(p->a);
|
||||||
|
f->explode((Kart*)(p->b));
|
||||||
|
}
|
||||||
|
else // projectile hits projectile
|
||||||
|
{
|
||||||
|
((Flyable*)(p->a))->explode(NULL);
|
||||||
|
((Flyable*)(p->b))->explode(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // for all p in m_all_collisions
|
||||||
} // update
|
} // update
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void Physics::handleCollisions() {
|
/** Handles the special case of two karts colliding with each other
|
||||||
int numManifolds = m_dispatcher->getNumManifolds();
|
* If both karts have a bomb, they'll explode immediately
|
||||||
for(int i=0; i<numManifolds; i++)
|
*/
|
||||||
|
void Physics::KartKartCollision(Kart *kartA, Kart *kartB)
|
||||||
|
{
|
||||||
|
Attachment *attachmentA=kartA->getAttachment();
|
||||||
|
Attachment *attachmentB=kartB->getAttachment();
|
||||||
|
|
||||||
|
if(attachmentA->getType()==ATTACH_BOMB)
|
||||||
|
{
|
||||||
|
// If both karts have a bomb, explode them immediately:
|
||||||
|
if(attachmentB->getType()==ATTACH_BOMB)
|
||||||
|
{
|
||||||
|
attachmentA->setTimeLeft(0.0f);
|
||||||
|
attachmentB->setTimeLeft(0.0f);
|
||||||
|
}
|
||||||
|
else // only A has a bomb, move it to B (unless it was from B)
|
||||||
|
{
|
||||||
|
if(attachmentA->getPreviousOwner()!=kartB)
|
||||||
|
{
|
||||||
|
attachmentA->moveBombFromTo(kartA, kartB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(attachmentB->getType()==ATTACH_BOMB &&
|
||||||
|
attachmentB->getPreviousOwner()!=kartA)
|
||||||
|
{
|
||||||
|
attachmentB->moveBombFromTo(kartB, kartA);
|
||||||
|
}
|
||||||
|
if(kartA->isPlayerKart()) sound_manager->playSfx(SOUND_CRASH);
|
||||||
|
if(kartB->isPlayerKart()) sound_manager->playSfx(SOUND_CRASH);
|
||||||
|
|
||||||
|
} // KartKartCollision
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** This function is called at each internal bullet timestep. It is used
|
||||||
|
* here to do the collision handling: using the contact manifolds after a
|
||||||
|
* physics time step might miss some collisions (when more than one internal
|
||||||
|
* time step was done, and the collision is added and removed).
|
||||||
|
**/
|
||||||
|
btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies,
|
||||||
|
btPersistentManifold** manifold,int numManifolds,
|
||||||
|
btTypedConstraint** constraints,int numConstraints,
|
||||||
|
const btContactSolverInfo& info,
|
||||||
|
btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,
|
||||||
|
btDispatcher* dispatcher) {
|
||||||
|
btScalar returnValue=
|
||||||
|
btSequentialImpulseConstraintSolver::solveGroup(bodies, numBodies, manifold,
|
||||||
|
numManifolds, constraints,
|
||||||
|
numConstraints, info,
|
||||||
|
debugDrawer, stackAlloc,
|
||||||
|
dispatcher);
|
||||||
|
int currentNumManifolds = m_dispatcher->getNumManifolds();
|
||||||
|
// We can't explode a rocket in a loop, since a rocket might collide with
|
||||||
|
// more than one object, and/or more than once with each object (if there
|
||||||
|
// is more than one collision point). So keep a list of rockets that will
|
||||||
|
// be exploded after the collisions
|
||||||
|
std::vector<Moveable*> rocketsToExplode;
|
||||||
|
for(int i=0; i<currentNumManifolds; i++)
|
||||||
{
|
{
|
||||||
btPersistentManifold* contactManifold = m_dynamics_world->getDispatcher()->getManifoldByIndexInternal(i);
|
btPersistentManifold* contactManifold = m_dynamics_world->getDispatcher()->getManifoldByIndexInternal(i);
|
||||||
|
|
||||||
btCollisionObject* objA = static_cast<btCollisionObject*>(contactManifold->getBody0());
|
btCollisionObject* objA = static_cast<btCollisionObject*>(contactManifold->getBody0());
|
||||||
btCollisionObject* objB = static_cast<btCollisionObject*>(contactManifold->getBody1());
|
btCollisionObject* objB = static_cast<btCollisionObject*>(contactManifold->getBody1());
|
||||||
contactManifold->refreshContactPoints(objA->getWorldTransform(),objB->getWorldTransform());
|
|
||||||
|
|
||||||
int numContacts = contactManifold->getNumContacts();
|
int numContacts = contactManifold->getNumContacts();
|
||||||
if(!numContacts) continue; // no real collision
|
if(!numContacts) continue; // no real collision
|
||||||
@ -200,63 +287,35 @@ void Physics::handleCollisions() {
|
|||||||
Moveable *movA = static_cast<Moveable*>(objA->getUserPointer());
|
Moveable *movA = static_cast<Moveable*>(objA->getUserPointer());
|
||||||
Moveable *movB = static_cast<Moveable*>(objB->getUserPointer());
|
Moveable *movB = static_cast<Moveable*>(objB->getUserPointer());
|
||||||
|
|
||||||
|
if(!numContacts) continue; // no real collision
|
||||||
|
|
||||||
// 1) object A is a track
|
// 1) object A is a track
|
||||||
// =======================
|
// =======================
|
||||||
if(!movA)
|
if(!movA)
|
||||||
{
|
{
|
||||||
if(!movB)
|
if(movB && movB->getMoveableType()==Moveable::MOV_PROJECTILE)
|
||||||
{ // 1.1) track hits track ??
|
{ // 1.1 projectile hits track
|
||||||
// ------------------------
|
|
||||||
continue; // --> ignore
|
|
||||||
}
|
|
||||||
else if(movB->getMoveableType()==Moveable::MOV_PROJECTILE)
|
|
||||||
{ // 1.2 projectile hits track
|
|
||||||
// -------------------------
|
// -------------------------
|
||||||
Projectile *p=(Projectile*)movB;
|
m_all_collisions.push_back(CollisionPair(movB, Moveable::MOV_PROJECTILE,
|
||||||
p->explode(NULL); // explode on track
|
NULL, Moveable::MOV_TRACK ));
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // 1.3 kart hits track
|
|
||||||
// -------------------
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 2) object a is a kart
|
// 2) object a is a kart
|
||||||
// =====================
|
// =====================
|
||||||
else if(movA->getMoveableType()==Moveable::MOV_KART)
|
else if(movA->getMoveableType()==Moveable::MOV_KART)
|
||||||
{
|
{
|
||||||
if(!movB)
|
if(movB && movB->getMoveableType()==Moveable::MOV_PROJECTILE)
|
||||||
{ // 2.1) kart hits track
|
{ // 2.1 projectile hits kart
|
||||||
// --------------------
|
|
||||||
continue; // --> ignore
|
|
||||||
}
|
|
||||||
else if(movB->getMoveableType()==Moveable::MOV_PROJECTILE)
|
|
||||||
{ // 2.2 projectile hits kart
|
|
||||||
// -------------------------
|
// -------------------------
|
||||||
Projectile *p=(Projectile*)movB;
|
m_all_collisions.push_back(CollisionPair(movB, Moveable::MOV_PROJECTILE,
|
||||||
p->explode((Kart*)movA);
|
movA, Moveable::MOV_KART ));
|
||||||
}
|
}
|
||||||
else if(movB->getMoveableType()==Moveable::MOV_KART)
|
else if(movB && movB->getMoveableType()==Moveable::MOV_KART)
|
||||||
{ // 2.3 kart hits kart
|
{ // 2.2 kart hits kart
|
||||||
// ------------------
|
// ------------------
|
||||||
Kart *kartA = (Kart*)movA;
|
m_all_collisions.push_back(CollisionPair(movA, Moveable::MOV_KART,
|
||||||
Kart *kartB = (Kart*)movB;
|
movB, Moveable::MOV_KART ));
|
||||||
|
|
||||||
// First check for bomb attachments
|
|
||||||
Attachment *attachmentA=kartA->getAttachment();
|
|
||||||
if(attachmentA->getType()==ATTACH_BOMB &&
|
|
||||||
attachmentA->getPreviousOwner()!=kartB)
|
|
||||||
{
|
|
||||||
attachmentA->moveBombFromTo(kartA, kartB);
|
|
||||||
}
|
|
||||||
Attachment *attachmentB=kartB->getAttachment();
|
|
||||||
if(attachmentB->getType()==ATTACH_BOMB &&
|
|
||||||
attachmentB->getPreviousOwner()!=kartA)
|
|
||||||
{
|
|
||||||
attachmentB->moveBombFromTo(kartB, kartA);
|
|
||||||
}
|
|
||||||
if(kartA->isPlayerKart()) sound_manager->playSfx(SOUND_CRASH);
|
|
||||||
if(kartB->isPlayerKart()) sound_manager->playSfx(SOUND_CRASH);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 3) object is a projectile
|
// 3) object is a projectile
|
||||||
@ -266,19 +325,20 @@ void Physics::handleCollisions() {
|
|||||||
if(!movB)
|
if(!movB)
|
||||||
{ // 3.1) projectile hits track
|
{ // 3.1) projectile hits track
|
||||||
// --------------------------
|
// --------------------------
|
||||||
((Projectile*)movA)->explode(NULL);
|
m_all_collisions.push_back(CollisionPair(movA, Moveable::MOV_PROJECTILE,
|
||||||
|
NULL, Moveable::MOV_TRACK ));
|
||||||
}
|
}
|
||||||
else if(movB->getMoveableType()==Moveable::MOV_PROJECTILE)
|
else if(movB->getMoveableType()==Moveable::MOV_PROJECTILE)
|
||||||
{ // 3.2 projectile hits projectile
|
{ // 3.2 projectile hits projectile
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
((Projectile*)movA)->explode(NULL);
|
m_all_collisions.push_back(CollisionPair(movA, Moveable::MOV_PROJECTILE,
|
||||||
((Projectile*)movB)->explode(NULL);
|
movB, Moveable::MOV_PROJECTILE));
|
||||||
}
|
}
|
||||||
else if(movB->getMoveableType()==Moveable::MOV_KART)
|
else if(movB->getMoveableType()==Moveable::MOV_KART)
|
||||||
{ // 3.3 projectile hits kart
|
{ // 3.3 projectile hits kart
|
||||||
// ------------------------
|
// ------------------------
|
||||||
Projectile *p=(Projectile*)movA;
|
m_all_collisions.push_back(CollisionPair(movA, Moveable::MOV_PROJECTILE,
|
||||||
p->explode((Kart*)movB);
|
movB, Moveable::MOV_KART ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 4) Nothing else should happen
|
// 4) Nothing else should happen
|
||||||
@ -288,7 +348,9 @@ void Physics::handleCollisions() {
|
|||||||
assert("Unknown user pointer");
|
assert("Unknown user pointer");
|
||||||
}
|
}
|
||||||
} // for i<numManifolds
|
} // for i<numManifolds
|
||||||
} // handleCollisions
|
|
||||||
|
return returnValue;
|
||||||
|
} // solveGroup
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
float Physics::getHAT(btVector3 pos)
|
float Physics::getHAT(btVector3 pos)
|
||||||
@ -300,8 +362,9 @@ float Physics::getHAT(btVector3 pos)
|
|||||||
|
|
||||||
m_dynamics_world->rayTest(pos, to_pos, rayCallback);
|
m_dynamics_world->rayTest(pos, to_pos, rayCallback);
|
||||||
if(!rayCallback.HasHit()) return NOHIT;
|
if(!rayCallback.HasHit()) return NOHIT;
|
||||||
return rayCallback.m_hitPointWorld.getZ() - pos.getZ();
|
|
||||||
} // getHOT
|
return pos.getZ()-rayCallback.m_hitPointWorld.getZ();
|
||||||
|
} // getHAT
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
bool Physics::getTerrainNormal(btVector3 pos, btVector3* normal)
|
bool Physics::getTerrainNormal(btVector3 pos, btVector3* normal)
|
||||||
{
|
{
|
||||||
|
@ -21,24 +21,71 @@
|
|||||||
#define HEADER_PHYSICS_H
|
#define HEADER_PHYSICS_H
|
||||||
|
|
||||||
#include "kart.hpp"
|
#include "kart.hpp"
|
||||||
|
#include "flyable.hpp"
|
||||||
#include <plib/sg.h>
|
#include <plib/sg.h>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#ifdef BULLET
|
|
||||||
#include "btBulletDynamicsCommon.h"
|
#include "btBulletDynamicsCommon.h"
|
||||||
#include "bullet/Demos/OpenGL/GLDebugDrawer.h"
|
#include "bullet/Demos/OpenGL/GLDebugDrawer.h"
|
||||||
class Physics
|
class Physics : public btSequentialImpulseConstraintSolver
|
||||||
{
|
{
|
||||||
protected:
|
private:
|
||||||
btDynamicsWorld *m_dynamics_world;
|
btDynamicsWorld *m_dynamics_world;
|
||||||
Kart *m_kart;
|
Kart *m_kart;
|
||||||
GLDebugDrawer *m_debug_drawer;
|
GLDebugDrawer *m_debug_drawer;
|
||||||
btCollisionDispatcher *m_dispatcher;
|
btCollisionDispatcher *m_dispatcher;
|
||||||
btBroadphaseInterface *m_axis_sweep;
|
btBroadphaseInterface *m_axis_sweep;
|
||||||
btDefaultCollisionConfiguration *m_collision_conf;
|
btDefaultCollisionConfiguration *m_collision_conf;
|
||||||
btConstraintSolver *m_constraint_solver;
|
|
||||||
|
|
||||||
void convertTrack(ssgEntity *track, sgMat4 m, btTriangleMesh* track_mesh);
|
// Bullet can report the same collision more than once (up to 4
|
||||||
|
// contact points per collision. Additionally, more than one internal
|
||||||
|
// substep might be taken, resulting in potentially even more
|
||||||
|
// duplicates. To handle this, all collisions (i.e. pair of objects)
|
||||||
|
// are stored in a vector, but only one entry per collision pair
|
||||||
|
// of objects.
|
||||||
|
// While this is a natural application of std::set, the set has some
|
||||||
|
// overhead (since it will likely use a tree to sort the entries).
|
||||||
|
// Considering that the number of collisions is usually rather small
|
||||||
|
// a simple list and linear search is being used here.
|
||||||
|
|
||||||
|
class CollisionPair {
|
||||||
|
public:
|
||||||
|
void *a, *b;
|
||||||
|
Moveable::MoveableType type_a, type_b;
|
||||||
|
// The entries in Collision Pairs are sorted: if a projectile
|
||||||
|
// is included, it's always 'a'. If only two karts are reported
|
||||||
|
// the first kart pointer is the smaller one
|
||||||
|
CollisionPair(void *a1, Moveable::MoveableType atype,
|
||||||
|
void *b1, Moveable::MoveableType btype) {
|
||||||
|
if(atype==Moveable::MOV_KART && btype==Moveable::MOV_KART && a1>b1) {
|
||||||
|
a=b1;b=a1; type_a=btype; type_b=atype;
|
||||||
|
} else {
|
||||||
|
a=a1; b=b1; type_a=atype; type_b=btype;
|
||||||
|
}
|
||||||
|
}; // CollisionPair
|
||||||
|
bool operator==(const CollisionPair p) {
|
||||||
|
return (p.a==a && p.b==b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// This class is the list of collision objects, where each collision
|
||||||
|
// pair is stored as most once.
|
||||||
|
class CollisionList : public std::vector<CollisionPair> {
|
||||||
|
public:
|
||||||
|
void push_back(CollisionPair p) {
|
||||||
|
// only add a pair if it's not already in there
|
||||||
|
for(iterator i=begin(); i!=end(); i++) {
|
||||||
|
if((*i)==p) return;
|
||||||
|
}
|
||||||
|
std::vector<CollisionPair>::push_back(p);
|
||||||
|
}; // push_back
|
||||||
|
};
|
||||||
|
|
||||||
|
CollisionList m_all_collisions;
|
||||||
|
void KartKartCollision(Kart *ka, Kart *kb);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void convertTrack (ssgEntity *track, sgMat4 m, btTriangleMesh* track_mesh);
|
||||||
Physics (float gravity);
|
Physics (float gravity);
|
||||||
~Physics ();
|
~Physics ();
|
||||||
void addKart (const Kart *k, btRaycastVehicle *v);
|
void addKart (const Kart *k, btRaycastVehicle *v);
|
||||||
@ -46,30 +93,21 @@ public:
|
|||||||
void removeKart (const Kart *k);
|
void removeKart (const Kart *k);
|
||||||
void removeBody (btRigidBody* b) {m_dynamics_world->removeRigidBody(b);}
|
void removeBody (btRigidBody* b) {m_dynamics_world->removeRigidBody(b);}
|
||||||
void update (float dt);
|
void update (float dt);
|
||||||
void handleCollisions();
|
|
||||||
void draw ();
|
void draw ();
|
||||||
void setTrack (ssgEntity *track);
|
void setTrack (ssgEntity *track);
|
||||||
btDynamicsWorld*
|
btDynamicsWorld*
|
||||||
getPhysicsWorld () const {return m_dynamics_world;}
|
getPhysicsWorld () const {return m_dynamics_world;}
|
||||||
void debugDraw (float m[16], btCollisionShape *s, const btVector3 color);
|
void debugDraw (float m[16], btCollisionShape *s, const btVector3 color);
|
||||||
static float NOHIT;
|
static const float NOHIT;
|
||||||
float getHAT (btVector3 pos);
|
float getHAT (btVector3 pos);
|
||||||
bool getTerrainNormal(btVector3 pos, btVector3* normal);
|
bool getTerrainNormal(btVector3 pos, btVector3* normal);
|
||||||
|
virtual btScalar solveGroup(btCollisionObject** bodies, int numBodies,
|
||||||
|
btPersistentManifold** manifold,int numManifolds,
|
||||||
|
btTypedConstraint** constraints,int numConstraints,
|
||||||
|
const btContactSolverInfo& info,
|
||||||
|
btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,
|
||||||
|
btDispatcher* dispatcher);
|
||||||
};
|
};
|
||||||
// For non-bullet version: empty object
|
|
||||||
#else
|
|
||||||
class Physics
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Physics(float gravity) {};
|
|
||||||
~Physics() {};
|
|
||||||
void update(float dt) {};
|
|
||||||
void setTrack(ssgEntity *track) {};
|
|
||||||
void draw () {};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ void PlayerKart::update(float dt)
|
|||||||
m_collectable.use() ;
|
m_collectable.use() ;
|
||||||
m_controls.fire = false;
|
m_controls.fire = false;
|
||||||
}
|
}
|
||||||
if ( isOnGround() && m_controls.rescue )
|
if ( m_controls.rescue )
|
||||||
{
|
{
|
||||||
sound_manager -> playSfx ( SOUND_BEEP ) ;
|
sound_manager -> playSfx ( SOUND_BEEP ) ;
|
||||||
forceRescue();
|
forceRescue();
|
||||||
|
@ -19,7 +19,9 @@
|
|||||||
|
|
||||||
#include "loader.hpp"
|
#include "loader.hpp"
|
||||||
#include "projectile_manager.hpp"
|
#include "projectile_manager.hpp"
|
||||||
#include "projectile.hpp"
|
#include "spark.hpp"
|
||||||
|
#include "missile.hpp"
|
||||||
|
#include "homing.hpp"
|
||||||
#include "explosion.hpp"
|
#include "explosion.hpp"
|
||||||
#include "collectable_manager.hpp"
|
#include "collectable_manager.hpp"
|
||||||
#include "collectable.hpp"
|
#include "collectable.hpp"
|
||||||
@ -50,7 +52,7 @@ void ProjectileManager::removeTextures()
|
|||||||
{
|
{
|
||||||
cleanup();
|
cleanup();
|
||||||
ssgDeRefDelete(m_explosion_model);
|
ssgDeRefDelete(m_explosion_model);
|
||||||
// Only the explosion is here, all other models are actualy managed
|
// Only the explosion is here, all other models are actually managed
|
||||||
// by collectable_manager.
|
// by collectable_manager.
|
||||||
callback_manager->clear(CB_EXPLOSION);
|
callback_manager->clear(CB_EXPLOSION);
|
||||||
} // removeTextures
|
} // removeTextures
|
||||||
@ -61,7 +63,7 @@ void ProjectileManager::cleanup()
|
|||||||
for(Projectiles::iterator i = m_active_projectiles.begin();
|
for(Projectiles::iterator i = m_active_projectiles.begin();
|
||||||
i != m_active_projectiles.end(); ++i)
|
i != m_active_projectiles.end(); ++i)
|
||||||
{
|
{
|
||||||
ssgTransform *m = (*i)->getModel();
|
ssgTransform *m = (*i)->getModelTransform();
|
||||||
m->removeAllKids();
|
m->removeAllKids();
|
||||||
delete *i;
|
delete *i;
|
||||||
}
|
}
|
||||||
@ -93,12 +95,10 @@ void ProjectileManager::update(float dt)
|
|||||||
{
|
{
|
||||||
if(! (*p)->hasHit()) { p++; continue; }
|
if(! (*p)->hasHit()) { p++; continue; }
|
||||||
newExplosion((*p)->getCoord());
|
newExplosion((*p)->getCoord());
|
||||||
// Create a new explosion, move the projectile to the
|
Flyable *f=*p;
|
||||||
// list of deleted projectiles (so that they can be
|
Projectiles::iterator pNext=m_active_projectiles.erase(p); // returns the next element
|
||||||
// reused later), and remove it from the list of active
|
delete f;
|
||||||
// projectiles.
|
p=pNext;
|
||||||
m_deleted_projectiles.push_back(*p);
|
|
||||||
p=m_active_projectiles.erase(p); // returns the next element
|
|
||||||
} // while p!=m_active_projectiles.end()
|
} // while p!=m_active_projectiles.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,32 +115,27 @@ void ProjectileManager::update(float dt)
|
|||||||
while(e!=m_active_explosions.end())
|
while(e!=m_active_explosions.end())
|
||||||
{
|
{
|
||||||
if(!(*e)->hasEnded()) { e++; continue;}
|
if(!(*e)->hasEnded()) { e++; continue;}
|
||||||
m_deleted_explosions.push_back(*e);
|
Explosion *exp=*e;
|
||||||
e=m_active_explosions.erase(e);
|
Explosions::iterator eNext=m_active_explosions.erase(e);
|
||||||
|
ssgDeRefDelete(exp); // reduce refcount and free object
|
||||||
|
e=eNext;
|
||||||
} // while e!=m_active_explosions.end()
|
} // while e!=m_active_explosions.end()
|
||||||
} // if m_explosion_ended
|
} // if m_explosion_ended
|
||||||
m_something_was_hit=false;
|
m_something_was_hit=false;
|
||||||
} // update
|
} // update
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
/** See if there is an old, unused projectile object available. If so,
|
Flyable *ProjectileManager::newProjectile(Kart *kart, CollectableType type)
|
||||||
* reuse this object, otherwise create a new one. */
|
|
||||||
Projectile *ProjectileManager::newProjectile(Kart *kart, int type)
|
|
||||||
{
|
{
|
||||||
Projectile *p;
|
Flyable *f;
|
||||||
if(m_deleted_projectiles.size()>0)
|
switch(type) {
|
||||||
{
|
case COLLECT_SPARK: f = new Spark(kart); break;
|
||||||
p = m_deleted_projectiles.back();
|
case COLLECT_HOMING: f = new Homing(kart); break;
|
||||||
m_deleted_projectiles.pop_back();
|
case COLLECT_MISSILE: f = new Missile(kart); break;
|
||||||
p->init(kart, type);
|
default: return NULL;
|
||||||
}
|
}
|
||||||
else
|
m_active_projectiles.push_back(f);
|
||||||
{
|
return f;
|
||||||
p=new Projectile(kart, type);
|
|
||||||
}
|
|
||||||
m_active_projectiles.push_back(p);
|
|
||||||
return p;
|
|
||||||
|
|
||||||
} // newProjectile
|
} // newProjectile
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@ -148,17 +143,7 @@ Projectile *ProjectileManager::newProjectile(Kart *kart, int type)
|
|||||||
* reuse this object, otherwise create a new one. */
|
* reuse this object, otherwise create a new one. */
|
||||||
Explosion* ProjectileManager::newExplosion(sgCoord* coord)
|
Explosion* ProjectileManager::newExplosion(sgCoord* coord)
|
||||||
{
|
{
|
||||||
Explosion *e;
|
Explosion *e = new Explosion(coord);
|
||||||
if(m_deleted_explosions.size()>0)
|
|
||||||
{
|
|
||||||
e = m_deleted_explosions.back();
|
|
||||||
m_deleted_explosions.pop_back();
|
|
||||||
e->init(coord);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
e=new Explosion(coord);
|
|
||||||
}
|
|
||||||
m_active_explosions.push_back(e);
|
m_active_explosions.push_back(e);
|
||||||
return e;
|
return e;
|
||||||
} // newExplosion
|
} // newExplosion
|
||||||
|
@ -22,34 +22,26 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <plib/ssg.h>
|
#include <plib/ssg.h>
|
||||||
|
#include "flyable.hpp"
|
||||||
|
#include "collectable_manager.hpp"
|
||||||
|
|
||||||
class Kart;
|
class Kart;
|
||||||
class Projectile;
|
|
||||||
class Explosion;
|
class Explosion;
|
||||||
|
|
||||||
class ProjectileManager
|
class ProjectileManager
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
typedef std::vector<Projectile*> Projectiles;
|
typedef std::vector<Flyable*> Projectiles;
|
||||||
typedef std::vector<Explosion* > Explosions;
|
typedef std::vector<Explosion* > Explosions;
|
||||||
|
|
||||||
// The list of all active projectiles, i.e. projectiles
|
// The list of all active projectiles, i.e. projectiles
|
||||||
// which are currently moving on the track
|
// which are currently moving on the track
|
||||||
Projectiles m_active_projectiles;
|
Projectiles m_active_projectiles;
|
||||||
|
|
||||||
// The list of all deleted projectiles, i.e. projectils which
|
|
||||||
// hit something and have therefore been deleted. The objects
|
|
||||||
// in this list can be reused later, this removes the overhead
|
|
||||||
// of object creation
|
|
||||||
Projectiles m_deleted_projectiles;
|
|
||||||
|
|
||||||
// All active explosions, i.e. explosions which are currently
|
// All active explosions, i.e. explosions which are currently
|
||||||
// being shown
|
// being shown
|
||||||
Explosions m_active_explosions;
|
Explosions m_active_explosions;
|
||||||
|
|
||||||
// The list of deleted explosion, which will be reused.
|
|
||||||
Explosions m_deleted_explosions;
|
|
||||||
|
|
||||||
ssgSelector* m_explosion_model;
|
ssgSelector* m_explosion_model;
|
||||||
bool m_something_was_hit;
|
bool m_something_was_hit;
|
||||||
bool m_explosion_ended;
|
bool m_explosion_ended;
|
||||||
@ -67,9 +59,9 @@ public:
|
|||||||
void loadData ();
|
void loadData ();
|
||||||
void cleanup ();
|
void cleanup ();
|
||||||
void update (float dt);
|
void update (float dt);
|
||||||
Projectile* newProjectile (Kart *kart, int type);
|
Flyable* newProjectile (Kart *kart, CollectableType type);
|
||||||
Explosion* newExplosion (sgCoord *coord);
|
Explosion* newExplosion (sgCoord *coord);
|
||||||
void Deactivate (Projectile *p) {}
|
void Deactivate (Flyable *p) {}
|
||||||
void removeTextures ();
|
void removeTextures ();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -326,7 +326,7 @@ void DefaultRobot::handle_items( const float DELTA, const int STEPS )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case COLLECT_MISSILE:
|
case COLLECT_MISSILE:
|
||||||
case COLLECT_HOMING_MISSILE:
|
case COLLECT_HOMING:
|
||||||
if( m_time_since_last_shot > 5.0f && m_crashes.m_kart != -1 )
|
if( m_time_since_last_shot > 5.0f && m_crashes.m_kart != -1 )
|
||||||
{
|
{
|
||||||
if( sgDistanceVec2( m_curr_pos.xyz,
|
if( sgDistanceVec2( m_curr_pos.xyz,
|
||||||
|
@ -65,6 +65,7 @@ SoundManager::SoundManager()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_initialized = true;
|
m_initialized = true;
|
||||||
|
getcwd
|
||||||
#else
|
#else
|
||||||
if(alutInit(0, NULL) == AL_TRUE) // init OpenAL sound system
|
if(alutInit(0, NULL) == AL_TRUE) // init OpenAL sound system
|
||||||
m_initialized = true;
|
m_initialized = true;
|
||||||
|
@ -197,8 +197,12 @@ void UserConfig::setDefaults()
|
|||||||
set(GA_LEAVE_RACE,
|
set(GA_LEAVE_RACE,
|
||||||
Input(IT_KEYBOARD, SDLK_ESCAPE));
|
Input(IT_KEYBOARD, SDLK_ESCAPE));
|
||||||
|
|
||||||
|
set(GA_DEBUG_ADD_SPARK,
|
||||||
|
Input(IT_KEYBOARD, SDLK_F1));
|
||||||
set(GA_DEBUG_ADD_MISSILE,
|
set(GA_DEBUG_ADD_MISSILE,
|
||||||
Input(IT_KEYBOARD, SDLK_F7));
|
Input(IT_KEYBOARD, SDLK_F2));
|
||||||
|
set(GA_DEBUG_ADD_HOMING,
|
||||||
|
Input(IT_KEYBOARD, SDLK_F3));
|
||||||
set(GA_DEBUG_TOGGLE_FPS,
|
set(GA_DEBUG_TOGGLE_FPS,
|
||||||
Input(IT_KEYBOARD, SDLK_F12));
|
Input(IT_KEYBOARD, SDLK_F12));
|
||||||
set(GA_DEBUG_TOGGLE_WIREFRAME,
|
set(GA_DEBUG_TOGGLE_WIREFRAME,
|
||||||
@ -206,7 +210,7 @@ void UserConfig::setDefaults()
|
|||||||
set(GA_DEBUG_HISTORY,
|
set(GA_DEBUG_HISTORY,
|
||||||
Input(IT_KEYBOARD, SDLK_F10));
|
Input(IT_KEYBOARD, SDLK_F10));
|
||||||
set(GA_DEBUG_BULLET,
|
set(GA_DEBUG_BULLET,
|
||||||
Input(IT_KEYBOARD, SDLK_F2));
|
Input(IT_KEYBOARD, SDLK_F4));
|
||||||
|
|
||||||
// TODO: The following should become a static
|
// TODO: The following should become a static
|
||||||
// array. This allows:
|
// array. This allows:
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
// $Id$
|
|
||||||
//
|
|
||||||
// SuperTuxKart - a fun racing game with go-kart
|
|
||||||
// Copyright (C) 2004 Steve Baker <sjbaker1@airmail.net>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License
|
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
#include <plib/sg.h>
|
|
||||||
|
|
||||||
void pr_from_normal ( sgVec3 hpr, sgVec3 nrm )
|
|
||||||
{
|
|
||||||
const float SY = sin ( -hpr [ 0 ] * SG_DEGREES_TO_RADIANS ) ;
|
|
||||||
const float CY = cos ( -hpr [ 0 ] * SG_DEGREES_TO_RADIANS ) ;
|
|
||||||
|
|
||||||
hpr[2] = SG_RADIANS_TO_DEGREES * atan2 ( nrm[0] * CY - nrm[1] * SY, nrm[2] ) ;
|
|
||||||
hpr[1] = -SG_RADIANS_TO_DEGREES * atan2 ( nrm[1] * CY + nrm[0] * SY, nrm[2] ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void hpr_from_normal ( sgVec3 hpr, sgVec3 nrm )
|
|
||||||
{
|
|
||||||
pr_from_normal ( hpr, nrm ) ;
|
|
||||||
hpr[0] = -SG_RADIANS_TO_DEGREES * atan2 ( nrm[0], nrm[1] ) ;
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
|||||||
// $Id$
|
|
||||||
//
|
|
||||||
// SuperTuxKart - a fun racing game with go-kart
|
|
||||||
// Copyright (C) 2004 Steve Baker <sjbaker1@airmail.net>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License
|
|
||||||
// as published by the Free Software Foundation; either version 2
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef HEADER_UTILS_H
|
|
||||||
#define HEADER_UTILS_H
|
|
||||||
|
|
||||||
//FIXME: erase this file or put what should go here?
|
|
||||||
|
|
||||||
#endif
|
|
@ -27,9 +27,9 @@
|
|||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
# include <OpenGL/gl.h>
|
# include <OpenGL/gl.h>
|
||||||
#else
|
#else
|
||||||
# ifdef WIN32
|
# ifdef WIN32
|
||||||
# define WIN32_LEAN_AND_MEAN
|
# define WIN32_LEAN_AND_MEAN
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
# endif
|
# endif
|
||||||
# include <GL/gl.h>
|
# include <GL/gl.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -102,9 +102,6 @@ World::World(const RaceSetup& raceSetup_) : m_race_setup(raceSetup_)
|
|||||||
|
|
||||||
assert(m_race_setup.m_karts.size() > 0);
|
assert(m_race_setup.m_karts.size() > 0);
|
||||||
|
|
||||||
// Clear all callbacks, which might still be stored there from a previous race.
|
|
||||||
callback_manager->clear(CB_TRACK);
|
|
||||||
|
|
||||||
// Load the track models - this must be done before the karts so that the
|
// Load the track models - this must be done before the karts so that the
|
||||||
// karts can be positioned properly on (and not in) the tracks.
|
// karts can be positioned properly on (and not in) the tracks.
|
||||||
loadTrack ( ) ;
|
loadTrack ( ) ;
|
||||||
@ -118,7 +115,6 @@ World::World(const RaceSetup& raceSetup_) : m_race_setup(raceSetup_)
|
|||||||
{
|
{
|
||||||
sgCoord init_pos;
|
sgCoord init_pos;
|
||||||
m_track->getStartCoords(pos, &init_pos);
|
m_track->getStartCoords(pos, &init_pos);
|
||||||
|
|
||||||
Kart* newkart;
|
Kart* newkart;
|
||||||
if(user_config->m_profile)
|
if(user_config->m_profile)
|
||||||
{
|
{
|
||||||
@ -149,9 +145,9 @@ World::World(const RaceSetup& raceSetup_) : m_race_setup(raceSetup_)
|
|||||||
{
|
{
|
||||||
history->LoadKartData(newkart, pos);
|
history->LoadKartData(newkart, pos);
|
||||||
}
|
}
|
||||||
newkart -> getModel () -> clrTraversalMaskBits(SSGTRAV_ISECT|SSGTRAV_HOT);
|
newkart -> getModelTransform() -> clrTraversalMaskBits(SSGTRAV_ISECT|SSGTRAV_HOT);
|
||||||
|
|
||||||
scene->add ( newkart -> getModel() ) ;
|
scene->add ( newkart -> getModelTransform() ) ;
|
||||||
m_kart.push_back(newkart);
|
m_kart.push_back(newkart);
|
||||||
pos++;
|
pos++;
|
||||||
} // for i
|
} // for i
|
||||||
@ -201,7 +197,7 @@ World::World(const RaceSetup& raceSetup_) : m_race_setup(raceSetup_)
|
|||||||
}
|
}
|
||||||
if( m_p_replay_player ) m_p_replay_player->showReplayAt( 0.0 );
|
if( m_p_replay_player ) m_p_replay_player->showReplayAt( 0.0 );
|
||||||
#endif
|
#endif
|
||||||
}
|
} // World
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
World::~World()
|
World::~World()
|
||||||
@ -210,6 +206,9 @@ World::~World()
|
|||||||
saveReplayHumanReadable( "test" );
|
saveReplayHumanReadable( "test" );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Clear all callbacks
|
||||||
|
callback_manager->clear(CB_TRACK);
|
||||||
|
|
||||||
for ( unsigned int i = 0 ; i < m_kart.size() ; i++ )
|
for ( unsigned int i = 0 ; i < m_kart.size() ; i++ )
|
||||||
delete m_kart[i];
|
delete m_kart[i];
|
||||||
|
|
||||||
@ -253,7 +252,7 @@ void World::resetAllKarts()
|
|||||||
{
|
{
|
||||||
#ifdef BULLET
|
#ifdef BULLET
|
||||||
bool all_finished=false;
|
bool all_finished=false;
|
||||||
for(int i=0; i<10; i++) m_physics->update(1./60.);
|
for(int i=0; i<10; i++) m_physics->update(1.f/60.f);
|
||||||
while(!all_finished)
|
while(!all_finished)
|
||||||
{
|
{
|
||||||
m_physics->update(1.f/60.f);
|
m_physics->update(1.f/60.f);
|
||||||
|
@ -102,9 +102,9 @@ public:
|
|||||||
float getGravity() const { return m_track->getGravity(); }
|
float getGravity() const { return m_track->getGravity(); }
|
||||||
Physics *getPhysics() const { return m_physics; }
|
Physics *getPhysics() const { return m_physics; }
|
||||||
Track *getTrack() const { return m_track; }
|
Track *getTrack() const { return m_track; }
|
||||||
#ifdef BULLET
|
|
||||||
float getHAT(btVector3 pos) const { return m_physics->getHAT(pos); }
|
float getHAT(btVector3 pos) const { return m_physics->getHAT(pos); }
|
||||||
#endif
|
bool getTerrainNormal(btVector3 pos, btVector3 *nrm)
|
||||||
|
const { return m_physics->getTerrainNormal(pos,nrm);}
|
||||||
Kart* getFastestKart() const { return m_fastest_kart; }
|
Kart* getFastestKart() const { return m_fastest_kart; }
|
||||||
float getFastestLapTime() const { return m_fastest_lap; }
|
float getFastestLapTime() const { return m_fastest_lap; }
|
||||||
void setFastestLap(Kart *k, float time) {m_fastest_kart=k;m_fastest_lap=time;}
|
void setFastestLap(Kart *k, float time) {m_fastest_kart=k;m_fastest_lap=time;}
|
||||||
|
Loading…
Reference in New Issue
Block a user