Refactor CObject interface related to crash spheres

master
Piotr Dziwinski 2015-07-10 09:26:38 +02:00
parent 5a68558f4c
commit b0ac2f8326
36 changed files with 797 additions and 745 deletions

View File

@ -164,6 +164,7 @@ set(BASE_SOURCES
object/motion/motiontoto.cpp
object/motion/motionvehicle.cpp
object/motion/motionworm.cpp
object/object.cpp
object/object_factory.cpp
object/object_manager.cpp
object/old_object.cpp

View File

@ -3742,11 +3742,11 @@ CObject* CParticle::SearchObjectGun(Math::Vector old, Math::Vector pos,
if (dist < min)
best = obj;
// Test with all spheres of the object.
int j = 0;
float oRadius;
while (obj->GetCrashSphere(j++, oPos, oRadius))
for (const auto& crashSphere : obj->GetAllCrashSpheres())
{
oPos = crashSphere.sphere.pos;
float oRadius = crashSphere.sphere.radius;
if ( oPos.x+oRadius < box1.x || oPos.x-oRadius > box2.x || // outside the box?
oPos.y+oRadius < box1.y || oPos.y-oRadius > box2.y ||
oPos.z+oRadius < box1.z || oPos.z-oRadius > box2.z ) continue;

View File

@ -86,14 +86,9 @@ bool CPyro::Create(PyroType type, CObject* obj, float force)
DisplayError(type, obj); // displays eventual messages
for (const auto& crashSphere : obj->GetAllCrashSpheres())
{
int i = 0;
// Copies all spheres of the object.
for (; i < 50; i++)
{
if ( !obj->GetCrashSphere(i, m_crashSpherePos[i], m_crashSphereRadius[i]) ) break;
}
m_crashSphereUsed = i;
m_crashSpheres.push_back(crashSphere.sphere);
}
// Calculates the size of the effect.
@ -641,18 +636,19 @@ bool CPyro::EventProcess(const Event &event)
{
m_lastParticle = m_time;
if ( m_crashSphereUsed > 0 )
if (m_crashSpheres.size() > 0)
{
int i = rand()%m_crashSphereUsed;
Math::Vector pos = m_crashSpherePos[i];
pos.x += (Math::Rand()-0.5f)*m_crashSphereRadius[i]*2.0f;
pos.z += (Math::Rand()-0.5f)*m_crashSphereRadius[i]*2.0f;
int i = rand() % m_crashSpheres.size();
Math::Vector pos = m_crashSpheres[i].pos;
float radius = m_crashSpheres[i].radius;
pos.x += (Math::Rand()-0.5f)*radius*2.0f;
pos.z += (Math::Rand()-0.5f)*radius*2.0f;
Math::Vector speed;
speed.x = (Math::Rand()-0.5f)*m_crashSphereRadius[i]*0.5f;
speed.z = (Math::Rand()-0.5f)*m_crashSphereRadius[i]*0.5f;
speed.y = Math::Rand()*m_crashSphereRadius[i]*1.0f;
speed.x = (Math::Rand()-0.5f)*radius*0.5f;
speed.z = (Math::Rand()-0.5f)*radius*0.5f;
speed.y = Math::Rand()*radius*1.0f;
Math::Point dim;
dim.x = Math::Rand()*m_crashSphereRadius[i]*0.5f+m_crashSphereRadius[i]*0.75f*m_force;
dim.x = Math::Rand()*radius*0.5f+radius*0.75f*m_force;
dim.y = dim.x;
m_particle->CreateParticle(pos, speed, dim, PARTISMOKE1, 3.0f);
}
@ -723,16 +719,17 @@ bool CPyro::EventProcess(const Event &event)
{
m_lastParticle = m_time;
if ( m_crashSphereUsed > 0 )
if (m_crashSpheres.size() > 0)
{
int i = rand()%m_crashSphereUsed;
Math::Vector pos = m_crashSpherePos[i];
pos.x += (Math::Rand()-0.5f)*m_crashSphereRadius[i]*2.0f;
pos.z += (Math::Rand()-0.5f)*m_crashSphereRadius[i]*2.0f;
int i = rand() % m_crashSpheres.size();
Math::Vector pos = m_crashSpheres[i].pos;
float radius = m_crashSpheres[i].radius;
pos.x += (Math::Rand()-0.5f)*radius*2.0f;
pos.z += (Math::Rand()-0.5f)*radius*2.0f;
Math::Vector speed;
speed.x = (Math::Rand()-0.5f)*m_crashSphereRadius[i]*0.5f;
speed.z = (Math::Rand()-0.5f)*m_crashSphereRadius[i]*0.5f;
speed.y = Math::Rand()*m_crashSphereRadius[i]*1.0f;
speed.x = (Math::Rand()-0.5f)*radius*0.5f;
speed.z = (Math::Rand()-0.5f)*radius*0.5f;
speed.y = Math::Rand()*radius*1.0f;
Math::Point dim;
dim.x = 1.0f*m_force;
dim.y = dim.x;
@ -2198,9 +2195,7 @@ void CPyro::FallStart()
CObject* CPyro::FallSearchBeeExplo()
{
Math::Vector iPos;
float iRadius = 0.0f;
m_object->GetCrashSphere(0, iPos, iRadius);
auto bulletCrashSphere = m_object->GetFirstCrashSphere();
for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects())
{
@ -2261,32 +2256,28 @@ CObject* CPyro::FallSearchBeeExplo()
float shieldRadius = obj->GetShieldRadius();
if ( shieldRadius > 0.0f )
{
float distance = Math::Distance(oPos, iPos);
float distance = Math::Distance(oPos, bulletCrashSphere.sphere.pos);
if (distance <= shieldRadius)
return obj;
}
if ( oType == OBJECT_BASE )
{
float distance = Math::Distance(oPos, iPos);
float distance = Math::Distance(oPos, bulletCrashSphere.sphere.pos);
if (distance < 25.0f)
return obj;
}
// Test the center of the object, which is necessary for objects
// that have no sphere in the center (station).
float distance = Math::Distance(oPos, iPos)-4.0f;
float distance = Math::Distance(oPos, bulletCrashSphere.sphere.pos)-4.0f;
if (distance < 5.0f)
return obj;
// Test with all spheres of the object.
Math::Vector ooPos;
float ooRadius = 0.0f;
int j = 0;
while (obj->GetCrashSphere(j++, ooPos, ooRadius))
for (const auto& objCrashSphere : obj->GetAllCrashSpheres())
{
distance = Math::Distance(ooPos, iPos);
if (distance <= iRadius+ooRadius)
if (Math::DistanceBetweenSpheres(objCrashSphere.sphere, bulletCrashSphere.sphere) <= 0.0f)
{
return obj;
}

View File

@ -31,8 +31,11 @@
#include "graphics/core/color.h"
#include "graphics/engine/pyro_type.h"
#include "math/sphere.h"
#include "object/object_type.h"
#include <vector>
class CObject;
class CRobotMain;
@ -180,9 +183,7 @@ protected:
float m_fallBulletTime;
bool m_fallEnding;
int m_crashSphereUsed; // number of spheres used
Math::Vector m_crashSpherePos[50];
float m_crashSphereRadius[50];
std::vector<Math::Sphere> m_crashSpheres;
};

27
src/math/sphere.h Normal file
View File

@ -0,0 +1,27 @@
#pragma once
#include "math/vector.h"
namespace Math {
struct Sphere
{
Sphere(const Vector& pos = Vector(), float radius = 0.0f)
: pos(pos), radius(radius) {}
Vector pos;
float radius;
};
//! Compute distance between given \a point and \a sphere
inline float DistanceToSphere(const Vector& point, const Sphere& sphere)
{
return Math::Distance(point, sphere.pos) - sphere.radius;
}
inline float DistanceBetweenSpheres(const Sphere& sphere1, const Sphere& sphere2)
{
return Math::Distance(sphere1.pos, sphere2.pos) - sphere1.radius - sphere2.radius;
}
} // namespace Math

View File

@ -1298,11 +1298,10 @@ Error CAutoBase::CheckCloseDoor()
ObjectType type = obj->GetType();
if ( type == OBJECT_PORTICO ) continue;
int j = 0;
Math::Vector oPos;
float oRad = 0.0f;
while ( obj->GetCrashSphere(j++, oPos, oRad) )
for (const auto& crashSphere : obj->GetAllCrashSpheres())
{
Math::Vector oPos = crashSphere.sphere.pos;
float oRad = crashSphere.sphere.radius;
float dist = Math::DistanceProjected(m_pos, oPos);
if ( dist+oRad > 32.0f &&
dist-oRad < 72.0f )

View File

@ -462,12 +462,11 @@ bool CAutoConvert::SearchVehicle()
type != OBJECT_BEE &&
type != OBJECT_WORM ) continue;
Math::Vector oPos;
float oRadius = 0.0f;
if ( !obj->GetCrashSphere(0, oPos, oRadius) ) continue;
float dist = Math::Distance(oPos, cPos)-oRadius;
if (obj->GetCrashSphereCount() == 0) continue;
if ( dist < 8.0f ) return true;
auto crashSphere = obj->GetFirstCrashSphere();
if (Math::DistanceToSphere(cPos, crashSphere.sphere) < 8.0f)
return true;
}
return false;

View File

@ -484,11 +484,11 @@ bool CAutoDerrick::SearchFree(Math::Vector pos)
ObjectType type = obj->GetType();
if ( type == OBJECT_DERRICK ) continue;
int j = 0;
Math::Vector sPos;
float sRadius = 0.0f;
while ( obj->GetCrashSphere(j++, sPos, sRadius) )
for (const auto& crashSphere : obj->GetAllCrashSpheres())
{
Math::Vector sPos = crashSphere.sphere.pos;
float sRadius = crashSphere.sphere.radius;
float distance = Math::Distance(sPos, pos);
distance -= sRadius;
if ( distance < 2.0f ) return false; // location occupied

View File

@ -433,12 +433,11 @@ bool CAutoEnergy::SearchVehicle()
type != OBJECT_BEE &&
type != OBJECT_WORM ) continue;
Math::Vector oPos;
float oRadius = 0.0f;
if ( !obj->GetCrashSphere(0, oPos, oRadius) ) continue;
float dist = Math::Distance(oPos, cPos)-oRadius;
if (obj->GetCrashSphereCount() == 0) continue;
if ( dist < 10.0f ) return true;
auto crashSphere = obj->GetFirstCrashSphere();
if (Math::DistanceToSphere(cPos, crashSphere.sphere) < 10.0f)
return true;
}
return false;

View File

@ -605,12 +605,11 @@ bool CAutoFactory::NearestVehicle()
type != OBJECT_BEE &&
type != OBJECT_WORM ) continue;
Math::Vector oPos;
float oRadius = 0.0f;
if ( !obj->GetCrashSphere(0, oPos, oRadius) ) continue;
float dist = Math::Distance(oPos, cPos)-oRadius;
if (obj->GetCrashSphereCount() == 0) continue;
if ( dist < 10.0f ) return true;
auto crashSphere = obj->GetFirstCrashSphere();
if (Math::DistanceToSphere(cPos, crashSphere.sphere) < 10.0f)
return true;
}
return false;

View File

@ -153,11 +153,11 @@ bool CAutoNest::SearchFree(Math::Vector pos)
ObjectType type = obj->GetType();
if ( type == OBJECT_NEST ) continue;
int j = 0;
Math::Vector sPos;
float sRadius = 0.0f;
while ( obj->GetCrashSphere(j++, sPos, sRadius) )
for (const auto& crashSphere : obj->GetAllCrashSpheres())
{
Math::Vector sPos = crashSphere.sphere.pos;
float sRadius = crashSphere.sphere.radius;
float distance = Math::Distance(sPos, pos);
distance -= sRadius;
if ( distance < 2.0f ) return false; // location occupied

View File

@ -368,12 +368,11 @@ bool CAutoNuclear::SearchVehicle()
type != OBJECT_BEE &&
type != OBJECT_WORM ) continue;
Math::Vector oPos;
float oRadius = 0.0f;
if ( !obj->GetCrashSphere(0, oPos, oRadius) ) continue;
float dist = Math::Distance(oPos, m_pos)-oRadius;
if (obj->GetCrashSphereCount() == 0) continue;
if ( dist < 10.0f ) return true;
auto crashSphere = obj->GetFirstCrashSphere();
if (Math::DistanceToSphere(m_pos, crashSphere.sphere) < 10.0f)
return true;
}
return false;

View File

@ -240,7 +240,7 @@ bool CAutoSafe::EventProcess(const Event &event)
m_main->CreateShortcuts();
}
m_object->FlushCrashShere();
m_object->DeleteAllCrashSpheres();
m_object->SetGlobalSphere(Math::Vector(0.0f, 0.0f, 0.0f), 0.0f);
m_sound->Play(SOUND_FINDING, m_object->GetPosition(0));

View File

@ -293,9 +293,9 @@ CObject* CAutoTower::SearchTarget(Math::Vector &impact)
}
}
Math::Vector oPos;
float radius = 0.0f;
if ( !obj->GetCrashSphere(0, oPos, radius) ) continue;
if (obj->GetCrashSphereCount() == 0) continue;
Math::Vector oPos = obj->GetFirstCrashSphere().sphere.pos;
float distance = Math::Distance(oPos, iPos);
if ( distance > TOWER_SCOPE ) continue; // too far
if ( distance < min )

