278 lines
8.9 KiB
C++
278 lines
8.9 KiB
C++
/**
|
|
* @author Edouard DUPIN
|
|
*
|
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
|
*
|
|
* @license BSD v3 (see license file)
|
|
*/
|
|
|
|
#include <ege/debug.h>
|
|
#include <ege/Environement.h>
|
|
#include <ege/ElementGame.h>
|
|
|
|
|
|
#undef __class__
|
|
#define __class__ "Environement"
|
|
|
|
|
|
ege::ElementGame* ege::Environement::getElementNearest(ege::ElementGame* _sourceRequest, float& _distance) {
|
|
if (nullptr == _sourceRequest) {
|
|
return nullptr;
|
|
}
|
|
vec3 sourcePosition = _sourceRequest->getPosition();
|
|
ege::ElementGame* result = nullptr;
|
|
for (size_t iii=0; iii<m_listElementGame.size() ; iii++) {
|
|
// chack nullptr pointer
|
|
if (nullptr == m_listElementGame[iii]) {
|
|
continue;
|
|
}
|
|
if (m_listElementGame[iii]->getGroup() <= 0) {
|
|
continue;
|
|
}
|
|
// check if they are in the same group:
|
|
if (m_listElementGame[iii]->getGroup() == _sourceRequest->getGroup()) {
|
|
continue;
|
|
}
|
|
// check distance ...
|
|
vec3 destPosition = m_listElementGame[iii]->getPosition();
|
|
float distance = btDistance(sourcePosition, destPosition);
|
|
//EGE_DEBUG("Distance : " << _distance << " >? " << distance << " id=" << iii);
|
|
if (_distance>distance) {
|
|
_distance = distance;
|
|
result = m_listElementGame[iii];
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
void ege::Environement::getElementNearest(const vec3& _sourcePosition,
|
|
float _distanceMax,
|
|
std::vector<ege::Environement::ResultNearestElement>& _resultList) {
|
|
_resultList.clear();
|
|
ege::Environement::ResultNearestElement result;
|
|
result.dist = 99999999999.0f;
|
|
result.element = nullptr;
|
|
for (size_t iii=0; iii<m_listElementGame.size() ; iii++) {
|
|
// chack nullptr pointer
|
|
result.element = m_listElementGame[iii];
|
|
if (nullptr == result.element) {
|
|
continue;
|
|
}
|
|
// check distance ...
|
|
vec3 destPosition = result.element->getPosition();
|
|
if (_sourcePosition == destPosition) {
|
|
continue;
|
|
}
|
|
result.dist = btDistance(_sourcePosition, destPosition);
|
|
//EGE_DEBUG("Distance : " << _distance << " >? " << distance << " id=" << iii);
|
|
if (_distanceMax>result.dist) {
|
|
_resultList.push_back(result);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ege::Environement::getElementNearestFixed(const vec3& _sourcePosition,
|
|
float _distanceMax,
|
|
std::vector<ege::Environement::ResultNearestElement>& _resultList) {
|
|
_resultList.clear();
|
|
ege::Environement::ResultNearestElement result;
|
|
result.dist = 99999999999.0f;
|
|
result.element = nullptr;
|
|
for (size_t iii=0; iii<m_listElementGame.size() ; iii++) {
|
|
// chack nullptr pointer
|
|
result.element = m_listElementGame[iii];
|
|
if (nullptr == result.element) {
|
|
continue;
|
|
}
|
|
if (false == result.element->isFixed()) {
|
|
continue;
|
|
}
|
|
// check distance ...
|
|
vec3 destPosition = result.element->getPositionTheoric();
|
|
result.dist = btDistance(_sourcePosition, destPosition);
|
|
//EGE_DEBUG("Distance : " << _distance << " >? " << distance << " id=" << iii);
|
|
if (_distanceMax <= result.dist) {
|
|
continue;
|
|
}
|
|
// try to add the element at the best positions:
|
|
size_t jjj;
|
|
for (jjj=0; jjj<_resultList.size(); jjj++) {
|
|
if (_resultList[jjj].dist>result.dist) {
|
|
_resultList.insert(_resultList.begin()+jjj, result);
|
|
break;
|
|
}
|
|
}
|
|
// add element at the end :
|
|
if (jjj >= _resultList.size()) {
|
|
_resultList.push_back(result);
|
|
}
|
|
}
|
|
}
|
|
|
|
static etk::Hash<ege::createElement_tf>& getHachTableCreating() {
|
|
static etk::Hash<ege::createElement_tf> s_table;
|
|
return s_table;
|
|
}
|
|
|
|
void ege::Environement::addCreator(const std::string& _type, ege::createElement_tf _creator) {
|
|
if (nullptr == _creator) {
|
|
EGE_ERROR("Try to add an empty CREATOR ...");
|
|
return;
|
|
}
|
|
EGE_DEBUG("Add creator: " << _type);
|
|
getHachTableCreating().add(_type, _creator);
|
|
EGE_DEBUG("Add creator: " << _type << " (done)");
|
|
}
|
|
|
|
ege::ElementGame* ege::Environement::createElement(const std::string& _type, bool _autoAddElement, enum ege::property _property, void* _value) {
|
|
if (false == getHachTableCreating().exist(_type)) {
|
|
EGE_ERROR("Request creating of an type that is not known '" << _type << "'");
|
|
return nullptr;
|
|
}
|
|
ege::createElement_tf creatorPointer = getHachTableCreating()[_type];
|
|
if (nullptr == creatorPointer) {
|
|
EGE_ERROR("nullptr pointer creator == > internal error... '" << _type << "'");
|
|
return nullptr;
|
|
}
|
|
ege::ElementGame* tmpElement = creatorPointer(*this);
|
|
if (nullptr == tmpElement) {
|
|
EGE_ERROR("allocation error '" << _type << "'");
|
|
return nullptr;
|
|
}
|
|
if (false == tmpElement->init(_property, _value)) {
|
|
EGE_ERROR("Init error ... '" << _type << "'");
|
|
// remove created element ...
|
|
delete(tmpElement);
|
|
return nullptr;
|
|
}
|
|
if (_autoAddElement == true) {
|
|
addElementGame(tmpElement);
|
|
}
|
|
return tmpElement;
|
|
}
|
|
|
|
ege::ElementGame* ege::Environement::createElement(const std::string& _type, std::string& _description, bool _autoAddElement) {
|
|
return createElement(_type, _autoAddElement, ege::typeString, static_cast<void*>(&_description));
|
|
}
|
|
|
|
ege::ElementGame* ege::Environement::createElement(const std::string& _type, ejson::Value* _value, bool _autoAddElement) {
|
|
return createElement(_type, _autoAddElement, ege::typeJson, static_cast<void*>(_value));
|
|
}
|
|
|
|
ege::ElementGame* ege::Environement::createElement(const std::string& _type, exml::Node* _node, bool _autoAddElement) {
|
|
return createElement(_type, _autoAddElement, ege::typeXml, static_cast<void*>(_node));
|
|
}
|
|
|
|
|
|
void ege::Environement::addElementGame(ege::ElementGame* _newElement) {
|
|
// prevent memory allocation and un allocation ...
|
|
if (nullptr == _newElement) {
|
|
return;
|
|
}
|
|
for (size_t iii=0; iii<m_listElementGame.size() ; iii++) {
|
|
if (nullptr == m_listElementGame[iii]) {
|
|
m_listElementGame[iii] = _newElement;
|
|
m_listElementGame[iii]->dynamicEnable();
|
|
return;
|
|
}
|
|
}
|
|
m_listElementGame.push_back(_newElement);
|
|
_newElement->dynamicEnable();
|
|
}
|
|
|
|
void ege::Environement::rmElementGame(ege::ElementGame* _removeElement) {
|
|
if (nullptr == _removeElement) {
|
|
return;
|
|
}
|
|
// inform the element that an element has been removed == > this permit to keep pointer on elements ...
|
|
for (size_t iii=0; iii<m_listElementGame.size() ; iii++) {
|
|
if (nullptr != m_listElementGame[iii]) {
|
|
m_listElementGame[iii]->elementIsRemoved(_removeElement);
|
|
}
|
|
}
|
|
// ream remove on the element :
|
|
for (size_t iii=0; iii<m_listElementGame.size() ; iii++) {
|
|
if (_removeElement == m_listElementGame[iii]) {
|
|
m_listElementGame[iii]->onDestroy();
|
|
m_listElementGame[iii]->dynamicDisable();
|
|
m_listElementGame[iii]->unInit();
|
|
delete(m_listElementGame[iii]);
|
|
m_listElementGame[iii] = nullptr;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void ege::Environement::getOrderedElementForDisplay(std::vector<ege::Environement::ResultNearestElement>& _resultList,
|
|
const vec3& _position,
|
|
const vec3& _direction) {
|
|
// remove all unneeded elements (old display...)
|
|
_resultList.clear();
|
|
// basic element result
|
|
ege::Environement::ResultNearestElement result;
|
|
result.dist = 99999999999.0f;
|
|
result.element = nullptr;
|
|
// for all element in the game we chek if it is needed to display it ...
|
|
for (size_t iii=0; iii<m_listElementGame.size() ; iii++) {
|
|
// chack nullptr pointer
|
|
if (nullptr == m_listElementGame[iii]) {
|
|
// no pointer null are set in the output list ...
|
|
continue;
|
|
}
|
|
result.element = m_listElementGame[iii];
|
|
// check distance ...
|
|
vec3 destPosition = result.element->getPosition();
|
|
vec3 angleView = (destPosition - _position).normalized();
|
|
float dotResult=angleView.dot(_direction);
|
|
//EGE_DEBUG("Dot position : " << destPosition << " == > dot=" << dotResult);
|
|
if (dotResult <= 0.85f) {
|
|
// they are not in the camera angle view ... == > no need to process display
|
|
continue;
|
|
}
|
|
result.dist = btDistance(_position, destPosition);
|
|
if (result.dist>500.0f) {
|
|
// The element is realy too far ... == > no need to display
|
|
continue;
|
|
}
|
|
// try to add the element at the best positions:
|
|
size_t jjj;
|
|
for (jjj=0; jjj<_resultList.size(); jjj++) {
|
|
if (_resultList[jjj].dist>result.dist) {
|
|
_resultList.insert(_resultList.begin()+jjj, result);
|
|
break;
|
|
}
|
|
}
|
|
// add element at the end :
|
|
if (jjj >= _resultList.size()) {
|
|
_resultList.push_back(result);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void ege::Environement::generateInteraction(ege::ElementInteraction& _event) {
|
|
// inform the element that an element has been removed == > this permit to keep pointer on elements ...
|
|
for (size_t iii=0; iii<m_listElementGame.size() ; iii++) {
|
|
if (nullptr == m_listElementGame[iii]) {
|
|
continue;
|
|
}
|
|
_event.applyEvent(*m_listElementGame[iii]);
|
|
/*
|
|
vec3 destPosition = m_listElementGame[iii]->getPosition();
|
|
float dist = btDistance(sourcePosition, destPosition);
|
|
if (dist == 0 || dist>decreasePower) {
|
|
continue;
|
|
}
|
|
float inpact = (decreasePower-dist)/decreasePower * power;
|
|
g_listElementGame[iii]->setFireOn(groupIdSource, type, -inpact, sourcePosition);
|
|
*/
|
|
}
|
|
}
|
|
|
|
ege::Environement::Environement() :
|
|
m_dynamicsWorld(nullptr),
|
|
m_particuleEngine(*this) {
|
|
// nothing to do ...
|
|
}
|