khanat-opennel-code/code/nel/samples/pacs/object.cpp

278 lines
7.6 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);
}
// ***************************************************************************