50
src/object/crash_sphere.h Normal file
View File

@ -0,0 +1,50 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
*
* 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://gnu.org/licenses
*/
#pragma once
#include "math/sphere.h"
#include "math/vector.h"
#include "sound/sound_type.h"
/**
* \struct CrashSphere
* \brief Sphere used to detect object collisions
*/
struct CrashSphere
{
CrashSphere(const Math::Vector& pos = Math::Vector(),
float radius = 0.0f,
SoundType _sound = SOUND_NONE,
float _hardness = 0.45f)
: sphere(pos, radius)
, sound(_sound)
, hardness(_hardness)
{}
//! Sphere (position + radius)
//! Sphere position is given in either object or world coordinates
//! (see CObject functions for more info)
Math::Sphere sphere;
//! Sound to be played on collision
SoundType sound;
//! "Hardness" of the sphere
float hardness;
};

View File

@ -85,7 +85,7 @@ void CMotionAnt::Create(Math::Vector pos, float angle, ObjectType type,
// A vehicle must have necessarily a collision
//with a sphere of center (0, y, 0) (see GetCrashSphere).
m_object->CreateCrashSphere(Math::Vector(0.0f, -2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f);
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, -2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f));
m_object->SetGlobalSphere(Math::Vector(-0.5f, 1.0f, 0.0f), 4.0f);
// Creates the head.

