279 lines
7.8 KiB
C++
279 lines
7.8 KiB
C++
|
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||
|
//
|
||
|
// This program is free software: you can redistribute it and/or modify
|
||
|
// it under the terms of the GNU Affero General Public License as
|
||
|
// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
|
||
|
//
|
||
|
// You should have received a copy of the GNU Affero General Public License
|
||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
#include "object.h"
|
||
|
|
||
|
// Pacs includes
|
||
|
#include <nel/pacs/u_move_container.h>
|
||
|
#include <nel/pacs/u_move_primitive.h>
|
||
|
|
||
|
// Misc includes
|
||
|
#include <nel/misc/vectord.h>
|
||
|
#include <nel/misc/quat.h>
|
||
|
#include <nel/misc/path.h>
|
||
|
|
||
|
// 3d includes
|
||
|
#include <nel/3d/u_scene.h>
|
||
|
#include <nel/3d/u_instance.h>
|
||
|
#include <nel/3d/u_instance_material.h>
|
||
|
|
||
|
#define BRAKE_FORCE (-0.1) // (m.s-2)
|
||
|
#define GRAVITY_FORCE (-15.0)
|
||
|
#define SHOCK_ABSORB (1.0) //
|
||
|
|
||
|
using namespace NL3D;
|
||
|
using namespace NLNET;
|
||
|
using namespace NLMISC;
|
||
|
using namespace NLPACS;
|
||
|
|
||
|
// ***************************************************************************
|
||
|
|
||
|
CObjectDyn::CObjectDyn (double width, double depth, double height, double orientation, const CVectorD& pos,
|
||
|
const CVectorD& speed, bool obstacle, UMoveContainer &container, UScene &scene,
|
||
|
UMovePrimitive::TReaction reaction, NLPACS::UMovePrimitive::TTrigger trigger,
|
||
|
uint8 worldImage, uint8 nbImage, uint8 insertWorldImage)
|
||
|
{
|
||
|
// Create a box instance
|
||
|
_Instance = scene.createInstance(CPath::lookup("rectangle.shape"));
|
||
|
if(_Instance.empty())
|
||
|
{
|
||
|
nlerror("Failed to load shape: %s", CPath::lookup("rectangle.shape").c_str());
|
||
|
}
|
||
|
|
||
|
// Freezed
|
||
|
Freezed = reaction == UMovePrimitive::DoNothing;
|
||
|
|
||
|
// Setup the instance
|
||
|
if (_Instance.getNumMaterials())
|
||
|
{
|
||
|
uint i;
|
||
|
for (i=0; i<_Instance.getNumMaterials(); i++)
|
||
|
{
|
||
|
UInstanceMaterial material = _Instance.getMaterial(i);
|
||
|
if (trigger != UMovePrimitive::NotATrigger)
|
||
|
{
|
||
|
// material.setBlend(true);
|
||
|
// material.setBlendFunc(UInstanceMaterial::srcalpha, UInstanceMaterial::invsrcalpha);
|
||
|
material.setDiffuse (CRGBA(255,255,255,255));
|
||
|
// material.setOpacity(128);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (Freezed)
|
||
|
{
|
||
|
material.setDiffuse (CRGBA(128,0,0,255));
|
||
|
material.setOpacity(255);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Setup the instance
|
||
|
_Instance.setScale (CVectorD (width, depth, height));
|
||
|
_Instance.setRotQuat (CQuat (CVectorD (0, 0, 1), (float)orientation));
|
||
|
|
||
|
// Create a collision volume
|
||
|
_MovePrimitive = container.addCollisionablePrimitive (worldImage, nbImage);
|
||
|
_MovePrimitive->insertInWorldImage (insertWorldImage);
|
||
|
|
||
|
// Setup the collision primitive
|
||
|
_MovePrimitive->setPrimitiveType (UMovePrimitive::_2DOrientedBox);
|
||
|
_MovePrimitive->setHeight ((float)height);
|
||
|
_MovePrimitive->setOrientation (orientation, insertWorldImage);
|
||
|
_MovePrimitive->setSize ((float)width, (float)depth);
|
||
|
|
||
|
// This primitive is an obstacle (it blocks others)
|
||
|
_MovePrimitive->setObstacle (obstacle);
|
||
|
|
||
|
// Setup reaction type
|
||
|
_MovePrimitive->setReactionType (reaction);
|
||
|
|
||
|
// Setup absorption value
|
||
|
_MovePrimitive->setAbsorbtion (0.9f);
|
||
|
|
||
|
// Setup user data
|
||
|
_MovePrimitive->UserData=(uint64)this;
|
||
|
|
||
|
// Setup trigger type
|
||
|
_MovePrimitive->setTriggerType (trigger);
|
||
|
|
||
|
// Set pos and speed
|
||
|
setPos (pos);
|
||
|
setSpeed (speed);
|
||
|
|
||
|
_MovePrimitive->setGlobalPosition (pos, insertWorldImage);
|
||
|
}
|
||
|
|
||
|
// ***************************************************************************
|
||
|
|
||
|
CObjectDyn::CObjectDyn (double diameter, double height, const CVectorD& pos, const CVectorD& speed,
|
||
|
bool obstacle, UMoveContainer &container, UScene &scene, UMovePrimitive::TReaction reaction,
|
||
|
NLPACS::UMovePrimitive::TTrigger trigger, uint8 worldImage, uint8 nbImage, uint8 insertWorldImage)
|
||
|
{
|
||
|
// Create a box instance
|
||
|
_Instance = scene.createInstance(CPath::lookup("cylinder.shape"));
|
||
|
if(_Instance.empty())
|
||
|
{
|
||
|
nlerror("Failed to load shape: %s",CPath::lookup("cylinder.shape").c_str());
|
||
|
}
|
||
|
|
||
|
// Freezed
|
||
|
Freezed = reaction == UMovePrimitive::DoNothing;
|
||
|
|
||
|
// Setup the instance
|
||
|
if (_Instance.getNumMaterials())
|
||
|
{
|
||
|
uint i;
|
||
|
for (i=0; i<_Instance.getNumMaterials(); i++)
|
||
|
{
|
||
|
UInstanceMaterial material = _Instance.getMaterial(i);
|
||
|
if (trigger != UMovePrimitive::NotATrigger)
|
||
|
{
|
||
|
// material.setBlend(true);
|
||
|
// material.setBlendFunc(UInstanceMaterial::srcalpha, UInstanceMaterial::invsrcalpha);
|
||
|
material.setDiffuse (CRGBA(255,255,255));
|
||
|
// material.setOpacity(128);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (Freezed)
|
||
|
{
|
||
|
material.setDiffuse (CRGBA(128,0,0));
|
||
|
material.setOpacity(255);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Setup the instance
|
||
|
_Instance.setScale (CVectorD (diameter, diameter, height));
|
||
|
|
||
|
// Create a collision volume
|
||
|
_MovePrimitive = container.addCollisionablePrimitive (worldImage, nbImage);
|
||
|
_MovePrimitive->insertInWorldImage (insertWorldImage);
|
||
|
|
||
|
// Setup the primitive
|
||
|
_MovePrimitive->setPrimitiveType (UMovePrimitive::_2DOrientedCylinder);
|
||
|
_MovePrimitive->setHeight ((float)height);
|
||
|
_MovePrimitive->setRadius ((float)diameter/2.f);
|
||
|
|
||
|
// This primitive is an obstacle (it blocks others)
|
||
|
_MovePrimitive->setObstacle (obstacle);
|
||
|
|
||
|
// Setup reaction type
|
||
|
_MovePrimitive->setReactionType (reaction);
|
||
|
|
||
|
// Setup reaction type
|
||
|
_MovePrimitive->setAbsorbtion (0.9f);
|
||
|
|
||
|
// Setup user data
|
||
|
_MovePrimitive->UserData=(uint64)this;
|
||
|
|
||
|
// Setup trigger type
|
||
|
_MovePrimitive->setTriggerType (trigger);
|
||
|
|
||
|
// Set pos and speed
|
||
|
setPos (pos);
|
||
|
setSpeed (speed);
|
||
|
_MovePrimitive->setGlobalPosition (pos, insertWorldImage);
|
||
|
}
|
||
|
|
||
|
// ***************************************************************************
|
||
|
|
||
|
void CObjectDyn::tryMove (double deltaTime, UMoveContainer &container, uint8 worldImage)
|
||
|
{
|
||
|
// New speed
|
||
|
if ( (_MovePrimitive->getSpeed(worldImage).norm()>0.f) || _Speed.norm()>0.f )
|
||
|
{
|
||
|
// Brake
|
||
|
CVectorD newSpeed=_Speed;
|
||
|
newSpeed.normalize();
|
||
|
newSpeed*=BRAKE_FORCE*deltaTime;
|
||
|
newSpeed+=_Speed;
|
||
|
|
||
|
// Stop ?
|
||
|
if (_Speed*newSpeed<=0)
|
||
|
newSpeed=CVectorD (0,0,0);
|
||
|
|
||
|
// Set speed
|
||
|
setSpeed (newSpeed);
|
||
|
|
||
|
// Try this move
|
||
|
_MovePrimitive->move (_Speed, worldImage);
|
||
|
_TryMove=true;
|
||
|
}
|
||
|
else
|
||
|
_TryMove=false;
|
||
|
|
||
|
}
|
||
|
|
||
|
// ***************************************************************************
|
||
|
|
||
|
void CObjectDyn::doMove (double deltaTime, uint8 worldImage)
|
||
|
{
|
||
|
// New speed
|
||
|
setSpeed (_MovePrimitive->getSpeed(worldImage));
|
||
|
|
||
|
// New position
|
||
|
setPos (_MovePrimitive->getFinalPosition (worldImage));
|
||
|
}
|
||
|
|
||
|
// ***************************************************************************
|
||
|
|
||
|
void CObjectDyn::setPos (const CVectorD& pos)
|
||
|
{
|
||
|
_Position=pos;
|
||
|
if (!_Instance.empty())
|
||
|
_Instance.setPos (pos);
|
||
|
}
|
||
|
|
||
|
// ***************************************************************************
|
||
|
|
||
|
void CObjectDyn::setGlobalPos (UGlobalPosition& gpos, CVectorD& pos, uint8 worldimage)
|
||
|
{
|
||
|
// Place the primitive the first time
|
||
|
_MovePrimitive->setGlobalPosition (gpos, worldimage);
|
||
|
setPos (pos);
|
||
|
}
|
||
|
|
||
|
// ***************************************************************************
|
||
|
|
||
|
void CObjectDyn::setSpeed (const CVectorD& speed)
|
||
|
{
|
||
|
_Speed=speed;
|
||
|
}
|
||
|
|
||
|
// ***************************************************************************
|
||
|
|
||
|
void CObjectDyn::remove (NLPACS::UMoveContainer &container, UScene &scene)
|
||
|
{
|
||
|
// Remove from container
|
||
|
container.removePrimitive (_MovePrimitive);
|
||
|
|
||
|
// Remove instance
|
||
|
if (!_Instance.empty())
|
||
|
scene.deleteInstance (_Instance);
|
||
|
}
|
||
|
|
||
|
// ***************************************************************************
|
||
|
|