View File

@ -83,7 +83,7 @@ void CMotionBee::Create(Math::Vector pos, float angle, ObjectType type,
// A vehicle must have an obligatory collision
// with a sphere of center (0, y, 0) (see GetCrashSphere).
m_object->CreateCrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f);
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f));
m_object->SetGlobalSphere(Math::Vector(-1.0f, 1.0f, 0.0f), 5.0f);
// Creates the head.

View File

@ -149,7 +149,7 @@ void CMotionHuman::Create(Math::Vector pos, float angle, ObjectType type,
m_object->SetAngleY(0, angle);
// A vehicle must have an obligatory collision with a sphere of center (0, y, 0) (see GetCrashSphere).
m_object->CreateCrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 2.0f, SOUND_AIE, 0.20f);
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 2.0f, SOUND_AIE, 0.20f));
m_object->SetGlobalSphere(Math::Vector(0.0f, 1.0f, 0.0f), 4.0f);
// Creates the head.

View File

@ -84,7 +84,7 @@ void CMotionMother::Create(Math::Vector pos, float angle, ObjectType type,
// A vehicle must have a obligatory collision
//with a sphere of center (0, y, 0) (see GetCrashSphere).
m_object->CreateCrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 20.0f, SOUND_BOUM, 0.20f);
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 20.0f, SOUND_BOUM, 0.20f));
m_object->SetGlobalSphere(Math::Vector(-2.0f, 10.0f, 0.0f), 25.0f);
// Creates the head.

View File

@ -110,7 +110,7 @@ void CMotionSpider::Create(Math::Vector pos, float angle, ObjectType type,
// A vehicle must have a obligatory collision
// with a sphere of center (0, y, 0) (see GetCrashSphere).
m_object->CreateCrashSphere(Math::Vector(0.0f, -2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f);
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, -2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f));
m_object->SetGlobalSphere(Math::Vector(-0.5f, 1.0f, 0.0f), 4.0f);
// Creates the abdomen.

View File

@ -191,26 +191,26 @@ void CMotionVehicle::Create(Math::Vector pos, float angle, ObjectType type,
type == OBJECT_MOBILErr ||
type == OBJECT_MOBILErs)
{
m_object->CreateCrashSphere(Math::Vector(0.0f, 4.0f, 0.0f), 6.5f, SOUND_BOUMm, 0.45f);
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 4.0f, 0.0f), 6.5f, SOUND_BOUMm, 0.45f));
m_object->SetGlobalSphere(Math::Vector(0.0f, 3.0f, 0.0f), 7.0f);
}
else if (type == OBJECT_MOBILEsa)
{
m_object->CreateCrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 4.5f, SOUND_BOUMm, 0.45f);
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 4.5f, SOUND_BOUMm, 0.45f));
m_object->SetGlobalSphere(Math::Vector(0.0f, 3.0f, 0.0f), 6.0f);
}
else if (type == OBJECT_MOBILEdr)
{
m_object->CreateCrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f);
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f));
m_object->SetGlobalSphere(Math::Vector(0.0f, 3.0f, 0.0f), 7.0f);
}
else if (type == OBJECT_APOLLO2)
{
m_object->CreateCrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 8.0f, SOUND_BOUMm, 0.45f);
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 8.0f, SOUND_BOUMm, 0.45f));
}
else
{
m_object->CreateCrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 4.5f, SOUND_BOUMm, 0.45f);
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 4.5f, SOUND_BOUMm, 0.45f));
m_object->SetGlobalSphere(Math::Vector(0.0f, 4.0f, 0.0f), 6.0f);
}

View File

@ -97,7 +97,7 @@ void CMotionWorm::Create(Math::Vector pos, float angle, ObjectType type,
m_object->SetAngleY(0, angle);
// A vehicle must have a obligatory collision with a sphere of center (0, y, 0) (see GetCrashSphere).
m_object->CreateCrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f);
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f));
m_object->SetGlobalSphere(Math::Vector(0.0f, 0.0f, 0.0f), 5.0f);
px = 1.0f+WORM_PART/2;

50
src/object/object.cpp Normal file
View File

@ -0,0 +1,50 @@
#include "object/object.h"
CObject::CObject(int id, ObjectType type)
: m_id(id)
, m_type(type)
{
m_implementedInterfaces.fill(false);
}
CObject::~CObject()
{
}
void CObject::AddCrashSphere(const CrashSphere& crashSphere)
{
m_crashSpheres.push_back(crashSphere);
}
CrashSphere CObject::GetFirstCrashSphere()
{
assert(m_crashSpheres.size() >= 1);
CrashSphere transformedFirstCrashSphere = m_crashSpheres[0];
TransformCrashSphere(transformedFirstCrashSphere.sphere);
return transformedFirstCrashSphere;
}
std::vector<CrashSphere> CObject::GetAllCrashSpheres()
{
std::vector<CrashSphere> allCrashSpheres;
for (const auto& crashSphere : m_crashSpheres)
{
CrashSphere transformedCrashSphere = crashSphere;
TransformCrashSphere(transformedCrashSphere.sphere);
allCrashSpheres.push_back(transformedCrashSphere);
}
return allCrashSpheres;
}
int CObject::GetCrashSphereCount()
{
return m_crashSpheres.size();
}
void CObject::DeleteAllCrashSpheres()
{
m_crashSpheres.clear();
}

View File

@ -24,6 +24,7 @@
#pragma once
#include "object/crash_sphere.h"
#include "object/object_interface_type.h"
#include "object/old_object_interface.h"
@ -49,19 +50,13 @@ class CObject : public COldObjectInterface
{
protected:
//! Constructor only accessible to subclasses
CObject(int id, ObjectType type)
: m_id(id)
, m_type(type)
{
m_implementedInterfaces.fill(false);
}
CObject(int id, ObjectType type);
public:
CObject(const CObject&) = delete;
CObject& operator=(const CObject&) = delete;
virtual ~CObject()
{}
virtual ~CObject();
//! Returns object type
inline ObjectType GetType() const
@ -86,9 +81,27 @@ public:
return m_implementedInterfaces[static_cast<int>(type)];
}
//! Adds a new crash sphere
/** Crash sphere position is given in object coordinates */
void AddCrashSphere(const CrashSphere& crashSphere);
//! Returns total number of crash spheres
int GetCrashSphereCount();
//! Returns the first crash sphere (assumes it exists)
/** Crash sphere position is returned in world coordinates */
CrashSphere GetFirstCrashSphere();
//! Returns all crash spheres
/** Crash sphere position is returned in world coordinates */
std::vector<CrashSphere> GetAllCrashSpheres();
//! Removes all crash spheres
void DeleteAllCrashSpheres();
protected:
//! Transform crash sphere by object's world matrix
virtual void TransformCrashSphere(Math::Sphere& crashSphere) = 0;
protected:
const int m_id; //!< unique identifier
ObjectType m_type; //!< object type
std::string m_name; //!< object class name
ObjectInterfaceTypes m_implementedInterfaces; //! interfaces that the object implements
ObjectInterfaceTypes m_implementedInterfaces; //!< interfaces that the object implements
std::vector<CrashSphere> m_crashSpheres; //!< crash spheres
};

File diff suppressed because it is too large Load Diff

View File

@ -286,7 +286,7 @@ COldObject::COldObject(int id)
m_cmdLine[i] = NAN;
}
FlushCrashShere();
DeleteAllCrashSpheres();
m_globalSpherePos = Math::Vector(0.0f, 0.0f, 0.0f);
m_globalSphereRadius = 0.0f;
m_jostlingSpherePos = Math::Vector(0.0f, 0.0f, 0.0f);
@ -1061,86 +1061,30 @@ int COldObject::SearchDescendant(int parent, int n)
return -1;
}
// Removes all spheres used for collisions.
void COldObject::FlushCrashShere()
void COldObject::TransformCrashSphere(Math::Sphere& crashSphere)
{
m_crashSphereUsed = 0;
}
// Adds a new sphere.
int COldObject::CreateCrashSphere(Math::Vector pos, float radius, SoundType sound,
float hardness)
{
float zoom;
if ( m_crashSphereUsed >= MAXCRASHSPHERE ) return -1;
zoom = GetZoomX(0);
m_crashSpherePos[m_crashSphereUsed] = pos;
m_crashSphereRadius[m_crashSphereUsed] = radius*zoom;
m_crashSphereHardness[m_crashSphereUsed] = hardness;
m_crashSphereSound[m_crashSphereUsed] = sound;
return m_crashSphereUsed++;
}
// Returns the number of spheres.
int COldObject::GetCrashSphereTotal()
{
return m_crashSphereUsed;
}
// Returns a sphere for collisions.
// The position is absolute in the world.
bool COldObject::GetCrashSphere(int rank, Math::Vector &pos, float &radius)
{
if ( rank < 0 || rank >= m_crashSphereUsed )
{
pos = m_objectPart[0].position;
radius = 0.0f;
return false;
}
crashSphere.radius *= GetZoomX(0);
// Returns to the sphere collisions,
// which ignores the inclination of the vehicle.
// which ignores the tilt of the vehicle.
// This is necessary to collisions with vehicles,
// so as not to reflect SetTilt, for example.
// The sphere must necessarily have a center (0, y, 0).
if ( rank == 0 && m_crashSphereUsed == 1 &&
m_crashSpherePos[0].x == 0.0f &&
m_crashSpherePos[0].z == 0.0f )
if (m_crashSpheres.size() == 1 &&
crashSphere.pos.x == 0.0f &&
crashSphere.pos.z == 0.0f )
{
pos = m_objectPart[0].position + m_crashSpherePos[0];
radius = m_crashSphereRadius[0];
return true;
crashSphere.pos += m_objectPart[0].position;
return;
}
if ( m_objectPart[0].bTranslate ||
m_objectPart[0].bRotate )
if (m_objectPart[0].bTranslate ||
m_objectPart[0].bRotate)
{
UpdateTransformObject();
}
pos = Math::Transform(m_objectPart[0].matWorld, m_crashSpherePos[rank]);
radius = m_crashSphereRadius[rank];
return true;
}
// Returns the hardness of a sphere.
SoundType COldObject::GetCrashSphereSound(int rank)
{
return m_crashSphereSound[rank];
}
// Returns the hardness of a sphere.
float COldObject::GetCrashSphereHardness(int rank)
{
return m_crashSphereHardness[rank];
crashSphere.pos = Math::Transform(m_objectPart[0].matWorld, crashSphere.pos);
}
// Specifies the global sphere, relative to the object.

View File

@ -29,7 +29,6 @@
// The father of all parts must always be the part number zero!
const int OBJECTMAXPART = 40;
const int MAXCRASHSPHERE = 40;
const int OBJECTMAXDESELLIST = 10;
const int OBJECTMAXCMDLINE = 20;
@ -102,12 +101,6 @@ public:
int GetShadowLight() override;
int GetEffectLight() override;
void FlushCrashShere() override;
int CreateCrashSphere(Math::Vector pos, float radius, SoundType sound, float hardness=0.45f) override;
int GetCrashSphereTotal() override;
bool GetCrashSphere(int rank, Math::Vector &pos, float &radius) override;
float GetCrashSphereHardness(int rank) override;
SoundType GetCrashSphereSound(int rank) override;
void SetGlobalSphere(Math::Vector pos, float radius) override;
void GetGlobalSphere(Math::Vector &pos, float &radius) override;
void GetJostlingSphere(Math::Vector &pos, float &radius) override;
@ -319,6 +312,7 @@ protected:
bool UpdateTransformObject(int part, bool bForceUpdate);
bool UpdateTransformObject();
void UpdateSelectParticle();
void TransformCrashSphere(Math::Sphere &crashSphere) override;
protected:
Gfx::CEngine* m_engine;
@ -391,11 +385,6 @@ protected:
float m_param;
int m_team;
int m_crashSphereUsed; // number of spheres used
Math::Vector m_crashSpherePos[MAXCRASHSPHERE];
float m_crashSphereRadius[MAXCRASHSPHERE];
float m_crashSphereHardness[MAXCRASHSPHERE];
SoundType m_crashSphereSound[MAXCRASHSPHERE];
Math::Vector m_globalSpherePos;
float m_globalSphereRadius;
Math::Vector m_jostlingSpherePos;

View File

@ -98,12 +98,6 @@ public:
virtual int GetShadowLight() = 0;
virtual int GetEffectLight() = 0;
virtual void FlushCrashShere() = 0;
virtual int CreateCrashSphere(Math::Vector pos, float radius, SoundType sound, float hardness=0.45f) = 0;
virtual int GetCrashSphereTotal() = 0;
virtual bool GetCrashSphere(int rank, Math::Vector &pos, float &radius) = 0;
virtual float GetCrashSphereHardness(int rank) = 0;
virtual SoundType GetCrashSphereSound(int rank) = 0;
virtual void SetGlobalSphere(Math::Vector pos, float radius) = 0;
virtual void GetGlobalSphere(Math::Vector &pos, float &radius) = 0;
virtual void GetJostlingSphere(Math::Vector &pos, float &radius) = 0;

View File

@ -4212,11 +4212,11 @@ float CRobotMain::SearchNearestObject(Math::Vector center, CObject *exclu)
min = Math::Min(min, dist);
}
int j = 0;
Math::Vector oPos;
float oRadius;
while (obj->GetCrashSphere(j++, oPos, oRadius))
for (const auto& crashSphere : obj->GetAllCrashSpheres())
{
Math::Vector oPos = crashSphere.sphere.pos;
float oRadius = crashSphere.sphere.radius;
float dist = Math::Distance(center, oPos)-oRadius;
if (dist < 0.0f) dist = 0.0f;
min = Math::Min(min, dist);
@ -4348,10 +4348,9 @@ void CRobotMain::ShowDropZone(CObject* metal, CObject* transporter)
}
else
{
int j = 0;
while (obj->GetCrashSphere(j++, oPos, oRadius))
for (const auto& crashSphere : obj->GetAllCrashSpheres())
{
float dist = Math::Distance(center, oPos)-oRadius;
float dist = Math::Distance(center, crashSphere.sphere.pos)-crashSphere.sphere.radius;
oMax = Math::Min(oMax, dist);
}
}
@ -4375,10 +4374,9 @@ void CRobotMain::ShowDropZone(CObject* metal, CObject* transporter)
type == OBJECT_SAFE ||
type == OBJECT_HUSTON ) // building?
{
int j = 0;
while (obj->GetCrashSphere(j++, oPos, oRadius))
for (const auto& crashSphere : obj->GetAllCrashSpheres())
{
float dist = Math::Distance(center, oPos)-oRadius-BUILDMARGIN;
float dist = Math::Distance(center, crashSphere.sphere.pos)-crashSphere.sphere.radius-BUILDMARGIN;
oMax = Math::Min(oMax, dist);
}
}

View File

@ -86,8 +86,8 @@ std::unique_ptr<CExchangePost> CExchangePost::Create(
obj->SetAngleY(2+i*2, 2.0f*Math::PI/3.0f*i);
}
obj->CreateCrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f);
obj->CreateCrashSphere(Math::Vector(0.0f, 11.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f);
obj->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f));
obj->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 11.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f));
obj->SetGlobalSphere(Math::Vector(0.0f, 5.0f, 0.0f), 6.0f);
obj->CreateShadowCircle(8.0f, 1.0f);

View File

@ -575,7 +575,7 @@ bool CTaskBuild::Abort()
Error CTaskBuild::FlatFloor()
{
ObjectType type;
Math::Vector center, pos, oPos, bPos;
Math::Vector center, pos, bPos;
Math::Point c, p;
float radius, max, oRadius, bRadius = 0.0f, angle, dist;
int j;
@ -624,21 +624,23 @@ Error CTaskBuild::FlatFloor()
type = pObj->GetType();
if ( type == OBJECT_BASE )
{
oPos = pObj->GetPosition(0);
Math::Vector oPos = pObj->GetPosition(0);
dist = Math::Distance(center, oPos)-80.0f;
if ( dist < max )
{
max = dist;
bPos = oPos;
bRadius = oRadius;
bRadius = 0.0f;
bBase = true;
}
}
else
{
j = 0;
while ( pObj->GetCrashSphere(j++, oPos, oRadius) )
for (const auto& crashSphere : pObj->GetAllCrashSpheres())
{
Math::Vector oPos = crashSphere.sphere.pos;
float oRadius = crashSphere.sphere.radius;
dist = Math::Distance(center, oPos)-oRadius;
if ( dist < max )
{
@ -686,9 +688,11 @@ Error CTaskBuild::FlatFloor()
type == OBJECT_SAFE ||
type == OBJECT_HUSTON ) // building?
{
j = 0;
while ( pObj->GetCrashSphere(j++, oPos, oRadius) )
for (const auto& crashSphere : pObj->GetAllCrashSpheres())
{
Math::Vector oPos = crashSphere.sphere.pos;
float oRadius = crashSphere.sphere.radius;
dist = Math::Distance(center, oPos)-oRadius;
if ( dist < max )
{

View File

@ -552,11 +552,11 @@ CObject* CTaskGoto::WormSearch(Math::Vector &impact)
if ( obj->GetVirusMode() ) continue; // object infected?
Math::Vector oPos;
float radius = 0.0f;
if ( !obj->GetCrashSphere(0, oPos, radius) ) continue;
if (obj->GetCrashSphereCount() == 0) continue;
Math::Vector oPos = obj->GetFirstCrashSphere().sphere.pos;
float distance = Math::DistanceProjected(oPos, iPos);
if ( distance < min )
if (distance < min)
{
min = distance;
best = obj;
@ -1294,50 +1294,44 @@ bool CTaskGoto::GetHotPoint(CObject *pObj, Math::Vector &pos,
bool CTaskGoto::LeakSearch(Math::Vector &pos, float &delay)
{
CObject *pObstacle = nullptr;
Math::Vector iPos, oPos, bPos;
float iRadius, oRadius, bRadius, dist, min, dir;
int j;
if (!m_physics->GetLand()) return false; // in flight?
if ( !m_physics->GetLand() ) return false; // in flight?
Math::Sphere crashSphere = m_object->GetFirstCrashSphere().sphere;
m_object->GetCrashSphere(0, iPos, iRadius);
min = 100000.0f;
bRadius = 0.0f;
for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects())
float min = 100000.0f;
CObject* obstacle = nullptr;
Math::Sphere obstacleCrashSphere;
for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects())
{
if ( pObj == m_object ) continue;
if ( !pObj->GetActive() ) continue;
if ( pObj->GetTransporter() != 0 ) continue; // object transported?
if ( obj == m_object ) continue;
if ( !obj->GetActive() ) continue;
if ( obj->GetTransporter() != nullptr ) continue; // object transported?
j = 0;
while ( pObj->GetCrashSphere(j++, oPos, oRadius) )
for (const auto& objCrashSphere : obj->GetAllCrashSpheres())
{
dist = Math::DistanceProjected(oPos, iPos);
if ( dist < min )
float dist = Math::DistanceProjected(crashSphere.pos, objCrashSphere.sphere.pos);
if (dist < min)
{
min = dist;
bPos = oPos;
bRadius = oRadius;
pObstacle = pObj;
obstacleCrashSphere = objCrashSphere.sphere;
obstacle = obj;
}
}
}
if ( min > iRadius+bRadius+4.0f ) return false;
if (min > crashSphere.radius + obstacleCrashSphere.radius + 4.0f) return false;
m_bLeakRecede = false;
dist = 4.0f;
dir = 1.0f;
if ( pObstacle->GetType() == OBJECT_FACTORY )
float dist = 4.0f;
float dir = 1.0f;
if (obstacle->GetType() == OBJECT_FACTORY)
{
dist = 16.0f;
dir = -1.0f;
m_bLeakRecede = true; // simply recoils
}
pos = bPos;
pos = obstacleCrashSphere.pos;
delay = m_physics->GetLinTimeLength(dist, dir);
return true;
}
@ -1394,10 +1388,8 @@ void CTaskGoto::ComputeRepulse(Math::Point &dir)
}
#else
ObjectType iType, oType;
Math::Vector iPos, oPos;
Math::Point repulse;
float gDist, add, addi, fac, dist, iRadius, oRadius;
int j;
float gDist, add, addi, fac, dist;
bool bAlien;
dir.x = 0.0f;
@ -1407,7 +1399,10 @@ void CTaskGoto::ComputeRepulse(Math::Point &dir)
iType = m_object->GetType();
if ( iType == OBJECT_WORM || iType == OBJECT_CONTROLLER ) return;
m_object->GetCrashSphere(0, iPos, iRadius);
auto firstCrashSphere = m_object->GetFirstCrashSphere();
Math::Vector iPos = firstCrashSphere.sphere.pos;
float iRadius = firstCrashSphere.sphere.radius;
gDist = Math::Distance(iPos, m_goal);
add = m_physics->GetLinStopLength()*1.1f; // braking distance
@ -1524,9 +1519,11 @@ void CTaskGoto::ComputeRepulse(Math::Point &dir)
addi = 2.0f; // between wasps, do not annoy too much
}
j = 0;
while ( pObj->GetCrashSphere(j++, oPos, oRadius) )
for (const auto& crashSphere : pObj->GetAllCrashSpheres())
{
Math::Vector oPos = crashSphere.sphere.pos;
float oRadius = crashSphere.sphere.radius;
if ( oPos.y-oRadius > iPos.y+iRadius ) continue;
if ( oPos.y+oRadius < iPos.y-iRadius ) continue;
@ -1559,34 +1556,33 @@ void CTaskGoto::ComputeRepulse(Math::Point &dir)
void CTaskGoto::ComputeFlyingRepulse(float &dir)
{
ObjectType oType;
Math::Vector iPos, oPos;
float add, fac, dist, iRadius, oRadius, repulse;
int j;
auto firstCrashSphere = m_object->GetFirstCrashSphere();
Math::Vector iPos = firstCrashSphere.sphere.pos;
float iRadius = firstCrashSphere.sphere.radius;
m_object->GetCrashSphere(0, iPos, iRadius);
add = 0.0f;
fac = 1.5f;
float add = 0.0f;
float fac = 1.5f;
dir = 0.0f;
for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects())
{
if ( pObj == m_object ) continue;
if ( pObj->GetTransporter() != 0 ) continue;
if ( pObj->GetTransporter() != nullptr ) continue;
oType = pObj->GetType();
ObjectType oType = pObj->GetType();
if ( oType == OBJECT_WORM ) continue;
j = 0;
while ( pObj->GetCrashSphere(j++, oPos, oRadius) )
for (const auto& crashSphere : pObj->GetAllCrashSpheres())
{
Math::Vector oPos = crashSphere.sphere.pos;
float oRadius = crashSphere.sphere.radius;
oRadius += iRadius+add;
dist = Math::DistanceProjected(oPos, iPos);
float dist = Math::DistanceProjected(oPos, iPos);
if ( dist <= oRadius )
{
repulse = iPos.y-oPos.y;
float repulse = iPos.y-oPos.y;
dist = powf(dist/oRadius, fac);
dist = 0.2f-0.2f*dist;
@ -1873,30 +1869,28 @@ bool CTaskGoto::BitmapTestLine(const Math::Vector &start, const Math::Vector &go
void CTaskGoto::BitmapObject()
{
ObjectType type;
Math::Vector iPos, oPos;
float iRadius, oRadius, h;
int j;
m_object->GetCrashSphere(0, iPos, iRadius);
auto firstCrashSphere = m_object->GetFirstCrashSphere();
float iRadius = firstCrashSphere.sphere.radius;
for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects())
{
type = pObj->GetType();
ObjectType type = pObj->GetType();
if ( pObj == m_object ) continue;
if ( pObj == m_bmCargoObject ) continue;
if ( pObj->GetTransporter() != 0 ) continue;
h = m_terrain->GetFloorLevel(pObj->GetPosition(0), false);
float h = m_terrain->GetFloorLevel(pObj->GetPosition(0), false);
if ( m_physics->GetType() == TYPE_FLYING && m_altitude > 0.0f )
{
h += m_altitude;
}
j = 0;
while ( pObj->GetCrashSphere(j++, oPos, oRadius) )
for (const auto& crashSphere : pObj->GetAllCrashSpheres())
{
Math::Vector oPos = crashSphere.sphere.pos;
float oRadius = crashSphere.sphere.radius;
if ( m_physics->GetType() == TYPE_FLYING && m_altitude > 0.0f ) // flying?
{
if ( oPos.y-oRadius > h+8.0f ||

View File

@ -953,16 +953,18 @@ CObject* CTaskManip::SearchOtherObject(bool bAdvance, Math::Vector &pos,
Character* character;
CObject* pPower;
Math::Matrix* mat;
Math::Vector iPos, oPos;
ObjectType type, powerType;
float iAngle, iRad, oAngle, oLimit, aLimit, dLimit;
float iAngle, oAngle, oLimit, aLimit, dLimit;
distance = 1000000.0f;
angle = 0.0f;
if ( m_bSubm ) return 0; // impossible with the submarine
if ( !m_object->GetCrashSphere(0, iPos, iRad) ) return 0;
if (m_object->GetCrashSphereCount() == 0) return 0;
Math::Vector iPos = m_object->GetFirstCrashSphere().sphere.pos;
iAngle = m_object->GetAngleY(0);
iAngle = Math::NormAngle(iAngle); // 0..2*Math::PI
@ -1027,7 +1029,7 @@ CObject* CTaskManip::SearchOtherObject(bool bAdvance, Math::Vector &pos,
mat = pObj->GetWorldMatrix(0);
character = pObj->GetCharacter();
oPos = Transform(*mat, character->posPower);
Math::Vector oPos = Transform(*mat, character->posPower);
oAngle = pObj->GetAngleY(0);
if ( type == OBJECT_TOWER ||
@ -1330,12 +1332,9 @@ bool CTaskManip::IsFreeDeposeObject(Math::Vector pos)
if ( !obj->GetActive() ) continue; // inactive?
if ( obj->GetTransporter() != nullptr ) continue; // object transported?
Math::Vector oPos;
float oRadius = 0.0f;
int j = 0;
while ( obj->GetCrashSphere(j++, oPos, oRadius) )
for (const auto& crashSphere : obj->GetAllCrashSpheres())
{
if ( Math::Distance(iPos, oPos)-(oRadius+1.0f) < 2.0f )
if ( Math::Distance(iPos, crashSphere.sphere.pos)-(crashSphere.sphere.radius+1.0f) < 2.0f )
{
return false; // location occupied
}

View File

@ -318,12 +318,11 @@ bool CTaskReset::SearchVehicle()
type != OBJECT_BEE &&
type != OBJECT_WORM ) continue;
Math::Vector oPos;
float oRadius = 0.0f;
if ( !obj->GetCrashSphere(0, oPos, oRadius) ) continue;
float dist = Math::Distance(oPos, m_goal)-oRadius;
if (obj->GetCrashSphereCount() == 0) continue;
if ( dist < 5.0f ) return true;
auto crashSphere = obj->GetFirstCrashSphere();
if (Math::DistanceToSphere(m_goal, crashSphere.sphere) < 5.0f)
return true;
}
return false;

View File

@ -364,11 +364,15 @@ CObject* CTaskTake::SearchFriendObject(float &angle,
Character* character;
CObject* pPower;
Math::Matrix* mat;
Math::Vector iPos, oPos;
ObjectType type, powerType;
float iAngle, iRad, distance;
float iAngle, distance;
if (m_object->GetCrashSphereCount() == 0) return 0;
auto crashSphere = m_object->GetFirstCrashSphere();
Math::Vector iPos = crashSphere.sphere.pos;
float iRad = crashSphere.sphere.radius;
if ( !m_object->GetCrashSphere(0, iPos, iRad) ) return 0;
iAngle = m_object->GetAngleY(0);
iAngle = Math::NormAngle(iAngle); // 0..2*Math::PI
@ -422,7 +426,7 @@ CObject* CTaskTake::SearchFriendObject(float &angle,
mat = pObj->GetWorldMatrix(0);
character = pObj->GetCharacter();
oPos = Transform(*mat, character->posPower);
Math::Vector oPos = Transform(*mat, character->posPower);
distance = fabs(Math::Distance(oPos, iPos) - (iRad+1.0f));
if ( distance <= dLimit )
@ -555,13 +559,8 @@ bool CTaskTake::TransporterDeposeObject()
bool CTaskTake::IsFreeDeposeObject(Math::Vector pos)
{
Math::Matrix* mat;
Math::Vector iPos, oPos;
float oRadius;
int j;
mat = m_object->GetWorldMatrix(0);
iPos = Transform(*mat, pos);
Math::Matrix* mat = m_object->GetWorldMatrix(0);
Math::Vector iPos = Transform(*mat, pos);
for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects())
{
@ -569,10 +568,9 @@ bool CTaskTake::IsFreeDeposeObject(Math::Vector pos)
if ( !pObj->GetActive() ) continue; // inactive?
if ( pObj->GetTransporter() != 0 ) continue; // object transported?
j = 0;
while ( pObj->GetCrashSphere(j++, oPos, oRadius) )
for (const auto& crashSphere : pObj->GetAllCrashSpheres())
{
if ( Math::Distance(iPos, oPos)-(oRadius+1.0f) < 1.0f )
if ( Math::Distance(iPos, crashSphere.sphere.pos)-(crashSphere.sphere.radius+1.0f) < 1.0f )
{
return false; // location occupied
}

View File

@ -2511,10 +2511,9 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle)
{
CPhysics* ph;
Math::Matrix matRotate;
Math::Vector iPos, oPos, iiPos, oAngle, oSpeed;
SoundType sound;
float iRad, oRad, distance, force, volume;
int j, colType;
Math::Vector iPos, oAngle, oSpeed;
float distance, force, volume;
int colType;
ObjectType iType, oType;
if ( m_object->GetRuin() ) return 0; // is burning or exploding?
@ -2522,7 +2521,10 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle)
// iiPos = sphere center is the old position.
// iPos = sphere center has the new position.
m_object->GetCrashSphere(0, iiPos, iRad);
auto firstCrashSphere = m_object->GetFirstCrashSphere();
Math::Vector iiPos = firstCrashSphere.sphere.pos;
float iRad = firstCrashSphere.sphere.radius;
iPos = iiPos + (pos - m_object->GetPosition(0));
iType = m_object->GetType();
@ -2547,10 +2549,12 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle)
if ( iType == OBJECT_MOTHER && oType == OBJECT_EGG ) continue;
if ( iType == OBJECT_EGG && oType == OBJECT_MOTHER ) continue;
pObj->GetJostlingSphere(oPos, oRad);
if ( oRad > 0.0f )
Math::Vector jostlingSpherePos;
float jostlingSphereRadius = 0.0f;
pObj->GetJostlingSphere(jostlingSpherePos, jostlingSphereRadius);
if ( jostlingSphereRadius > 0.0f )
{
JostleObject(pObj, iPos, iRad, oPos, oRad);
JostleObject(pObj, iPos, iRad, jostlingSpherePos, jostlingSphereRadius);
}
if ( iType == OBJECT_MOTHER ||
@ -2580,7 +2584,7 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle)
!m_object->GetResetBusy() &&
m_object->GetTrainer() ) // driving vehicle?
{
oPos = pObj->GetPosition(0);
Math::Vector oPos = pObj->GetPosition(0);
distance = Math::DistanceProjected(oPos, iPos);
if ( distance < 4.0f )
{
@ -2591,7 +2595,7 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle)
if ( oType == OBJECT_TARGET2 )
{
oPos = pObj->GetPosition(0);
Math::Vector oPos = pObj->GetPosition(0);
distance = Math::Distance(oPos, iPos);
if ( distance < 10.0f*1.5f )
{
@ -2600,9 +2604,11 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle)
}
}
j = 0;
while ( pObj->GetCrashSphere(j++, oPos, oRad) )
for (const auto& crashSphere : pObj->GetAllCrashSpheres())
{
Math::Vector oPos = crashSphere.sphere.pos;
float oRad = crashSphere.sphere.radius;
if ( iType == OBJECT_MOTHER && oRad <= 1.2f ) continue;
if ( iType == OBJECT_ANT && oRad <= 1.2f ) continue;
if ( iType == OBJECT_SPIDER && oRad <= 1.2f ) continue;
@ -2618,11 +2624,10 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle)
m_bCollision = true;
m_bObstacle = true;
sound = pObj->GetCrashSphereSound(j-1);
if ( sound != SOUND_CLICK )
if (crashSphere.sound != SOUND_CLICK)
{
force = fabs(m_linMotion.realSpeed.x);
force *= pObj->GetCrashSphereHardness(j-1)*2.0f;
force *= crashSphere.hardness*2.0f;
if ( ExploOther(iType, pObj, oType, force) ) continue;
colType = ExploHimself(iType, oType, force);
if ( colType == 2 ) return 2; // destroyed?
@ -2630,12 +2635,12 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle)
}
force = m_linMotion.realSpeed.Length();
force *= pObj->GetCrashSphereHardness(j-1);
force *= crashSphere.hardness;
volume = fabs(force*0.05f);
if ( volume > 1.0f ) volume = 1.0f;
if ( sound != SOUND_CLICK )
if ( crashSphere.sound != SOUND_CLICK )
{
m_sound->Play(sound, m_object->GetPosition(0), volume);
m_sound->Play(crashSphere.sound, m_object->GetPosition(0), volume);
}
if ( iType == OBJECT_HUMAN && volume > 0.5f )
{