2017-01-29 17:13:01 +01:00
// Cyphesis Online RPG Server and AI Engine
2017-02-14 17:57:40 +01:00
// Copyright (C) 2017 Erik Ogenvik
2017-01-29 17:13:01 +01:00
//
// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
# ifdef NDEBUG
# undef NDEBUG
# endif
# ifndef DEBUG
# define DEBUG
# endif
2020-07-05 01:33:34 +02:00
# include "../TestBaseWithContext.h"
2020-01-20 23:17:55 +01:00
# include "../TestWorld.h"
2017-01-29 17:13:01 +01:00
# include "server/Ruleset.h"
2018-10-31 21:38:35 +01:00
# include "rules/simulation/Entity.h"
2017-01-29 17:13:01 +01:00
# include "common/debug.h"
# include <Atlas/Objects/Anonymous.h>
2018-02-26 12:55:05 +01:00
# include <wfmath/atlasconv.h>
2017-01-29 17:13:01 +01:00
2018-11-03 16:43:33 +01:00
# include <rules/simulation/PhysicalDomain.h>
2018-01-10 15:11:20 +01:00
# include "physics/Convert.h"
2018-11-03 16:43:33 +01:00
# include <rules/simulation/TerrainProperty.h>
2017-01-29 17:13:01 +01:00
# include <Mercator/BasePoint.h>
# include <Mercator/Terrain.h>
2018-11-03 16:43:33 +01:00
# include <rules/simulation/PropelProperty.h>
# include <rules/simulation/AngularFactorProperty.h>
# include <rules/simulation/GeometryProperty.h>
# include "rules/simulation/PhysicalWorld.h"
2018-12-16 20:33:13 +01:00
# include "rules/BBoxProperty.h"
2018-01-10 15:11:20 +01:00
# include <BulletCollision/CollisionShapes/btBoxShape.h>
2018-03-05 22:14:58 +01:00
# include <BulletDynamics/Dynamics/btRigidBody.h>
2018-11-03 16:43:33 +01:00
# include <rules/simulation/TerrainModProperty.h>
2018-10-31 21:38:35 +01:00
# include <rules/simulation/EntityProperty.h>
2019-09-15 10:19:20 +02:00
# include <rules/simulation/ModeDataProperty.h>
2020-04-25 16:36:43 +02:00
# include <rules/simulation/VisibilityDistanceProperty.h>
2020-01-20 23:17:55 +01:00
# include "../stubs/common/stubMonitors.h"
2017-01-29 17:13:01 +01:00
using Atlas : : Message : : Element ;
using Atlas : : Message : : ListType ;
using Atlas : : Message : : MapType ;
using Atlas : : Objects : : Root ;
using Atlas : : Objects : : Entity : : Anonymous ;
using Atlas : : Objects : : Entity : : RootEntity ;
using String : : compose ;
2019-12-16 23:43:44 +01:00
namespace Cyphesis {
2020-01-04 16:15:24 +01:00
template < >
2020-07-05 01:33:34 +02:00
int AssertBase : : assertFuzzyEqual ( const char * l , const WFMath : : Point < 3 > & lval ,
const char * r , const WFMath : : Point < 3 > & rval ,
const char * e , const WFMath : : CoordType & epsilon ,
const char * func , const char * file , int line )
2019-12-16 23:43:44 +01:00
{
if ( ! lval . isEqualTo ( rval , epsilon ) ) {
addFailure ( String : : compose ( " %1:%2: %3: Assertion '%4 ~= %5' failed. "
" %6 != %7 " ,
file , line , func , l , r , lval , rval ) ) ;
return - 1 ;
}
return 0 ;
}
}
2018-01-11 17:07:05 +01:00
class TestPhysicalDomain : public PhysicalDomain
{
2017-09-01 13:19:27 +02:00
public :
2018-04-19 10:19:35 +02:00
explicit TestPhysicalDomain ( LocatedEntity & entity ) :
2020-01-04 16:15:24 +01:00
PhysicalDomain ( entity )
2018-01-11 17:07:05 +01:00
{
2017-09-01 13:19:27 +02:00
}
2018-04-19 10:19:35 +02:00
PhysicalWorld * test_getPhysicalWorld ( ) const
2018-01-11 17:07:05 +01:00
{
2019-11-17 18:43:43 +01:00
return m_dynamicsWorld . get ( ) ;
2017-09-01 13:19:27 +02:00
}
2018-04-19 10:19:35 +02:00
btRigidBody * test_getRigidBody ( long id )
{
2019-11-17 18:43:43 +01:00
return btRigidBody : : upcast ( m_entries . find ( id ) - > second - > collisionObject . get ( ) ) ;
2018-04-19 10:19:35 +02:00
}
2018-04-27 14:47:16 +02:00
2018-05-23 22:50:41 +02:00
void test_childEntityPropertyApplied ( const std : : string & name , PropertyBase & prop , long id )
{
2021-06-18 22:44:30 +02:00
childEntityPropertyApplied ( name , prop , * m_entries . find ( id ) - > second ) ;
2018-04-27 14:47:16 +02:00
}
2017-09-01 13:19:27 +02:00
} ;
2020-01-04 16:15:24 +01:00
double epsilon = 0.0001 ;
2017-01-29 17:13:01 +01:00
2020-07-05 01:33:34 +02:00
struct TestContext
2020-01-04 16:15:24 +01:00
{
2020-07-05 01:33:34 +02:00
long m_id_counter ;
2017-01-29 17:13:01 +01:00
2020-07-05 01:33:34 +02:00
long newId ( )
2020-01-04 16:15:24 +01:00
{
return + + m_id_counter ;
}
2020-07-05 01:33:34 +02:00
} ;
2018-03-23 19:22:35 +01:00
2018-03-05 22:14:58 +01:00
2020-07-05 01:33:34 +02:00
struct Tested : public Cyphesis : : TestBaseWithContext < TestContext >
{
Tested ( )
2020-01-04 16:15:24 +01:00
{
2020-07-05 01:33:34 +02:00
ADD_TEST ( Tested : : test_deleteWithPlanted ) ;
ADD_TEST ( Tested : : test_scaleBbox ) ;
ADD_TEST ( Tested : : test_movePlantedAndResting ) ;
ADD_TEST ( Tested : : test_plantedOn ) ;
ADD_TEST ( Tested : : test_terrainMods ) ;
ADD_TEST ( Tested : : test_lake_rotated ) ;
ADD_TEST ( Tested : : test_lake ) ;
ADD_TEST ( Tested : : test_ocean ) ;
ADD_TEST ( Tested : : test_placement ) ;
ADD_TEST ( Tested : : test_convert ) ;
ADD_TEST ( Tested : : test_terrainPrecision ) ;
ADD_TEST ( Tested : : test_fallToBottom ) ;
ADD_TEST ( Tested : : test_standOnFixed ) ;
ADD_TEST ( Tested : : test_fallToTerrain ) ;
ADD_TEST ( Tested : : test_collision ) ;
ADD_TEST ( Tested : : test_mode ) ;
ADD_TEST ( Tested : : test_determinism ) ;
ADD_TEST ( Tested : : test_zoffset ) ;
ADD_TEST ( Tested : : test_zscaledoffset ) ;
ADD_TEST ( Tested : : test_visibility ) ;
ADD_TEST ( Tested : : test_stairs ) ;
2020-01-04 16:15:24 +01:00
}
2018-02-26 12:55:05 +01:00
2020-07-05 01:33:34 +02:00
void test_scaleBbox ( TestContext & context )
2020-01-04 16:15:24 +01:00
{
double tickSize = 1.0 / 15.0 ;
double time = 0 ;
2018-02-26 12:55:05 +01:00
2020-01-04 16:15:24 +01:00
OpVector res ;
2018-02-26 12:55:05 +01:00
2021-05-23 21:31:36 +02:00
TypeNode rockType ( " rock " ) ;
2018-01-11 17:07:05 +01:00
2021-05-23 21:31:36 +02:00
Property < double > massProp { } ;
massProp . data ( ) = 10000 ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
ModeProperty plantedProperty { } ;
plantedProperty . set ( " planted " ) ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
ModeProperty freeProperty { } ;
freeProperty . set ( " free " ) ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
Entity rootEntity ( context . newId ( ) ) ;
rootEntity . incRef ( ) ;
2021-06-18 22:44:30 +02:00
rootEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
rootEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 64 , 0 , - 64 ) , WFMath : : Point < 3 > ( 64 , 64 , 64 ) ) ;
2021-05-23 21:31:36 +02:00
std : : unique_ptr < TestPhysicalDomain > domain ( new TestPhysicalDomain ( rootEntity ) ) ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
Entity plantedEntity ( context . newId ( ) ) ;
plantedEntity . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( plantedProperty . copy ( ) ) ) ;
plantedEntity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
plantedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 0 , 0 , 0 ) ;
plantedEntity . requirePropertyClassFixed < OrientationProperty > ( ) . data ( ) = WFMath : : Quaternion : : IDENTITY ( ) ;
2017-01-29 23:01:08 +01:00
2021-06-18 22:44:30 +02:00
auto & bBoxProperty = plantedEntity . requirePropertyClassFixed < BBoxProperty > ( ) ;
2021-05-23 21:31:36 +02:00
bBoxProperty . data ( ) = { { - 1 , 0 , - 1 } ,
{ 1 , 1 , 1 } } ;
2021-06-18 22:44:30 +02:00
plantedEntity . applyProperty ( bBoxProperty ) ;
2017-02-14 17:57:40 +01:00
2021-05-23 21:31:36 +02:00
domain - > addEntity ( plantedEntity ) ;
2017-02-14 21:41:01 +01:00
2020-01-04 16:15:24 +01:00
btVector3 from ( 0 , 10 , 0 ) ;
btVector3 to ( 0 , - 10 , 0 ) ;
2017-02-15 21:48:43 +01:00
2020-01-04 16:15:24 +01:00
btCollisionWorld : : ClosestRayResultCallback callback ( from , to ) ;
domain - > test_getPhysicalWorld ( ) - > rayTest ( from , to , callback ) ;
domain - > tick ( 1.0f , res ) ;
ASSERT_TRUE ( callback . hasHit ( ) ) ;
ASSERT_FUZZY_EQUAL ( 1.0f , callback . m_hitPointWorld . y ( ) , 0.1f ) ;
//Add a box and let it fall on the planted entity
2021-05-23 21:31:36 +02:00
Entity freeEntity ( context . newId ( ) ) ;
freeEntity . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( freeProperty . copy ( ) ) ) ;
freeEntity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 0 , 10 , 0 ) ;
freeEntity . requirePropertyClassFixed < OrientationProperty > ( ) . data ( ) = WFMath : : Quaternion : : IDENTITY ( ) ;
freeEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = { { - 0.5f , 0 , - 0.5f } ,
{ 0.5f , 1 , 0.5f } } ;
2021-05-23 21:31:36 +02:00
freeEntity . setProperty ( " mass " , std : : unique_ptr < Property < double > > ( massProp . copy ( ) ) ) ;
domain - > addEntity ( freeEntity ) ;
2020-01-04 16:15:24 +01:00
while ( time < 5 ) {
time + = tickSize ;
domain - > tick ( tickSize , res ) ;
}
2017-03-24 17:19:10 +01:00
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 1.0f , 0.1f ) ;
2017-09-01 13:19:27 +02:00
2020-01-04 16:15:24 +01:00
//Make the bbox larger and test that it adjust itself against the terrain.
2021-05-23 21:31:36 +02:00
bBoxProperty . data ( ) = { { - 1 , 0 , - 1 } ,
{ 1 , 2 , 1 } } ;
2021-05-31 00:05:25 +02:00
bBoxProperty . apply ( plantedEntity ) ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
domain - > test_childEntityPropertyApplied ( " bbox " , bBoxProperty , plantedEntity . getIntId ( ) ) ;
2017-01-29 17:13:01 +01:00
2020-01-04 16:15:24 +01:00
domain - > tick ( 1.0f , res ) ;
2019-12-16 23:43:44 +01:00
2020-01-04 16:15:24 +01:00
callback = btCollisionWorld : : ClosestRayResultCallback ( from , to ) ;
domain - > test_getPhysicalWorld ( ) - > rayTest ( from , to , callback ) ;
2017-01-29 17:13:01 +01:00
2020-01-04 16:15:24 +01:00
ASSERT_TRUE ( callback . hasHit ( ) ) ;
ASSERT_FUZZY_EQUAL ( 2.0f , callback . m_hitPointWorld . y ( ) , 0.1f ) ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
domain - > removeEntity ( freeEntity ) ;
2017-01-29 17:13:01 +01:00
2020-01-04 16:15:24 +01:00
//Test again with the falling box
2021-06-18 22:44:30 +02:00
freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 0 , 10 , 0 ) ;
2018-01-11 17:07:05 +01:00
2021-05-23 21:31:36 +02:00
domain - > addEntity ( freeEntity ) ;
2018-03-23 19:22:35 +01:00
2020-01-04 16:15:24 +01:00
time = 0 ;
while ( time < 5 ) {
time + = tickSize ;
domain - > tick ( tickSize , res ) ;
}
2018-04-27 14:47:16 +02:00
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 2.0f , 0.1f ) ;
2018-04-27 14:47:16 +02:00
2020-01-04 16:15:24 +01:00
}
2018-04-27 14:47:16 +02:00
2020-07-05 01:33:34 +02:00
void test_deleteWithPlanted ( TestContext & context )
{
//Place four boxes, all "planted", and all on top of each others.
//Now first delete the third box from the bottom. The top box should now be placed on the second box.
//Then delete the first box. The second box should now be placed on the ground, and the top box should be on top of it.
2021-05-23 21:31:36 +02:00
Entity rootEntity ( context . newId ( ) ) ;
rootEntity . incRef ( ) ;
2021-06-18 22:44:30 +02:00
rootEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
rootEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = { { - 64 , 0 , - 64 } ,
{ 64 , 64 , 64 } } ;
2021-05-23 21:31:36 +02:00
std : : unique_ptr < TestPhysicalDomain > domain ( new TestPhysicalDomain ( rootEntity ) ) ;
2020-07-05 01:33:34 +02:00
2021-05-23 21:31:36 +02:00
ModeProperty plantedProperty { } ;
plantedProperty . set ( " planted " ) ;
Property < double > massProp { } ;
massProp . data ( ) = 10000 ;
2020-07-05 01:33:34 +02:00
OpVector res ;
2021-05-23 21:31:36 +02:00
Entity planted1 ( context . newId ( ) ) ;
2021-06-18 22:44:30 +02:00
planted1 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = { 1 , 1 , 0 } ;
planted1 . requirePropertyClassFixed < OrientationProperty > ( ) . data ( ) = WFMath : : Quaternion : : IDENTITY ( ) ;
planted1 . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = { { - 2 , 0 , - 2 } ,
{ 2 , 1 , 2 } } ;
2021-05-23 21:31:36 +02:00
planted1 . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( plantedProperty . copy ( ) ) ) ;
2020-07-05 01:33:34 +02:00
2021-05-23 21:31:36 +02:00
domain - > addEntity ( planted1 ) ;
2020-07-05 01:33:34 +02:00
domain - > tick ( 0 , res ) ;
2021-05-23 21:31:36 +02:00
ASSERT_EQUAL ( rootEntity . getIntId ( ) , * planted1 . getPropertyClassFixed < ModeDataProperty > ( ) - > getPlantedOnData ( ) . entityId )
2020-07-05 01:33:34 +02:00
2021-05-23 21:31:36 +02:00
Entity planted2 ( context . newId ( ) ) ;
2021-06-18 22:44:30 +02:00
planted2 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = { 0 , 2 , 1 } ;
planted2 . requirePropertyClassFixed < OrientationProperty > ( ) . data ( ) = WFMath : : Quaternion : : IDENTITY ( ) ;
planted2 . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = { { - 2 , 0 , - 2 } ,
{ 2 , 1 , 2 } } ;
2021-05-23 21:31:36 +02:00
planted2 . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( plantedProperty . copy ( ) ) ) ;
2020-07-05 01:33:34 +02:00
2021-05-23 21:31:36 +02:00
domain - > addEntity ( planted2 ) ;
2020-07-05 01:33:34 +02:00
domain - > tick ( 0 , res ) ;
2021-05-23 21:31:36 +02:00
ASSERT_EQUAL ( planted1 . getIntId ( ) , * planted2 . getPropertyClassFixed < ModeDataProperty > ( ) - > getPlantedOnData ( ) . entityId )
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( 1.0f , planted2 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 0.1f ) ;
2020-07-05 01:33:34 +02:00
2021-05-23 21:31:36 +02:00
Entity planted3 ( context . newId ( ) ) ;
2021-06-18 22:44:30 +02:00
planted3 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = { 0 , 4 , 1 } ;
planted3 . requirePropertyClassFixed < OrientationProperty > ( ) . data ( ) = WFMath : : Quaternion : : IDENTITY ( ) ;
planted3 . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = { { - 2 , 0 , - 2 } ,
{ 2 , 1 , 2 } } ;
2021-05-23 21:31:36 +02:00
planted3 . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( plantedProperty . copy ( ) ) ) ;
2020-07-05 01:33:34 +02:00
2021-05-23 21:31:36 +02:00
domain - > addEntity ( planted3 ) ;
2020-07-05 01:33:34 +02:00
domain - > tick ( 0 , res ) ;
2021-05-23 21:31:36 +02:00
ASSERT_EQUAL ( planted2 . getIntId ( ) , * planted3 . getPropertyClassFixed < ModeDataProperty > ( ) - > getPlantedOnData ( ) . entityId )
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( 2.0f , planted3 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 0.1f ) ;
2020-07-05 01:33:34 +02:00
2021-05-23 21:31:36 +02:00
Entity planted4 ( context . newId ( ) ) ;
2021-06-18 22:44:30 +02:00
planted4 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = { 0 , 6 , 1 } ;
planted4 . requirePropertyClassFixed < OrientationProperty > ( ) . data ( ) = WFMath : : Quaternion : : IDENTITY ( ) ;
planted4 . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = { { - 2 , 0 , - 2 } ,
{ 2 , 1 , 2 } } ;
2021-05-23 21:31:36 +02:00
planted4 . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( plantedProperty . copy ( ) ) ) ;
2020-07-05 01:33:34 +02:00
2021-05-23 21:31:36 +02:00
domain - > addEntity ( planted4 ) ;
2020-07-05 01:33:34 +02:00
domain - > tick ( 0 , res ) ;
2021-05-23 21:31:36 +02:00
ASSERT_EQUAL ( planted3 . getIntId ( ) , * planted4 . getPropertyClassFixed < ModeDataProperty > ( ) - > getPlantedOnData ( ) . entityId )
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( 3.0f , planted4 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 0.1f ) ;
2020-07-05 01:33:34 +02:00
//Now delete planted3, which should place planted4 on top of planted2
2021-05-23 21:31:36 +02:00
domain - > removeEntity ( planted3 ) ;
2020-07-05 01:33:34 +02:00
domain - > tick ( 0 , res ) ;
2021-05-23 21:31:36 +02:00
ASSERT_EQUAL ( planted2 . getIntId ( ) , * planted4 . getPropertyClassFixed < ModeDataProperty > ( ) - > getPlantedOnData ( ) . entityId )
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( 2.0f , planted4 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 0.1f ) ;
2020-07-05 01:33:34 +02:00
2021-05-23 21:31:36 +02:00
domain - > removeEntity ( planted1 ) ;
2020-07-05 01:33:34 +02:00
domain - > tick ( 0 , res ) ;
2021-05-23 21:31:36 +02:00
ASSERT_EQUAL ( rootEntity . getIntId ( ) , * planted2 . getPropertyClassFixed < ModeDataProperty > ( ) - > getPlantedOnData ( ) . entityId )
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( 0.0f , planted2 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 0.1f ) ;
2021-05-23 21:31:36 +02:00
ASSERT_EQUAL ( planted2 . getIntId ( ) , * planted4 . getPropertyClassFixed < ModeDataProperty > ( ) - > getPlantedOnData ( ) . entityId )
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( 1.0f , planted4 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 0.1f ) ;
2020-07-05 01:33:34 +02:00
}
void test_convert ( TestContext & context )
2020-01-04 16:15:24 +01:00
{
WFMath : : AxisBox < 3 > wfBox ( WFMath : : Point < 3 > ( - 1 , - 3 , - 5 ) , WFMath : : Point < 3 > ( 1 , 3 , 5 ) ) ;
2018-04-27 14:47:16 +02:00
2020-01-04 16:15:24 +01:00
auto wfSize = wfBox . highCorner ( ) - wfBox . lowCorner ( ) ;
btVector3 btSize = Convert : : toBullet ( wfSize ) ;
2018-04-27 14:47:16 +02:00
2020-01-04 16:15:24 +01:00
ASSERT_EQUAL ( btSize . x ( ) , wfSize . x ( ) ) ;
ASSERT_EQUAL ( btSize . y ( ) , wfSize . y ( ) ) ;
ASSERT_EQUAL ( btSize . z ( ) , wfSize . z ( ) ) ;
2018-04-27 14:47:16 +02:00
2020-01-04 16:15:24 +01:00
WFMath : : Quaternion wfQuat ;
wfQuat . rotation ( 1 , - WFMath : : numeric_constants < float > : : pi ( ) / 2.0f ) ;
btQuaternion btQuat = Convert : : toBullet ( wfQuat ) ;
2018-04-27 14:47:16 +02:00
2020-01-04 16:15:24 +01:00
ASSERT_FUZZY_EQUAL ( wfQuat . scalar ( ) , btQuat . getW ( ) , epsilon ) ;
ASSERT_FUZZY_EQUAL ( wfQuat . vector ( ) . x ( ) , btQuat . getX ( ) , epsilon ) ;
ASSERT_FUZZY_EQUAL ( wfQuat . vector ( ) . y ( ) , btQuat . getY ( ) , epsilon ) ;
ASSERT_FUZZY_EQUAL ( wfQuat . vector ( ) . z ( ) , btQuat . getZ ( ) , epsilon ) ;
2018-04-27 14:47:16 +02:00
2020-01-04 16:15:24 +01:00
//Now create a box, rotate it and see that the values match.
2018-04-27 14:47:16 +02:00
2020-01-04 16:15:24 +01:00
btBoxShape btBox ( btSize / 2 ) ;
2018-04-27 14:47:16 +02:00
2020-01-04 16:15:24 +01:00
auto wfHighCorner = wfBox . highCorner ( ) ;
wfHighCorner . rotate ( wfQuat , WFMath : : Point < 3 > : : ZERO ( ) ) ;
auto wfLowCorner = wfBox . lowCorner ( ) ;
wfLowCorner . rotate ( wfQuat , WFMath : : Point < 3 > : : ZERO ( ) ) ;
2018-04-27 14:47:16 +02:00
2020-01-04 16:15:24 +01:00
btTransform transform ( btQuat ) ;
2018-04-27 14:47:16 +02:00
2020-01-04 16:15:24 +01:00
btVector3 minAabb , maxAabb ;
btBox . getAabb ( transform , minAabb , maxAabb ) ;
2018-04-27 14:47:16 +02:00
2020-01-04 16:15:24 +01:00
wfBox . highCorner ( ) . x ( ) = std : : max ( wfHighCorner . x ( ) , wfLowCorner . x ( ) ) ;
wfBox . highCorner ( ) . y ( ) = std : : max ( wfHighCorner . y ( ) , wfLowCorner . y ( ) ) ;
wfBox . highCorner ( ) . z ( ) = std : : max ( wfHighCorner . z ( ) , wfLowCorner . z ( ) ) ;
2018-04-27 14:47:16 +02:00
2020-01-04 16:15:24 +01:00
wfBox . lowCorner ( ) . x ( ) = std : : min ( wfHighCorner . x ( ) , wfLowCorner . x ( ) ) ;
wfBox . lowCorner ( ) . y ( ) = std : : min ( wfHighCorner . y ( ) , wfLowCorner . y ( ) ) ;
wfBox . lowCorner ( ) . z ( ) = std : : min ( wfHighCorner . z ( ) , wfLowCorner . z ( ) ) ;
2018-04-27 14:47:16 +02:00
2020-01-04 16:15:24 +01:00
ASSERT_FUZZY_EQUAL ( wfBox . highCorner ( ) . x ( ) , maxAabb . x ( ) , 0.01 ) ;
ASSERT_FUZZY_EQUAL ( wfBox . highCorner ( ) . y ( ) , maxAabb . y ( ) , 0.01 ) ;
ASSERT_FUZZY_EQUAL ( wfBox . highCorner ( ) . z ( ) , maxAabb . z ( ) , 0.01 ) ;
2018-04-27 14:47:16 +02:00
2020-01-04 16:15:24 +01:00
ASSERT_FUZZY_EQUAL ( wfBox . lowCorner ( ) . x ( ) , minAabb . x ( ) , 0.01 ) ;
ASSERT_FUZZY_EQUAL ( wfBox . lowCorner ( ) . y ( ) , minAabb . y ( ) , 0.01 ) ;
ASSERT_FUZZY_EQUAL ( wfBox . lowCorner ( ) . z ( ) , minAabb . z ( ) , 0.01 ) ;
2018-04-27 14:47:16 +02:00
}
2020-07-05 01:33:34 +02:00
void test_movePlantedAndResting ( TestContext & context )
2020-01-04 16:15:24 +01:00
{
2018-04-27 14:47:16 +02:00
2020-01-04 16:15:24 +01:00
//Place a box, "planted". On top of that, place another box, also "planted". And on top of that, place a box which is "free".
//Then move the first box. The two boxes on top should move along with it.
2018-04-27 14:47:16 +02:00
2021-05-23 21:31:36 +02:00
Entity rootEntity ( context . newId ( ) ) ;
rootEntity . incRef ( ) ;
2021-06-18 22:44:30 +02:00
rootEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
rootEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = { { - 64 , 0 , - 64 } ,
{ 64 , 64 , 64 } } ;
2021-05-23 21:31:36 +02:00
std : : unique_ptr < TestPhysicalDomain > domain ( new TestPhysicalDomain ( rootEntity ) ) ;
ModeProperty fixedProperty { } ;
fixedProperty . set ( " fixed " ) ;
ModeProperty plantedProperty { } ;
plantedProperty . set ( " planted " ) ;
ModeProperty freeProperty { } ;
freeProperty . set ( " free " ) ;
Property < double > massProp { } ;
massProp . data ( ) = 10000 ;
Entity fixed1 ( context . newId ( ) ) ;
2021-06-18 22:44:30 +02:00
fixed1 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = { 0 , 0 , 0 } ;
fixed1 . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = { { - 2 , - 1 , - 2 } ,
{ 2 , 1 , 2 } } ;
fixed1 . requirePropertyClassFixed < OrientationProperty > ( ) . data ( ) = WFMath : : Quaternion : : IDENTITY ( ) ;
2021-05-23 21:31:36 +02:00
fixed1 . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( fixedProperty . copy ( ) ) ) ;
domain - > addEntity ( fixed1 ) ;
2018-04-27 14:47:16 +02:00
2020-01-04 16:15:24 +01:00
OpVector res ;
domain - > tick ( 0 , res ) ;
2018-04-27 14:47:16 +02:00
2021-06-18 22:44:30 +02:00
ASSERT_EQUAL ( 0 , fixed1 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) ) ;
2018-04-27 14:47:16 +02:00
2021-05-23 21:31:36 +02:00
Entity planted1 ( context . newId ( ) ) ;
2021-06-18 22:44:30 +02:00
planted1 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = { 1 , 1 , 0 } ;
planted1 . requirePropertyClassFixed < OrientationProperty > ( ) . data ( ) = WFMath : : Quaternion : : IDENTITY ( ) ;
planted1 . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = { { - 2 , - 1 , - 2 } ,
{ 2 , 1 , 2 } } ;
2021-05-23 21:31:36 +02:00
planted1 . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( plantedProperty . copy ( ) ) ) ;
2018-03-25 14:27:50 +02:00
2021-05-23 21:31:36 +02:00
domain - > addEntity ( planted1 ) ;
2018-03-25 14:27:50 +02:00
2020-01-04 16:15:24 +01:00
domain - > tick ( 0 , res ) ;
2018-03-25 14:27:50 +02:00
2021-05-23 21:31:36 +02:00
Entity planted2 ( context . newId ( ) ) ;
2021-06-18 22:44:30 +02:00
planted2 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = { 0 , 2 , 1 } ;
planted2 . requirePropertyClassFixed < OrientationProperty > ( ) . data ( ) = WFMath : : Quaternion : : IDENTITY ( ) ;
planted2 . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = { { - 2 , - 1 , - 2 } ,
{ 2 , 1 , 2 } } ;
2021-05-23 21:31:36 +02:00
planted2 . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( plantedProperty . copy ( ) ) ) ;
2018-03-25 14:27:50 +02:00
2021-05-23 21:31:36 +02:00
domain - > addEntity ( planted2 ) ;
2018-03-25 14:27:50 +02:00
2020-01-04 16:15:24 +01:00
domain - > tick ( 0 , res ) ;
2018-03-25 14:27:50 +02:00
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( 2.0f , planted2 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 0.1f ) ;
2018-03-25 14:27:50 +02:00
2021-05-23 21:31:36 +02:00
Entity freeEntity ( context . newId ( ) ) ;
2021-06-18 22:44:30 +02:00
freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = { 1 , 4 , 0 } ;
freeEntity . requirePropertyClassFixed < OrientationProperty > ( ) . data ( ) = WFMath : : Quaternion : : IDENTITY ( ) ;
2021-05-23 21:31:36 +02:00
freeEntity . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( freeProperty . copy ( ) ) ) ;
2021-06-18 22:44:30 +02:00
freeEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = { { - 1 , - 1 , - 1 } ,
{ 1 , 1 , 1 } } ;
2021-05-23 21:31:36 +02:00
freeEntity . setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
domain - > addEntity ( freeEntity ) ;
2018-03-25 14:27:50 +02:00
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( 4.0f , freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 0.1 ) ;
2020-01-04 16:15:24 +01:00
domain - > tick ( 1 , res ) ;
2018-03-25 14:27:50 +02:00
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( 4.0f , freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 0.1 ) ;
2018-03-25 14:27:50 +02:00
2020-01-04 16:15:24 +01:00
//Only change position
{
std : : set < LocatedEntity * > transformedEntities ;
2018-03-25 14:27:50 +02:00
2021-05-23 21:31:36 +02:00
domain - > applyTransform ( fixed1 , Domain : : TransformData { WFMath : : Quaternion ( ) , { 10 , 10 , 10 } , nullptr , { } } , transformedEntities ) ;
2020-01-04 16:15:24 +01:00
ASSERT_EQUAL ( 4u , transformedEntities . size ( ) ) ;
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( WFMath : : Point < 3 > ( 11 , 11 , 10 ) , planted1 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , epsilon ) ;
ASSERT_FUZZY_EQUAL ( WFMath : : Point < 3 > ( 10 , 12 , 11 ) , planted2 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , epsilon ) ;
ASSERT_TRUE ( WFMath : : Equal ( WFMath : : Point < 3 > ( 11 , 14 , 10 ) , freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , 0.1 ) ) ;
2020-01-04 16:15:24 +01:00
}
domain - > tick ( 0 , res ) ;
2018-03-25 14:27:50 +02:00
2020-01-04 16:15:24 +01:00
//Only change orientation
{
std : : set < LocatedEntity * > transformedEntities ;
2018-03-25 14:27:50 +02:00
2021-05-23 21:31:36 +02:00
domain - > applyTransform ( fixed1 , Domain : : TransformData { WFMath : : Quaternion ( 1 , WFMath : : numeric_constants < float > : : pi ( ) / 2 ) , { } , nullptr , { } } , transformedEntities ) ;
2020-01-04 16:15:24 +01:00
ASSERT_EQUAL ( 4u , transformedEntities . size ( ) ) ;
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( WFMath : : Point < 3 > ( 10 , 11 , 9 ) , planted1 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , epsilon ) ;
ASSERT_FUZZY_EQUAL ( WFMath : : Point < 3 > ( 11 , 12 , 10 ) , planted2 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , epsilon ) ;
ASSERT_TRUE ( WFMath : : Equal ( WFMath : : Point < 3 > ( 10 , 14 , 9 ) , freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , 0.1 ) ) ;
2020-01-04 16:15:24 +01:00
}
domain - > tick ( 0 , res ) ;
2018-03-25 14:27:50 +02:00
2020-01-04 16:15:24 +01:00
//Move it, and at the same time rotate it 90 degrees around the y axis.
{
std : : set < LocatedEntity * > transformedEntities ;
2018-03-25 14:27:50 +02:00
2021-05-23 21:31:36 +02:00
domain - > applyTransform ( fixed1 , Domain : : TransformData { WFMath : : Quaternion ( 1 , WFMath : : numeric_constants < float > : : pi ( ) ) , { 15 , 15 , 15 } , nullptr , { } } , transformedEntities ) ;
2020-01-04 16:15:24 +01:00
ASSERT_EQUAL ( 4u , transformedEntities . size ( ) ) ;
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( WFMath : : Point < 3 > ( 14 , 16 , 15 ) , planted1 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , epsilon ) ;
ASSERT_FUZZY_EQUAL ( WFMath : : Point < 3 > ( 15 , 17 , 14 ) , planted2 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , epsilon ) ;
ASSERT_TRUE ( WFMath : : Equal ( WFMath : : Point < 3 > ( 14 , 19 , 15 ) , freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , 0.1 ) ) ;
2020-01-04 16:15:24 +01:00
}
domain - > tick ( 0 , res ) ;
2018-03-25 14:27:50 +02:00
2020-01-04 16:15:24 +01:00
//Move away the first planted entity, which should also move along the second planted and the free entity, and not affect the fixed entity.
{
std : : set < LocatedEntity * > transformedEntities ;
2021-05-23 21:31:36 +02:00
domain - > applyTransform ( planted1 , Domain : : TransformData { { } ,
{ 20 , 0 , 20 } ,
nullptr , { } } , transformedEntities ) ;
2020-01-04 16:15:24 +01:00
ASSERT_EQUAL ( 3u , transformedEntities . size ( ) ) ;
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( WFMath : : Point < 3 > ( 21 , 1 , 19 ) , planted2 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , epsilon ) ;
ASSERT_TRUE ( WFMath : : Equal ( WFMath : : Point < 3 > ( 20 , 3 , 20 ) , freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , 0.1 ) ) ;
ASSERT_FUZZY_EQUAL ( WFMath : : Point < 3 > ( 15 , 15 , 15 ) , fixed1 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , epsilon ) ;
2020-01-04 16:15:24 +01:00
}
2018-03-25 14:27:50 +02:00
2020-01-04 16:15:24 +01:00
{
std : : set < LocatedEntity * > transformedEntities ;
2021-05-23 21:31:36 +02:00
domain - > applyTransform ( fixed1 , Domain : : TransformData { WFMath : : Quaternion ( ) , { 5 , 20 , 5 } , nullptr , { } } , transformedEntities ) ;
2020-01-04 16:15:24 +01:00
ASSERT_EQUAL ( 1u , transformedEntities . size ( ) ) ;
}
2018-03-25 14:27:50 +02:00
2020-01-04 16:15:24 +01:00
//Remove the second planted entity, making sure that the first planted doesn't keep a reference
2021-05-23 21:31:36 +02:00
domain - > removeEntity ( planted2 ) ;
2020-01-04 16:15:24 +01:00
{
std : : set < LocatedEntity * > transformedEntities ;
2018-03-25 14:27:50 +02:00
2021-05-23 21:31:36 +02:00
domain - > applyTransform ( planted1 , Domain : : TransformData { WFMath : : Quaternion ( ) , { 15 , 0 , 20 } , nullptr , { } } , transformedEntities ) ;
2020-01-04 16:15:24 +01:00
ASSERT_EQUAL ( 1u , transformedEntities . size ( ) ) ;
}
2018-03-25 14:27:50 +02:00
}
2020-07-05 01:33:34 +02:00
void test_plantedOn ( TestContext & context )
2018-03-25 14:27:50 +02:00
{
2020-01-04 16:15:24 +01:00
std : : vector < std : : string > shapes { " box " , " cylinder-x " , " cylinder-y " , " cylinder-z " , " capsule-x " , " capsule-y " , " capsule-z " } ;
for ( auto plantedShape : shapes ) {
for ( auto plantedOnTopShape : shapes ) {
2020-07-05 01:33:34 +02:00
auto id = context . newId ( ) ;
2021-05-23 21:31:36 +02:00
Entity rootEntity { id } ;
rootEntity . incRef ( ) ;
TerrainProperty terrainProperty { } ;
rootEntity . setProperty ( " terrain " , std : : unique_ptr < PropertyBase > ( terrainProperty . copy ( ) ) ) ;
Mercator : : Terrain & terrain = terrainProperty . getData ( rootEntity ) ;
2020-01-04 16:15:24 +01:00
terrain . setBasePoint ( 0 , 0 , Mercator : : BasePoint ( 10 ) ) ;
terrain . setBasePoint ( 0 , 1 , Mercator : : BasePoint ( 10 ) ) ;
terrain . setBasePoint ( 1 , 0 , Mercator : : BasePoint ( 10 ) ) ;
terrain . setBasePoint ( 1 , 1 , Mercator : : BasePoint ( 10 ) ) ;
2021-06-18 22:44:30 +02:00
rootEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
rootEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = { { - 64 , - 64 , - 64 } ,
{ 64 , 64 , 64 } } ;
2020-01-04 16:15:24 +01:00
TestPhysicalDomain domain { rootEntity } ;
2021-05-23 21:31:36 +02:00
Entity planted1 ( context . newId ( ) ) ;
2021-06-18 22:44:30 +02:00
planted1 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 0 , 10 , 0 ) ;
planted1 . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = { { - 1 , - 1 , - 1 } ,
{ 1 , 1 , 1 } } ;
2020-01-04 16:15:24 +01:00
{
2021-05-23 21:31:36 +02:00
GeometryProperty plantedGeometryProperty { } ;
plantedGeometryProperty . set ( MapType { { " type " , plantedShape } } ) ;
ModeProperty modeProperty { } ;
modeProperty . set ( " planted " ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
planted1 . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modeProperty . copy ( ) ) ) ;
planted1 . setProperty ( GeometryProperty : : property_name , std : : unique_ptr < PropertyBase > ( plantedGeometryProperty . copy ( ) ) ) ;
2020-01-04 16:15:24 +01:00
}
2021-05-23 21:31:36 +02:00
domain . addEntity ( planted1 ) ;
2020-01-04 16:15:24 +01:00
OpVector res ;
domain . tick ( 0 , res ) ;
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( planted1 . getPropertyClassFixed < ModeDataProperty > ( ) )
ASSERT_TRUE ( planted1 . getPropertyClassFixed < ModeDataProperty > ( ) - > getPlantedOnData ( ) . entityId )
ASSERT_EQUAL ( rootEntity . getIntId ( ) , * planted1 . getPropertyClassFixed < ModeDataProperty > ( ) - > getPlantedOnData ( ) . entityId )
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( 10 , planted1 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 0.1 ) ;
2020-01-04 16:15:24 +01:00
{
2021-05-23 21:31:36 +02:00
auto * planted1RigidBody = domain . test_getRigidBody ( planted1 . getIntId ( ) ) ;
2020-01-04 16:15:24 +01:00
btVector3 aabbMin , aabbMax ;
planted1RigidBody - > getAabb ( aabbMin , aabbMax ) ;
ASSERT_FUZZY_EQUAL_FN ( aabbMin . y ( ) , 9 , 0.1 , [ & ] ( ) { this - > addFailure ( String : : compose ( " Using shape '%1'. " , plantedShape ) ) ; } ) ;
ASSERT_FUZZY_EQUAL_FN ( aabbMax . y ( ) , 11 , 0.1 , [ & ] ( ) { this - > addFailure ( String : : compose ( " Using shape '%1'. " , plantedShape ) ) ; } ) ;
}
2021-05-23 21:31:36 +02:00
Entity planted2 ( context . newId ( ) ) ;
2021-06-18 22:44:30 +02:00
planted2 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 0 , 15 , 0 ) ;
planted2 . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = { { - 1 , - 1 , - 1 } ,
{ 1 , 1 , 1 } } ;
2020-01-04 16:15:24 +01:00
{
2021-05-23 21:31:36 +02:00
GeometryProperty plantedGeometryProperty { } ;
plantedGeometryProperty . set ( MapType { { " type " , plantedShape } } ) ;
ModeProperty modeProperty { } ;
modeProperty . set ( " planted " ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
planted2 . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modeProperty . copy ( ) ) ) ;
planted2 . setProperty ( GeometryProperty : : property_name , std : : unique_ptr < PropertyBase > ( plantedGeometryProperty . copy ( ) ) ) ;
2020-01-04 16:15:24 +01:00
}
2021-05-23 21:31:36 +02:00
domain . addEntity ( planted2 ) ;
2020-01-04 16:15:24 +01:00
domain . tick ( 0 , res ) ;
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( planted2 . getPropertyClassFixed < ModeDataProperty > ( ) ) ;
ASSERT_TRUE ( planted2 . getPropertyClassFixed < ModeDataProperty > ( ) - > getPlantedOnData ( ) . entityId ) ;
ASSERT_EQUAL ( planted1 . getIntId ( ) , * planted2 . getPropertyClassFixed < ModeDataProperty > ( ) - > getPlantedOnData ( ) . entityId ) ;
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( 11 , planted2 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 0.1 ) ;
2020-01-04 16:15:24 +01:00
{
2021-05-23 21:31:36 +02:00
auto * planted2RigidBody = domain . test_getRigidBody ( planted2 . getIntId ( ) ) ;
2020-01-04 16:15:24 +01:00
btVector3 aabbMin , aabbMax ;
planted2RigidBody - > getAabb ( aabbMin , aabbMax ) ;
ASSERT_FUZZY_EQUAL_FN ( aabbMin . y ( ) , 10 , 0.1 , [ & ] ( ) { this - > addFailure ( String : : compose ( " Using shape '%1'. " , plantedShape ) ) ; } ) ;
ASSERT_FUZZY_EQUAL_FN ( aabbMax . y ( ) , 12 , 0.1 , [ & ] ( ) { this - > addFailure ( String : : compose ( " Using shape '%1'. " , plantedShape ) ) ; } ) ;
}
2021-05-23 21:31:36 +02:00
Entity plantedOn ( context . newId ( ) ) ;
2021-06-18 22:44:30 +02:00
plantedOn . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = { 0 , 15 , 0 } ;
2020-01-04 16:15:24 +01:00
{
2021-05-23 21:31:36 +02:00
ModeProperty modeProperty { } ;
modeProperty . set ( " planted " ) ;
plantedOn . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modeProperty . copy ( ) ) ) ;
2020-01-04 16:15:24 +01:00
}
2021-06-18 22:44:30 +02:00
plantedOn . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = { { - 1 , 0 , - 1 } ,
{ 1 , 1 , 1 } } ;
2021-05-23 21:31:36 +02:00
ModeDataProperty modeDataProperty { } ;
modeDataProperty . setPlantedData ( { planted1 . getIntId ( ) } ) ;
plantedOn . setProperty ( ModeDataProperty : : property_name , std : : unique_ptr < PropertyBase > ( modeDataProperty . copy ( ) ) ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
GeometryProperty geometryProperty { } ;
geometryProperty . set ( MapType { { " type " , plantedOnTopShape } } ) ;
plantedOn . setProperty ( GeometryProperty : : property_name , std : : unique_ptr < PropertyBase > ( geometryProperty . copy ( ) ) ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
domain . addEntity ( plantedOn ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( plantedOn . getPropertyClassFixed < ModeDataProperty > ( ) ) ;
ASSERT_TRUE ( plantedOn . getPropertyClassFixed < ModeDataProperty > ( ) - > getPlantedOnData ( ) . entityId ) ;
ASSERT_EQUAL ( planted1 . getIntId ( ) , * plantedOn . getPropertyClassFixed < ModeDataProperty > ( ) - > getPlantedOnData ( ) . entityId ) ;
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL_FN ( plantedOn . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 11 , 0.1 ,
[ & ] ( ) { this - > addFailure ( String : : compose ( " Using shape '%1' on top of '%2'. " , plantedOnTopShape , plantedShape ) ) ; } ) ;
2020-01-04 16:15:24 +01:00
{
2021-05-23 21:31:36 +02:00
auto * plantedOnRigidBody = domain . test_getRigidBody ( plantedOn . getIntId ( ) ) ;
2020-01-04 16:15:24 +01:00
btVector3 aabbMin , aabbMax ;
plantedOnRigidBody - > getAabb ( aabbMin , aabbMax ) ;
ASSERT_FUZZY_EQUAL_FN ( aabbMin . y ( ) , 11 , 0.1 , [ & ] ( ) { this - > addFailure ( String : : compose ( " Using shape '%1' on top of '%2'. " , plantedOnTopShape , plantedShape ) ) ; } ) ;
ASSERT_FUZZY_EQUAL_FN ( aabbMax . y ( ) , 12 , 0.1 , [ & ] ( ) { this - > addFailure ( String : : compose ( " Using shape '%1' on top of '%2'. " , plantedOnTopShape , plantedShape ) ) ; } ) ;
}
2021-05-23 21:31:36 +02:00
domain . removeEntity ( planted2 ) ;
domain . removeEntity ( planted1 ) ;
domain . removeEntity ( plantedOn ) ;
2018-03-25 14:27:50 +02:00
2020-01-04 16:15:24 +01:00
}
}
2018-03-25 14:27:50 +02:00
}
2020-07-05 01:33:34 +02:00
void test_terrainMods ( TestContext & context )
2018-03-25 14:27:50 +02:00
{
2021-05-23 21:31:36 +02:00
Entity rootEntity ( context . newId ( ) ) ;
rootEntity . incRef ( ) ;
TerrainProperty terrainProperty { } ;
rootEntity . setProperty ( " terrain " , std : : unique_ptr < PropertyBase > ( terrainProperty . copy ( ) ) ) ;
Mercator : : Terrain & terrain = terrainProperty . getData ( rootEntity ) ;
2020-01-04 16:15:24 +01:00
terrain . setBasePoint ( 0 , 0 , Mercator : : BasePoint ( 10 ) ) ;
terrain . setBasePoint ( 0 , 1 , Mercator : : BasePoint ( 10 ) ) ;
terrain . setBasePoint ( 1 , 0 , Mercator : : BasePoint ( 10 ) ) ;
terrain . setBasePoint ( 1 , 1 , Mercator : : BasePoint ( 10 ) ) ;
2021-06-18 22:44:30 +02:00
rootEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
rootEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 64 , - 64 , - 64 ) , WFMath : : Point < 3 > ( 64 , 64 , 64 ) ) ;
2021-05-23 21:31:36 +02:00
std : : unique_ptr < TestPhysicalDomain > domain ( new TestPhysicalDomain ( rootEntity ) ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
ModeProperty modePropertyBase { } ;
modePropertyBase . set ( " planted " ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
Entity terrainModEntity ( context . newId ( ) ) ;
2021-06-18 22:44:30 +02:00
terrainModEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 32 , 10 , 32 ) ;
2021-05-23 21:31:36 +02:00
auto modeProperty = terrainModEntity . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modePropertyBase . copy ( ) ) ) ;
TerrainModProperty terrainModProperty { } ;
2020-01-04 16:15:24 +01:00
Atlas : : Message : : MapType modElement {
{ " heightoffset " , - 5.0f } ,
{ " shape " , MapType {
{ " points " , ListType {
ListType { - 10.f , - 10.f } ,
ListType { 10.f , - 10.f } ,
ListType { 10.f , 10.f } ,
ListType { - 10.f , 10.f } ,
}
} ,
{ " type " , " polygon " }
}
} ,
{ " type " , " levelmod " }
} ;
2021-05-23 21:31:36 +02:00
terrainModProperty . set ( modElement ) ;
2021-05-31 00:05:25 +02:00
terrainModProperty . apply ( terrainModEntity ) ;
2021-05-23 21:31:36 +02:00
terrainModEntity . setProperty ( TerrainModProperty : : property_name , std : : unique_ptr < PropertyBase > ( terrainModProperty . copy ( ) ) ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
domain - > addEntity ( terrainModEntity ) ;
2018-03-25 14:27:50 +02:00
2020-01-04 16:15:24 +01:00
OpVector res ;
2018-03-25 14:27:50 +02:00
std : : set < LocatedEntity * > transformedEntities ;
2020-01-04 16:15:24 +01:00
domain - > tick ( 0 , res ) ;
2018-03-25 14:27:50 +02:00
2020-01-04 16:15:24 +01:00
ASSERT_FUZZY_EQUAL ( terrain . get ( 10 , 10 ) , 10.0f , 0.1f ) ;
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( terrain . hasMod ( terrainModEntity . getIntId ( ) ) ) ;
2020-01-04 16:15:24 +01:00
ASSERT_FUZZY_EQUAL ( terrain . get ( 32 , 32 ) , 5.0f , 0.1f ) ;
2018-03-25 14:27:50 +02:00
2020-01-04 16:15:24 +01:00
{
btVector3 rayFrom ( 32 , 32 , 32 ) ;
btVector3 rayTo ( 32 , - 32 , 32 ) ;
btCollisionWorld : : ClosestRayResultCallback callback ( rayFrom , rayTo ) ;
domain - > test_getPhysicalWorld ( ) - > rayTest ( rayFrom , rayTo , callback ) ;
2018-03-23 19:22:35 +01:00
2020-01-04 16:15:24 +01:00
ASSERT_FUZZY_EQUAL ( callback . m_hitPointWorld . y ( ) , 5.0f , 0.1f ) ;
}
2021-05-23 21:31:36 +02:00
domain - > applyTransform ( terrainModEntity , Domain : : TransformData { WFMath : : Quaternion ( ) , WFMath : : Point < 3 > ( 10 , 10 , 10 ) , nullptr , { } } , transformedEntities ) ;
2018-03-23 19:22:35 +01:00
2020-01-04 16:15:24 +01:00
domain - > tick ( 0 , res ) ;
2018-03-23 19:22:35 +01:00
2020-01-04 16:15:24 +01:00
ASSERT_FUZZY_EQUAL ( terrain . get ( 10 , 10 ) , 5.0f , 0.1f ) ;
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( terrain . hasMod ( terrainModEntity . getIntId ( ) ) ) ;
2020-01-04 16:15:24 +01:00
ASSERT_FUZZY_EQUAL ( terrain . get ( 32 , 32 ) , 10.0f , 0.1f ) ;
2018-03-23 19:22:35 +01:00
2020-01-04 16:15:24 +01:00
{
btVector3 rayFrom ( 32 , 32 , 32 ) ;
btVector3 rayTo ( 32 , - 32 , 32 ) ;
btCollisionWorld : : ClosestRayResultCallback callback ( rayFrom , rayTo ) ;
domain - > test_getPhysicalWorld ( ) - > rayTest ( rayFrom , rayTo , callback ) ;
2018-04-19 10:19:35 +02:00
2020-01-04 16:15:24 +01:00
ASSERT_FUZZY_EQUAL ( callback . m_hitPointWorld . y ( ) , 10.0f , 0.1f ) ;
}
2018-03-23 19:22:35 +01:00
2020-01-04 16:15:24 +01:00
//Now change "mode" to "free", which should remove the mod.
2018-03-23 19:22:35 +01:00
2020-01-04 16:15:24 +01:00
modeProperty - > set ( " free " ) ;
2021-05-31 00:05:25 +02:00
modeProperty - > apply ( terrainModEntity ) ;
2021-05-23 21:31:36 +02:00
terrainModEntity . propertyApplied . emit ( " mode " , * modeProperty ) ;
2018-03-23 19:22:35 +01:00
2020-01-04 16:15:24 +01:00
domain - > tick ( 0 , res ) ;
2018-03-23 19:22:35 +01:00
2020-01-04 16:15:24 +01:00
ASSERT_FUZZY_EQUAL ( terrain . get ( 10 , 10 ) , 10.0f , 0.1f ) ;
2021-05-23 21:31:36 +02:00
ASSERT_FALSE ( terrain . hasMod ( terrainModEntity . getIntId ( ) ) ) ;
2020-01-04 16:15:24 +01:00
ASSERT_FUZZY_EQUAL ( terrain . get ( 32 , 32 ) , 10.0f , 0.1f ) ;
2018-03-23 19:22:35 +01:00
2020-01-04 16:15:24 +01:00
//And back to "planted" which should bring it back
modeProperty - > set ( " planted " ) ;
2021-05-31 00:05:25 +02:00
modeProperty - > apply ( terrainModEntity ) ;
2021-05-23 21:31:36 +02:00
terrainModEntity . propertyApplied . emit ( " mode " , * modeProperty ) ;
2018-04-19 10:19:35 +02:00
2020-01-04 16:15:24 +01:00
domain - > tick ( 0 , res ) ;
2018-03-23 19:22:35 +01:00
2020-01-04 16:15:24 +01:00
ASSERT_FUZZY_EQUAL ( terrain . get ( 10 , 10 ) , 5.0f , 0.1f ) ;
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( terrain . hasMod ( terrainModEntity . getIntId ( ) ) ) ;
2020-01-04 16:15:24 +01:00
ASSERT_FUZZY_EQUAL ( terrain . get ( 32 , 32 ) , 10.0f , 0.1f ) ;
}
2018-03-23 19:22:35 +01:00
2018-03-05 22:14:58 +01:00
2020-07-05 01:33:34 +02:00
void test_lake_rotated ( TestContext & context )
2020-01-04 16:15:24 +01:00
{
2021-05-23 21:31:36 +02:00
struct TestEntity : public Entity
2020-01-04 16:15:24 +01:00
{
2021-05-23 21:31:36 +02:00
explicit TestEntity ( long intId ) : Entity ( intId )
{
}
2018-03-05 22:14:58 +01:00
2022-07-04 15:37:51 +02:00
explicit TestEntity ( RouterId id ) : Entity ( id )
2021-05-23 21:31:36 +02:00
{
}
decltype ( LocatedEntity : : propertyApplied ) & test_propertyApplied ( )
{
return propertyApplied ;
}
2020-01-04 16:15:24 +01:00
} ;
2018-03-05 22:14:58 +01:00
2021-05-23 21:31:36 +02:00
TypeNode rockType ( " rock " ) ;
TypeNode lakeType ( " lake " ) ;
2018-03-05 22:14:58 +01:00
2021-05-23 21:31:36 +02:00
Property < double > massProp { } ;
massProp . data ( ) = 10000 ;
2018-03-05 22:14:58 +01:00
2021-05-23 21:31:36 +02:00
BoolProperty waterBodyProp { } ;
waterBodyProp . set ( 1 ) ;
2018-03-05 22:14:58 +01:00
2021-05-23 21:31:36 +02:00
ModeProperty modeFreeProperty { } ;
modeFreeProperty . set ( " free " ) ;
rockType . injectProperty ( " mode " , std : : unique_ptr < PropertyBase > ( modeFreeProperty . copy ( ) ) ) ;
2018-03-05 22:14:58 +01:00
2021-05-23 21:31:36 +02:00
ModeProperty modeFixedProperty { } ;
modeFixedProperty . set ( " fixed " ) ;
2018-03-05 22:14:58 +01:00
2021-05-23 21:31:36 +02:00
Entity rootEntity ( context . newId ( ) ) ;
rootEntity . incRef ( ) ;
2021-06-18 22:44:30 +02:00
rootEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
rootEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 64 , 0 , - 64 ) , WFMath : : Point < 3 > ( 64 , 64 , 64 ) ) ;
2021-05-23 21:31:36 +02:00
std : : unique_ptr < TestPhysicalDomain > domain ( new TestPhysicalDomain ( rootEntity ) ) ;
2018-03-05 22:14:58 +01:00
2021-05-23 21:31:36 +02:00
TestEntity lake ( context . newId ( ) ) ;
lake . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modeFixedProperty . copy ( ) ) ) ;
lake . setType ( & lakeType ) ;
lake . setProperty ( " water_body " , std : : unique_ptr < PropertyBase > ( waterBodyProp . copy ( ) ) ) ;
2021-06-18 22:44:30 +02:00
lake . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( 0 , - 64 , 0 ) , WFMath : : Point < 3 > ( 10 , 0 , 2 ) ) ;
lake . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 0 , 10 , 0 ) ;
2020-01-04 16:15:24 +01:00
//rotate 90 degrees
2021-06-18 22:44:30 +02:00
lake . requirePropertyClassFixed < OrientationProperty > ( ) . data ( ) = WFMath : : Quaternion ( 1 , - WFMath : : numeric_constants < float > : : pi ( ) / 2.0f ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( lake ) ;
2020-01-04 16:15:24 +01:00
//Should be in water
2022-07-04 15:37:51 +02:00
Entity freeEntity ( RouterId ( " freeEntity " , context . newId ( ) ) ) ;
2021-05-23 21:31:36 +02:00
freeEntity . setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
freeEntity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( - 1 , 1 , 9 ) ;
freeEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , - 1 , - 1 ) , WFMath : : Point < 3 > ( 1 , 1 , 1 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( freeEntity ) ;
2020-01-04 16:15:24 +01:00
//Should not be in water
2022-07-04 15:37:51 +02:00
Entity freeEntity2 ( RouterId ( " freeEntity2 " , context . newId ( ) ) ) ;
2021-05-23 21:31:36 +02:00
freeEntity2 . setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
freeEntity2 . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
freeEntity2 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 9 , 1 , 1 ) ;
freeEntity2 . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , - 1 , - 1 ) , WFMath : : Point < 3 > ( 1 , 1 , 1 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( freeEntity2 ) ;
ModeProperty plantedProp { } ;
plantedProp . set ( " planted " ) ;
ModeDataProperty modeDataProp { } ;
modeDataProp . setPlantedData ( { lake . getIntId ( ) } ) ;
2022-07-04 15:37:51 +02:00
Entity floatingEntity ( RouterId ( " floatingEntity " , context . newId ( ) ) ) ;
2021-05-23 21:31:36 +02:00
floatingEntity . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( plantedProp . copy ( ) ) ) ;
floatingEntity . setProperty ( ModeDataProperty : : property_name , std : : unique_ptr < PropertyBase > ( modeDataProp . copy ( ) ) ) ;
floatingEntity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
floatingEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 5 , 20 , 1 ) ;
floatingEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , - 1 , - 1 ) , WFMath : : Point < 3 > ( 1 , 1 , 1 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( floatingEntity ) ;
2018-03-05 22:14:58 +01:00
2020-01-04 16:15:24 +01:00
OpVector res ;
domain - > tick ( 0 , res ) ;
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( freeEntity . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Submerged ) ;
ASSERT_TRUE ( freeEntity2 . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Free ) ;
ASSERT_TRUE ( floatingEntity . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Planted ) ;
2021-06-18 22:44:30 +02:00
ASSERT_EQUAL ( WFMath : : Point < 3 > ( 5 , 10 , 1 ) , floatingEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) ) ;
2018-03-05 22:14:58 +01:00
2020-01-04 16:15:24 +01:00
}
2018-03-05 22:14:58 +01:00
2020-07-05 01:33:34 +02:00
void test_lake ( TestContext & context )
2018-03-05 22:14:58 +01:00
{
2021-05-23 21:31:36 +02:00
struct TestEntity : public Entity
2020-01-04 16:15:24 +01:00
{
2021-05-23 21:31:36 +02:00
explicit TestEntity ( long intId ) : Entity ( intId )
{
}
2018-03-05 22:14:58 +01:00
2022-07-04 15:37:51 +02:00
explicit TestEntity ( RouterId id ) : Entity ( id )
2021-05-23 21:31:36 +02:00
{
}
decltype ( LocatedEntity : : propertyApplied ) & test_propertyApplied ( )
{
return propertyApplied ;
}
2020-01-04 16:15:24 +01:00
} ;
2018-03-05 22:14:58 +01:00
2020-01-04 16:15:24 +01:00
double tickSize = 1.0 / 15.0 ;
double time = 0 ;
2018-03-05 22:14:58 +01:00
2021-05-23 21:31:36 +02:00
TypeNode rockType ( " rock " ) ;
TypeNode lakeType ( " lake " ) ;
2018-03-05 22:14:58 +01:00
2021-05-23 21:31:36 +02:00
Property < double > massProp { } ;
massProp . data ( ) = 10000 ;
2018-03-05 22:14:58 +01:00
2021-05-23 21:31:36 +02:00
BoolProperty waterBodyProp { } ;
waterBodyProp . set ( 1 ) ;
2018-03-05 22:14:58 +01:00
2021-05-23 21:31:36 +02:00
ModeProperty modeFreeProperty { } ;
modeFreeProperty . set ( " free " ) ;
rockType . injectProperty ( " mode " , std : : unique_ptr < PropertyBase > ( modeFreeProperty . copy ( ) ) ) ;
2018-03-05 22:14:58 +01:00
2021-05-23 21:31:36 +02:00
ModeProperty modeFixedProperty { } ;
modeFixedProperty . set ( " fixed " ) ;
2018-03-05 22:14:58 +01:00
2018-02-26 12:55:05 +01:00
2021-05-23 21:31:36 +02:00
Entity rootEntity ( context . newId ( ) ) ;
rootEntity . incRef ( ) ;
2021-06-18 22:44:30 +02:00
rootEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
rootEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 64 , - 64 , - 64 ) , WFMath : : Point < 3 > ( 64 , 64 , 64 ) ) ;
2021-05-23 21:31:36 +02:00
std : : unique_ptr < TestPhysicalDomain > domain ( new TestPhysicalDomain ( rootEntity ) ) ;
2018-02-26 12:55:05 +01:00
2021-05-23 21:31:36 +02:00
TestEntity lake ( context . newId ( ) ) ;
lake . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modeFixedProperty . copy ( ) ) ) ;
lake . setType ( & lakeType ) ;
lake . setProperty ( " water_body " , std : : unique_ptr < PropertyBase > ( waterBodyProp . copy ( ) ) ) ;
2021-06-18 22:44:30 +02:00
lake . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 5 , - 64 , - 5 ) , WFMath : : Point < 3 > ( 5 , 0 , 5 ) ) ;
lake . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 20 , 0 , 0 ) ;
lake . requirePropertyClassFixed < OrientationProperty > ( ) . data ( ) = WFMath : : Quaternion : : IDENTITY ( ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( lake ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
Entity freeEntity ( context . newId ( ) ) ;
freeEntity . setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
freeEntity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 20 , 2 , 0 ) ;
freeEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , 0 , - 1 ) , WFMath : : Point < 3 > ( 1 , 1 , 1 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( freeEntity ) ;
2020-01-04 16:15:24 +01:00
//The second entity is placed in water, and should be submerged from the start
2021-05-23 21:31:36 +02:00
Entity freeEntity2 ( context . newId ( ) ) ;
freeEntity2 . setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
freeEntity2 . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
freeEntity2 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 20 , - 2 , 2 ) ;
freeEntity2 . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , 0 , - 1 ) , WFMath : : Point < 3 > ( 1 , 1 , 1 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( freeEntity2 ) ;
2020-01-04 16:15:24 +01:00
//The third entity is placed outside of the lake, and should never be submerged.
2021-05-23 21:31:36 +02:00
Entity freeEntity3 ( context . newId ( ) ) ;
freeEntity3 . setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
freeEntity3 . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
freeEntity3 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( - 20 , 2 , 0 ) ;
freeEntity3 . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , 0 , - 1 ) , WFMath : : Point < 3 > ( 1 , 1 , 1 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( freeEntity3 ) ;
2018-02-26 12:55:05 +01:00
2020-01-04 16:15:24 +01:00
OpVector res ;
std : : set < LocatedEntity * > transformedEntities ;
domain - > tick ( 0 , res ) ;
while ( time < 5 ) {
time + = tickSize ;
domain - > tick ( tickSize , res ) ;
}
2018-02-26 12:55:05 +01:00
2021-06-18 22:44:30 +02:00
ASSERT_TRUE ( freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) < 0 ) ;
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( freeEntity . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Submerged ) ;
2020-01-04 16:15:24 +01:00
2021-06-18 22:44:30 +02:00
ASSERT_TRUE ( freeEntity2 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) < 0 ) ;
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( freeEntity2 . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Submerged ) ;
2020-01-04 16:15:24 +01:00
2021-06-18 22:44:30 +02:00
ASSERT_TRUE ( freeEntity3 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) < 0 ) ;
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( freeEntity3 . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Free ) ;
2020-01-04 16:15:24 +01:00
//Move outside
2021-05-23 21:31:36 +02:00
domain - > applyTransform ( freeEntity , Domain : : TransformData { WFMath : : Quaternion : : IDENTITY ( ) , WFMath : : Point < 3 > ( 20 , 60 , 0 ) , nullptr , { } } , transformedEntities ) ;
2020-01-04 16:15:24 +01:00
domain - > tick ( 0 , res ) ;
2021-06-18 22:44:30 +02:00
ASSERT_GREATER ( freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 0 ) ;
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( freeEntity . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Free ) ;
2020-01-04 16:15:24 +01:00
//Move back in.
2021-05-23 21:31:36 +02:00
domain - > applyTransform ( freeEntity , Domain : : TransformData { WFMath : : Quaternion : : IDENTITY ( ) , WFMath : : Point < 3 > ( 20 , - 10 , 0 ) , nullptr , { } } , transformedEntities ) ;
2020-01-04 16:15:24 +01:00
domain - > tick ( 0 , res ) ;
2021-06-18 22:44:30 +02:00
ASSERT_LESS ( freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 0 ) ;
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( freeEntity . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Submerged ) ;
ASSERT_TRUE ( freeEntity3 . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Free ) ;
2020-01-04 16:15:24 +01:00
//Move the lake to where freeEntity3 is
2021-06-18 22:44:30 +02:00
domain - > applyTransform ( lake , Domain : : TransformData { WFMath : : Quaternion ( ) , freeEntity3 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) + WFMath : : Vector < 3 > ( 0 , 5 , 0 ) , nullptr , { } } ,
transformedEntities ) ;
2020-01-04 16:15:24 +01:00
domain - > tick ( 0 , res ) ;
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( freeEntity3 . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Submerged ) ;
ASSERT_TRUE ( freeEntity . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Free ) ;
2020-01-04 16:15:24 +01:00
//Update the bbox of the lake so that it's outside of freeEntity3.
//To emulate the propertyApplied signal being called in this test we need to do it ourselves.
2021-06-18 22:44:30 +02:00
auto newBbox = lake . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) ;
2020-01-04 16:15:24 +01:00
newBbox . highCorner ( ) . x ( ) = 1 ;
newBbox . highCorner ( ) . y ( ) = 1 ;
newBbox . highCorner ( ) . z ( ) = 1 ;
newBbox . lowCorner ( ) . x ( ) = - 1 ;
newBbox . lowCorner ( ) . y ( ) = - 1 ;
newBbox . lowCorner ( ) . z ( ) = - 1 ;
2021-05-23 21:31:36 +02:00
BBoxProperty bBoxProperty { } ;
bBoxProperty . set ( newBbox . toAtlas ( ) ) ;
lake . setProperty ( " bbox " , std : : unique_ptr < PropertyBase > ( bBoxProperty . copy ( ) ) ) ;
2021-05-31 00:05:25 +02:00
bBoxProperty . apply ( lake ) ;
2021-05-23 21:31:36 +02:00
lake . test_propertyApplied ( ) . emit ( " bbox " , bBoxProperty ) ;
2020-01-04 16:15:24 +01:00
domain - > tick ( 0 , res ) ;
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( freeEntity3 . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Free ) ;
ASSERT_TRUE ( freeEntity . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Free ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
domain - > removeEntity ( lake ) ;
2020-01-04 16:15:24 +01:00
domain - > tick ( 0 , res ) ;
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( freeEntity . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Free ) ;
ASSERT_TRUE ( freeEntity2 . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Free ) ;
ASSERT_TRUE ( freeEntity3 . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Free ) ;
2018-02-26 12:55:05 +01:00
}
2020-07-05 01:33:34 +02:00
void test_ocean ( TestContext & context )
2020-01-04 16:15:24 +01:00
{
double tickSize = 1.0 / 15.0 ;
double time = 0 ;
2018-02-26 12:55:05 +01:00
2021-05-23 21:31:36 +02:00
TypeNode rockType ( " rock " ) ;
TypeNode oceanType ( " ocean " ) ;
2018-02-26 12:55:05 +01:00
2021-05-23 21:31:36 +02:00
Property < double > massProp { } ;
massProp . data ( ) = 10000 ;
2018-02-26 12:55:05 +01:00
2021-05-23 21:31:36 +02:00
BoolProperty waterBodyProp { } ;
waterBodyProp . set ( 1 ) ;
2018-02-26 12:55:05 +01:00
2021-05-23 21:31:36 +02:00
ModeProperty modeFreeProperty { } ;
modeFreeProperty . set ( " free " ) ;
ModeProperty modeFixedProperty { } ;
modeFixedProperty . set ( " fixed " ) ;
2018-02-26 12:55:05 +01:00
2021-05-23 21:31:36 +02:00
rockType . injectProperty ( " mode " , std : : unique_ptr < PropertyBase > ( modeFreeProperty . copy ( ) ) ) ;
2018-02-26 12:55:05 +01:00
2021-05-23 21:31:36 +02:00
Entity rootEntity ( context . newId ( ) ) ;
rootEntity . incRef ( ) ;
2021-06-18 22:44:30 +02:00
rootEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
rootEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 64 , - 64 , - 64 ) , WFMath : : Point < 3 > ( 64 , 64 , 64 ) ) ;
2021-05-23 21:31:36 +02:00
std : : unique_ptr < TestPhysicalDomain > domain ( new TestPhysicalDomain ( rootEntity ) ) ;
2018-02-26 12:55:05 +01:00
2021-05-23 21:31:36 +02:00
Entity ocean ( context . newId ( ) ) ;
ocean . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modeFixedProperty . copy ( ) ) ) ;
ocean . setType ( & oceanType ) ;
ocean . setProperty ( " water_body " , std : : unique_ptr < PropertyBase > ( waterBodyProp . copy ( ) ) ) ;
2021-06-18 22:44:30 +02:00
ocean . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 0 , 0 , 0 ) ;
ocean . requirePropertyClassFixed < OrientationProperty > ( ) . data ( ) = WFMath : : Quaternion : : IDENTITY ( ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( ocean ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
Entity freeEntity ( context . newId ( ) ) ;
freeEntity . setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
freeEntity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 0 , 2 , 0 ) ;
freeEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , 0 , - 1 ) , WFMath : : Point < 3 > ( 1 , 1 , 1 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( freeEntity ) ;
2020-01-04 16:15:24 +01:00
//The second entity is placed in water, and should be submerged from the start
2021-05-23 21:31:36 +02:00
Entity freeEntity2 ( context . newId ( ) ) ;
freeEntity2 . setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
freeEntity2 . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
freeEntity2 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 10 , - 10 , 0 ) ;
freeEntity2 . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , 0 , - 1 ) , WFMath : : Point < 3 > ( 1 , 1 , 1 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( freeEntity2 ) ;
2018-02-26 12:55:05 +01:00
2018-01-11 17:07:05 +01:00
2020-01-04 16:15:24 +01:00
OpVector res ;
std : : set < LocatedEntity * > transformedEntities ;
domain - > tick ( 0 , res ) ;
while ( time < 5 ) {
time + = tickSize ;
domain - > tick ( tickSize , res ) ;
}
2018-01-11 17:07:05 +01:00
2021-06-18 22:44:30 +02:00
ASSERT_LESS ( freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 0 )
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( freeEntity . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Submerged ) ;
2018-01-11 17:07:05 +01:00
2021-06-18 22:44:30 +02:00
ASSERT_LESS ( freeEntity2 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 0 ) ;
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( freeEntity2 . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Submerged ) ;
2018-01-11 17:07:05 +01:00
2020-01-04 16:15:24 +01:00
//Move outside
2021-05-23 21:31:36 +02:00
domain - > applyTransform ( freeEntity , Domain : : TransformData { WFMath : : Quaternion : : IDENTITY ( ) , WFMath : : Point < 3 > ( 0 , 60 , 0 ) , nullptr , { } } , transformedEntities ) ;
2020-01-04 16:15:24 +01:00
domain - > tick ( 0 , res ) ;
2021-06-18 22:44:30 +02:00
ASSERT_TRUE ( freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) > 0 ) ;
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( freeEntity . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Free ) ;
2018-01-11 17:07:05 +01:00
2020-01-04 16:15:24 +01:00
//Move back in.
2021-05-23 21:31:36 +02:00
domain - > applyTransform ( freeEntity , Domain : : TransformData { WFMath : : Quaternion : : IDENTITY ( ) , WFMath : : Point < 3 > ( 0 , - 10 , 0 ) , nullptr , { } } , transformedEntities ) ;
2020-01-04 16:15:24 +01:00
domain - > tick ( 0 , res ) ;
2021-06-18 22:44:30 +02:00
ASSERT_TRUE ( freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) < 0 ) ;
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( freeEntity . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Submerged ) ;
2018-01-11 17:07:05 +01:00
2021-05-23 21:31:36 +02:00
domain - > removeEntity ( ocean ) ;
2020-01-04 16:15:24 +01:00
domain - > tick ( 0 , res ) ;
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( freeEntity . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Free ) ;
ASSERT_TRUE ( freeEntity2 . getPropertyClassFixed < ModeProperty > ( ) - > getMode ( ) = = ModeProperty : : Mode : : Free ) ;
2020-01-04 16:15:24 +01:00
}
2018-01-11 17:07:05 +01:00
2020-07-05 01:33:34 +02:00
void test_placement ( TestContext & context )
2020-01-04 16:15:24 +01:00
{
2018-01-11 17:07:05 +01:00
2021-05-23 21:31:36 +02:00
TypeNode rockType ( " rock " ) ;
2018-01-11 17:07:05 +01:00
2021-05-23 21:31:36 +02:00
Property < double > massProp { } ;
massProp . data ( ) = 10000 ;
2018-01-11 17:07:05 +01:00
2021-05-23 21:31:36 +02:00
ModeProperty modeProperty { } ;
modeProperty . set ( " fixed " ) ;
2018-01-11 17:07:05 +01:00
2021-05-23 21:31:36 +02:00
Entity rootEntity ( context . newId ( ) ) ;
rootEntity . incRef ( ) ;
2021-06-18 22:44:30 +02:00
rootEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
rootEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 64 , - 64 , - 64 ) , WFMath : : Point < 3 > ( 64 , 64 , 64 ) ) ;
2021-05-23 21:31:36 +02:00
std : : unique_ptr < TestPhysicalDomain > domain ( new TestPhysicalDomain ( rootEntity ) ) ;
2018-01-11 17:07:05 +01:00
2020-01-04 16:15:24 +01:00
// btDiscreteDynamicsWorld* bulletWorld = domain->test_getBulletWorld();
2018-01-11 17:07:05 +01:00
2021-05-23 21:31:36 +02:00
auto verifyBboxes = [ & ] ( Entity & entity ) {
btRigidBody * rigidBody = domain - > test_getRigidBody ( entity . getIntId ( ) ) ;
2020-01-04 16:15:24 +01:00
btVector3 aabbMin , aabbMax ;
rigidBody - > getAabb ( aabbMin , aabbMax ) ;
2018-01-11 17:07:05 +01:00
2020-01-04 16:15:24 +01:00
//Get the final positions of the entity's bbox
2018-01-11 17:07:05 +01:00
2020-01-04 16:15:24 +01:00
btVector3 expectedBtAabbMax ( std : : numeric_limits < float > : : lowest ( ) , std : : numeric_limits < float > : : lowest ( ) , std : : numeric_limits < float > : : lowest ( ) ) ;
btVector3 expectedBtAabbMin ( std : : numeric_limits < float > : : max ( ) , std : : numeric_limits < float > : : max ( ) , std : : numeric_limits < float > : : max ( ) ) ;
2018-01-11 17:07:05 +01:00
2021-06-18 22:44:30 +02:00
for ( size_t i = 0 ; i < entity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) . numCorners ( ) ; + + i ) {
WFMath : : Point < 3 > point = entity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) . getCorner ( i ) ;
point . rotate ( entity . requirePropertyClassFixed < OrientationProperty > ( ) . data ( ) , WFMath : : Point < 3 > : : ZERO ( ) ) ;
2018-01-11 17:07:05 +01:00
2021-06-18 22:44:30 +02:00
point + = WFMath : : Vector < 3 > ( entity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) ) ;
2018-01-11 17:07:05 +01:00
2020-01-04 16:15:24 +01:00
btVector3 btPoint = Convert : : toBullet ( point ) ;
2018-01-11 17:07:05 +01:00
2020-01-04 16:15:24 +01:00
expectedBtAabbMax . setX ( std : : max ( expectedBtAabbMax . x ( ) , btPoint . x ( ) ) ) ;
expectedBtAabbMax . setY ( std : : max ( expectedBtAabbMax . y ( ) , btPoint . y ( ) ) ) ;
expectedBtAabbMax . setZ ( std : : max ( expectedBtAabbMax . z ( ) , btPoint . z ( ) ) ) ;
2018-01-11 17:07:05 +01:00
2020-01-04 16:15:24 +01:00
expectedBtAabbMin . setX ( std : : min ( expectedBtAabbMin . x ( ) , btPoint . x ( ) ) ) ;
expectedBtAabbMin . setY ( std : : min ( expectedBtAabbMin . y ( ) , btPoint . y ( ) ) ) ;
expectedBtAabbMin . setZ ( std : : min ( expectedBtAabbMin . z ( ) , btPoint . z ( ) ) ) ;
2018-01-11 17:07:05 +01:00
2020-01-04 16:15:24 +01:00
}
2018-01-11 17:07:05 +01:00
2020-01-04 16:15:24 +01:00
ASSERT_FUZZY_EQUAL ( expectedBtAabbMax . x ( ) , aabbMax . x ( ) , 0.001 ) ;
ASSERT_FUZZY_EQUAL ( expectedBtAabbMax . y ( ) , aabbMax . y ( ) , 0.001 ) ;
ASSERT_FUZZY_EQUAL ( expectedBtAabbMax . z ( ) , aabbMax . z ( ) , 0.001 ) ;
2018-01-11 17:07:05 +01:00
2020-01-04 16:15:24 +01:00
ASSERT_FUZZY_EQUAL ( expectedBtAabbMin . x ( ) , aabbMin . x ( ) , 0.001 ) ;
ASSERT_FUZZY_EQUAL ( expectedBtAabbMin . y ( ) , aabbMin . y ( ) , 0.001 ) ;
ASSERT_FUZZY_EQUAL ( expectedBtAabbMin . z ( ) , aabbMin . z ( ) , 0.001 ) ;
} ;
2018-01-11 17:07:05 +01:00
2021-05-23 21:31:36 +02:00
auto performPlacementTests = [ & ] ( Entity & entity ) {
2020-01-04 16:15:24 +01:00
verifyBboxes ( entity ) ;
std : : set < LocatedEntity * > transformedEntities ;
2018-01-11 17:07:05 +01:00
2020-01-04 16:15:24 +01:00
//Change pos only
2021-05-23 21:31:36 +02:00
domain - > applyTransform ( entity , Domain : : TransformData { WFMath : : Quaternion ( ) , WFMath : : Point < 3 > ( 20 , 30 , 1 ) , nullptr , { } } , transformedEntities ) ;
2017-01-29 17:13:01 +01:00
2020-01-04 16:15:24 +01:00
verifyBboxes ( entity ) ;
2018-01-11 17:07:05 +01:00
2020-01-04 16:15:24 +01:00
//Change orientation only
2021-05-23 21:31:36 +02:00
domain - > applyTransform ( entity , Domain : : TransformData { WFMath : : Quaternion ( 1 , WFMath : : numeric_constants < float > : : pi ( ) / 3.0f ) , WFMath : : Point < 3 > ( ) , nullptr , { } } ,
2020-01-04 16:15:24 +01:00
transformedEntities ) ;
2018-01-11 17:07:05 +01:00
2020-01-04 16:15:24 +01:00
verifyBboxes ( entity ) ;
2018-01-11 17:07:05 +01:00
2020-01-04 16:15:24 +01:00
//Change pos and orientation
2021-05-23 21:31:36 +02:00
domain - > applyTransform ( entity , Domain : : TransformData { WFMath : : Quaternion ( 1 , WFMath : : numeric_constants < float > : : pi ( ) / 5.0f ) , WFMath : : Point < 3 > ( 10 , - 25 , 6 ) , nullptr , { } } ,
2020-01-04 16:15:24 +01:00
transformedEntities ) ;
2018-01-11 17:07:05 +01:00
2020-01-04 16:15:24 +01:00
verifyBboxes ( entity ) ;
2018-01-11 17:07:05 +01:00
2020-01-04 16:15:24 +01:00
} ;
2018-01-10 15:11:20 +01:00
2020-01-04 16:15:24 +01:00
//Start with a box centered at origo, with no orientation
{
2021-05-23 21:31:36 +02:00
Entity entity ( context . newId ( ) ) ;
entity . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modeProperty . copy ( ) ) ) ;
entity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
entity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 10 , - 20 , 1 ) ;
entity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 6 , - 1 , - 2 ) , WFMath : : Point < 3 > ( 6 , 1 , 2 ) ) ;
entity . requirePropertyClassFixed < OrientationProperty > ( ) . data ( ) = WFMath : : Quaternion : : IDENTITY ( ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( entity ) ;
2020-01-04 16:15:24 +01:00
performPlacementTests ( entity ) ;
}
2018-01-10 15:11:20 +01:00
2020-01-04 16:15:24 +01:00
//Start with a box centered at origo, with 45 degrees orientation
{
2021-05-23 21:31:36 +02:00
Entity entity ( context . newId ( ) ) ;
entity . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modeProperty . copy ( ) ) ) ;
entity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
entity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 10 , - 20 , 1 ) ;
entity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 6 , - 1 , - 2 ) , WFMath : : Point < 3 > ( 6 , 1 , 2 ) ) ;
2020-01-04 16:15:24 +01:00
WFMath : : Quaternion wfQuat ;
wfQuat . rotation ( 1 , - WFMath : : numeric_constants < float > : : pi ( ) / 4.0f ) ;
2021-06-18 22:44:30 +02:00
entity . requirePropertyClassFixed < OrientationProperty > ( ) . data ( ) = wfQuat ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( entity ) ;
2020-01-04 16:15:24 +01:00
performPlacementTests ( entity ) ;
}
2018-01-10 15:11:20 +01:00
2020-01-04 16:15:24 +01:00
//A box not centered at origo, with no orientation
{
2021-05-23 21:31:36 +02:00
Entity entity ( context . newId ( ) ) ;
entity . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modeProperty . copy ( ) ) ) ;
entity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
entity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 10 , - 20 , 1 ) ;
entity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( 0 , 0 , 0 ) , WFMath : : Point < 3 > ( 6 , 1 , 2 ) ) ;
entity . requirePropertyClassFixed < OrientationProperty > ( ) . data ( ) = WFMath : : Quaternion : : IDENTITY ( ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( entity ) ;
2020-01-04 16:15:24 +01:00
performPlacementTests ( entity ) ;
}
2018-01-10 15:11:20 +01:00
2020-01-04 16:15:24 +01:00
//A box not centered at origo, with 45 degrees orientation
{
2021-05-23 21:31:36 +02:00
Entity entity ( context . newId ( ) ) ;
entity . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modeProperty . copy ( ) ) ) ;
entity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
entity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 10 , - 20 , 1 ) ;
entity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( 2 , 0 , 1 ) , WFMath : : Point < 3 > ( 6 , 1 , 2 ) ) ;
2020-01-04 16:15:24 +01:00
WFMath : : Quaternion wfQuat ;
wfQuat . rotation ( 1 , - WFMath : : numeric_constants < float > : : pi ( ) / 4.0f ) ;
2021-06-18 22:44:30 +02:00
entity . requirePropertyClassFixed < OrientationProperty > ( ) . data ( ) = wfQuat ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( entity ) ;
2020-01-04 16:15:24 +01:00
performPlacementTests ( entity ) ;
}
}
2018-01-10 15:11:20 +01:00
2020-07-05 01:33:34 +02:00
void test_fallToBottom ( TestContext & context )
2020-01-04 16:15:24 +01:00
{
2018-01-10 15:11:20 +01:00
2020-01-04 16:15:24 +01:00
double tickSize = 1.0 / 15.0 ;
double time = 0 ;
2018-01-10 15:11:20 +01:00
2021-05-23 21:31:36 +02:00
Entity rootEntity ( context . newId ( ) ) ;
rootEntity . incRef ( ) ;
2021-06-18 22:44:30 +02:00
rootEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
rootEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 64 , - 64 , - 64 ) , WFMath : : Point < 3 > ( 64 , 64 , 64 ) ) ;
2021-05-23 21:31:36 +02:00
std : : unique_ptr < TestPhysicalDomain > domain ( new TestPhysicalDomain ( rootEntity ) ) ;
2018-01-10 15:11:20 +01:00
2021-05-23 21:31:36 +02:00
Property < double > massProp { } ;
massProp . data ( ) = 10000 ;
2018-01-10 15:11:20 +01:00
2021-05-23 21:31:36 +02:00
TypeNode rockType ( " rock " ) ;
2018-01-10 15:11:20 +01:00
2021-05-23 21:31:36 +02:00
Entity freeEntity ( context . newId ( ) ) ;
freeEntity . setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
freeEntity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
freeEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , 0 , - 1 ) , WFMath : : Point < 3 > ( 1 , 1 , 1 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( freeEntity ) ;
2018-01-10 15:11:20 +01:00
2021-05-23 21:31:36 +02:00
Entity fixedEntity ( context . newId ( ) ) ;
fixedEntity . setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
2018-01-10 15:11:20 +01:00
2021-05-23 21:31:36 +02:00
ModeProperty modeProperty { } ;
modeProperty . set ( " fixed " ) ;
fixedEntity . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modeProperty . copy ( ) ) ) ;
fixedEntity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
fixedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 10 , 0 , 10 ) ;
fixedEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , 0 , - 1 ) , WFMath : : Point < 3 > ( 1 , 1 , 1 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( fixedEntity ) ;
2018-01-10 15:11:20 +01:00
2020-01-04 16:15:24 +01:00
OpVector res ;
2018-01-10 15:11:20 +01:00
2020-01-04 16:15:24 +01:00
//First tick should not update anything
domain - > tick ( 0 , res ) ;
2021-06-18 22:44:30 +02:00
ASSERT_EQUAL ( freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , WFMath : : Point < 3 > : : ZERO ( ) ) ;
ASSERT_EQUAL ( fixedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , WFMath : : Point < 3 > ( 10 , 0 , 10 ) ) ;
2018-01-10 15:11:20 +01:00
2020-01-04 16:15:24 +01:00
//Inject enough ticks to move rock to bottom
while ( time < 5 ) {
time + = tickSize ;
domain - > tick ( tickSize , res ) ;
}
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , - 64 , 0.1 ) ;
2020-01-04 16:15:24 +01:00
//Fixed entity should not move
2021-06-18 22:44:30 +02:00
ASSERT_EQUAL ( fixedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , WFMath : : Point < 3 > ( 10 , 0 , 10 ) ) ;
2020-01-04 16:15:24 +01:00
}
2017-01-29 17:13:01 +01:00
2020-07-05 01:33:34 +02:00
void test_standOnFixed ( TestContext & context )
2020-01-04 16:15:24 +01:00
{
2017-01-29 17:13:01 +01:00
2020-01-04 16:15:24 +01:00
double tickSize = 1.0 / 15.0 ;
double time = 0 ;
2021-05-23 21:31:36 +02:00
Entity rootEntity ( context . newId ( ) ) ;
rootEntity . incRef ( ) ;
2021-06-18 22:44:30 +02:00
rootEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
rootEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 64 , - 64 , - 64 ) , WFMath : : Point < 3 > ( 64 , 64 , 64 ) ) ;
2021-05-23 21:31:36 +02:00
std : : unique_ptr < TestPhysicalDomain > domain ( new TestPhysicalDomain ( rootEntity ) ) ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
Property < double > massProp { } ;
massProp . data ( ) = 10000 ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
TypeNode rockType ( " rock " ) ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
Entity freeEntity ( context . newId ( ) ) ;
freeEntity . setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
freeEntity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 0 , 1 , 0 ) ;
freeEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , 0 , - 1 ) , WFMath : : Point < 3 > ( 1 , 1 , 1 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( freeEntity ) ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
Entity fixedEntity ( context . newId ( ) ) ;
fixedEntity . setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
ModeProperty modeProperty { } ;
modeProperty . set ( " fixed " ) ;
fixedEntity . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modeProperty . copy ( ) ) ) ;
fixedEntity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
fixedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
fixedEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , 0 , - 1 ) , WFMath : : Point < 3 > ( 1 , 1 , 1 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( fixedEntity ) ;
2017-01-29 17:13:01 +01:00
2020-01-04 16:15:24 +01:00
OpVector res ;
2017-01-29 17:13:01 +01:00
2020-01-04 16:15:24 +01:00
//Inject enough ticks to move rock to bottom
while ( time < 5 ) {
time + = tickSize ;
domain - > tick ( tickSize , res ) ;
}
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , WFMath : : Point < 3 > ( 0 , 1 , 0 ) , epsilon ) ;
2017-01-29 17:13:01 +01:00
}
2020-07-05 01:33:34 +02:00
void test_fallToTerrain ( TestContext & context )
2020-01-04 16:15:24 +01:00
{
2017-01-29 17:13:01 +01:00
2020-01-04 16:15:24 +01:00
double tickSize = 1.0 / 15.0 ;
double time = 0 ;
2021-05-23 21:31:36 +02:00
Entity rootEntity ( context . newId ( ) ) ;
rootEntity . incRef ( ) ;
TerrainProperty terrainProperty { } ;
rootEntity . setProperty ( " terrain " , std : : unique_ptr < PropertyBase > ( terrainProperty . copy ( ) ) ) ;
Mercator : : Terrain & terrain = terrainProperty . getData ( rootEntity ) ;
2020-01-04 16:15:24 +01:00
terrain . setBasePoint ( 0 , 0 , Mercator : : BasePoint ( 10 ) ) ;
terrain . setBasePoint ( 0 , 1 , Mercator : : BasePoint ( 10 ) ) ;
terrain . setBasePoint ( 1 , 0 , Mercator : : BasePoint ( 10 ) ) ;
terrain . setBasePoint ( 1 , 1 , Mercator : : BasePoint ( 10 ) ) ;
2021-06-18 22:44:30 +02:00
rootEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
rootEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 64 , - 64 , - 64 ) , WFMath : : Point < 3 > ( 64 , 64 , 64 ) ) ;
2021-05-23 21:31:36 +02:00
std : : unique_ptr < TestPhysicalDomain > domain ( new TestPhysicalDomain ( rootEntity ) ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
Property < double > massProp { } ;
massProp . data ( ) = 10000 ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
TypeNode rockType ( " rock " ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
Entity freeEntity ( context . newId ( ) ) ;
freeEntity . setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
freeEntity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 10 , 20 , 10 ) ;
freeEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , 0 , - 1 ) , WFMath : : Point < 3 > ( 1 , 1 , 1 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( freeEntity ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
Entity plantedEntity ( context . newId ( ) ) ;
plantedEntity . setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
ModeProperty modeProperty { } ;
modeProperty . set ( " planted " ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
plantedEntity . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modeProperty . copy ( ) ) ) ;
plantedEntity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
plantedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 20 , 20 , 20 ) ;
plantedEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , 0 , - 1 ) , WFMath : : Point < 3 > ( 1 , 1 , 1 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( plantedEntity ) ;
2020-01-04 16:15:24 +01:00
2021-06-18 22:44:30 +02:00
ASSERT_EQUAL ( freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 20 ) ;
2020-01-04 16:15:24 +01:00
//Planted entity should be placed on the terrain when added to the domain.
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( plantedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , WFMath : : Point < 3 > ( 20 , 10.0058 , 20 ) , epsilon ) ;
2017-01-29 17:13:01 +01:00
2020-01-04 16:15:24 +01:00
OpVector res ;
2017-01-29 17:13:01 +01:00
2020-01-04 16:15:24 +01:00
//Inject enough ticks to move rock to bottom
while ( time < 5 ) {
time + = tickSize ;
domain - > tick ( tickSize , res ) ;
}
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 10.0087f , 0.01f ) ;
2020-01-04 16:15:24 +01:00
//Planted entity should not move
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( plantedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , WFMath : : Point < 3 > ( 20 , 10.0058 , 20 ) , epsilon ) ;
2020-01-04 16:15:24 +01:00
//If we now change the bbox of the free entity it should not fall through the terrain. The y-position should be the same
2021-06-18 22:44:30 +02:00
freeEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 0.5 , 0 , - 0.5 ) , WFMath : : Point < 3 > ( 0.5 , 0.5 , 0.5 ) ) ;
2021-01-26 22:03:16 +01:00
PropertyBase * ptr { } ;
2021-05-23 21:31:36 +02:00
freeEntity . propertyApplied ( " bbox " , * ptr ) ;
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 10.0087f , 0.01f ) ;
2020-01-04 16:15:24 +01:00
//Make sure that everything is correct even after ticking through the simulation
2017-01-29 17:13:01 +01:00
domain - > tick ( tickSize , res ) ;
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 10.0087f , 0.01f ) ;
2017-01-29 17:13:01 +01:00
}
2020-07-05 01:33:34 +02:00
void test_collision ( TestContext & context )
2020-01-04 16:15:24 +01:00
{
double tickSize = 1.0 / 15.0 ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
Property < double > zeroFrictionProperty { } ;
zeroFrictionProperty . data ( ) = 0 ;
Property < double > speedGroundProperty { } ;
speedGroundProperty . data ( ) = 5.0 ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
Entity rootEntity ( context . newId ( ) ) ;
rootEntity . incRef ( ) ;
TerrainProperty terrainProperty { } ;
rootEntity . setProperty ( " terrain " , std : : unique_ptr < PropertyBase > ( terrainProperty . copy ( ) ) ) ;
Mercator : : Terrain & terrain = terrainProperty . getData ( rootEntity ) ;
2020-01-04 16:15:24 +01:00
terrain . setBasePoint ( 0 , 0 , Mercator : : BasePoint ( 10 ) ) ;
terrain . setBasePoint ( 0 , 1 , Mercator : : BasePoint ( 10 ) ) ;
terrain . setBasePoint ( 1 , 0 , Mercator : : BasePoint ( 10 ) ) ;
terrain . setBasePoint ( 1 , 1 , Mercator : : BasePoint ( 10 ) ) ;
2021-05-23 21:31:36 +02:00
rootEntity . setProperty ( " friction " , std : : unique_ptr < PropertyBase > ( zeroFrictionProperty . copy ( ) ) ) ;
2021-06-18 22:44:30 +02:00
rootEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
rootEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 64 , - 64 , - 64 ) , WFMath : : Point < 3 > ( 64 , 64 , 64 ) ) ;
2021-05-23 21:31:36 +02:00
std : : unique_ptr < TestPhysicalDomain > domain ( new TestPhysicalDomain ( rootEntity ) ) ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
Property < double > massProp { } ;
massProp . data ( ) = 100 ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
TypeNode rockType ( " rock " ) ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
PropelProperty propelProperty { } ;
2020-01-04 16:15:24 +01:00
//Move y axis 2 meter per second.
2021-05-23 21:31:36 +02:00
propelProperty . data ( ) = WFMath : : Vector < 3 > ( 0 , 0 , 2.0 / speedGroundProperty . data ( ) ) ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
AngularFactorProperty angularZeroFactorProperty { } ;
angularZeroFactorProperty . data ( ) = WFMath : : Vector < 3 > : : ZERO ( ) ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
Entity freeEntity ( context . newId ( ) ) ;
freeEntity . setProperty ( PropelProperty : : property_name , std : : unique_ptr < PropertyBase > ( propelProperty . copy ( ) ) ) ;
freeEntity . setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
freeEntity . setProperty ( " friction " , std : : unique_ptr < PropertyBase > ( zeroFrictionProperty . copy ( ) ) ) ;
freeEntity . setProperty ( " speed_ground " , std : : unique_ptr < PropertyBase > ( speedGroundProperty . copy ( ) ) ) ;
freeEntity . setProperty ( AngularFactorProperty : : property_name , std : : unique_ptr < PropertyBase > ( angularZeroFactorProperty . copy ( ) ) ) ;
freeEntity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 10 , 10 , 10 ) ;
freeEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , 0 , - 1 ) , WFMath : : Point < 3 > ( 1 , 1 , 1 ) ) ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
domain - > addEntity ( freeEntity ) ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
Entity plantedEntity ( context . newId ( ) ) ;
plantedEntity . setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
ModeProperty modeProperty { } ;
modeProperty . set ( " planted " ) ;
2017-01-29 17:13:01 +01:00
2021-05-23 21:31:36 +02:00
plantedEntity . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modeProperty . copy ( ) ) ) ;
plantedEntity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
plantedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 10 , 10 , 15 ) ;
plantedEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , 0 , - 1 ) , WFMath : : Point < 3 > ( 1 , 1 , 1 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( plantedEntity ) ;
2021-06-18 22:44:30 +02:00
const WFMath : : Point < 3 > plantedPos = plantedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) ;
2017-01-29 17:13:01 +01:00
2020-01-04 16:15:24 +01:00
OpVector res ;
2017-01-29 17:13:01 +01:00
2020-01-04 16:15:24 +01:00
domain - > tick ( tickSize , res ) ;
2017-01-29 17:13:01 +01:00
2020-01-04 16:15:24 +01:00
//Should have moved 2/15 meters
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . z ( ) , 10 + ( 2.0 / 15.0 ) , 0.1f ) ;
2017-01-29 17:13:01 +01:00
2020-01-04 16:15:24 +01:00
//Inject ticks for one second
domain - > tick ( 14.0 / 15.0 , res ) ;
2017-01-29 17:13:01 +01:00
2020-01-04 16:15:24 +01:00
//Should have moved 2 meters in y axis
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . z ( ) , 12 , 0.1f ) ;
2017-02-14 17:57:40 +01:00
2020-01-04 16:15:24 +01:00
//Inject ticks for three seconds
for ( int i = 0 ; i < ( 3 * 15 ) ; + + i ) {
domain - > tick ( tickSize , res ) ;
}
2017-02-14 17:57:40 +01:00
2020-01-04 16:15:24 +01:00
//Should have stopped at planted entity
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . z ( ) , 13 , 0.1f ) ;
ASSERT_EQUAL ( plantedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , plantedPos ) ;
2017-02-14 17:57:40 +01:00
2021-05-23 21:31:36 +02:00
domain - > removeEntity ( plantedEntity ) ;
2020-01-04 16:15:24 +01:00
domain - > tick ( 1.0 , res ) ;
2017-01-29 17:13:01 +01:00
2020-01-04 16:15:24 +01:00
//Should have moved two more meters as planted entity was removed.
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( freeEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . z ( ) , 15 , 0.1f ) ;
2017-01-29 17:13:01 +01:00
}
2020-07-05 01:33:34 +02:00
void test_mode ( TestContext & context )
2020-01-04 16:15:24 +01:00
{
2017-01-29 23:01:08 +01:00
2020-01-04 16:15:24 +01:00
double tickSize = 1.0 / 15.0 ;
2021-05-23 21:31:36 +02:00
ModeProperty modePlantedProperty { } ;
modePlantedProperty . set ( " planted " ) ;
ModeProperty modeFixedProperty { } ;
modeFixedProperty . set ( " fixed " ) ;
ModeProperty modeFreeProperty { } ;
modeFreeProperty . set ( " " ) ;
TypeNode rockType ( " rock " ) ;
Entity rootEntity ( context . newId ( ) ) ;
rootEntity . incRef ( ) ;
TerrainProperty terrainProperty { } ;
rootEntity . setProperty ( " terrain " , std : : unique_ptr < PropertyBase > ( terrainProperty . copy ( ) ) ) ;
Mercator : : Terrain & terrain = terrainProperty . getData ( rootEntity ) ;
2020-01-04 16:15:24 +01:00
terrain . setBasePoint ( 0 , 0 , Mercator : : BasePoint ( 40 ) ) ;
terrain . setBasePoint ( 0 , 1 , Mercator : : BasePoint ( 40 ) ) ;
terrain . setBasePoint ( 1 , 0 , Mercator : : BasePoint ( 10 ) ) ;
terrain . setBasePoint ( 1 , 1 , Mercator : : BasePoint ( 10 ) ) ;
2021-06-18 22:44:30 +02:00
rootEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
rootEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 64 , - 64 , - 64 ) , WFMath : : Point < 3 > ( 64 , 64 , 64 ) ) ;
2021-05-23 21:31:36 +02:00
std : : unique_ptr < TestPhysicalDomain > domain ( new TestPhysicalDomain ( rootEntity ) ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
Property < double > massProp { } ;
massProp . data ( ) = 100 ;
2020-01-04 16:15:24 +01:00
2022-07-04 15:37:51 +02:00
Entity freeEntity1 ( RouterId ( " free1 " , context . newId ( ) ) ) ;
2021-05-23 21:31:36 +02:00
freeEntity1 . setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
freeEntity1 . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
freeEntity1 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 10 , 30 , 10 ) ;
freeEntity1 . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , 0 , - 1 ) , WFMath : : Point < 3 > ( 1 , 1 , 1 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( freeEntity1 ) ;
2020-01-04 16:15:24 +01:00
2021-06-18 22:44:30 +02:00
ASSERT_EQUAL ( freeEntity1 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , WFMath : : Point < 3 > ( 10 , 30 , 10 ) ) ;
2020-01-04 16:15:24 +01:00
//The other free entity is placed below the terrain; it's expected to then be clamped to the terrain
2021-05-23 21:31:36 +02:00
Entity freeEntity2 ( context . newId ( ) ) ;
freeEntity2 . setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
freeEntity2 . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
freeEntity2 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 20 , - 10 , 20 ) ;
freeEntity2 . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , 0 , - 1 ) , WFMath : : Point < 3 > ( 1 , 1 , 1 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( freeEntity2 ) ;
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( freeEntity2 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , WFMath : : Point < 3 > ( 20 , 22.6006 , 20 ) , epsilon ) ;
2021-05-23 21:31:36 +02:00
Entity plantedEntity ( context . newId ( ) ) ;
plantedEntity . setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
plantedEntity . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modePlantedProperty . copy ( ) ) ) ;
plantedEntity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
plantedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 30 , 10 , 30 ) ;
plantedEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , 0 , - 1 ) , WFMath : : Point < 3 > ( 1 , 1 , 1 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( plantedEntity ) ;
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( plantedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , WFMath : : Point < 3 > ( 30 , 18.4325 , 30 ) , epsilon ) ;
2021-05-23 21:31:36 +02:00
Entity fixedEntity ( context . newId ( ) ) ;
fixedEntity . setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
fixedEntity . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modeFixedProperty . copy ( ) ) ) ;
fixedEntity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
fixedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 40 , 50 , 40 ) ;
fixedEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , 0 , - 1 ) , WFMath : : Point < 3 > ( 1 , 1 , 1 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( fixedEntity ) ;
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( fixedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , WFMath : : Point < 3 > ( 40 , 50 , 40 ) , epsilon ) ;
2017-01-29 17:13:01 +01:00
2020-01-04 16:15:24 +01:00
OpVector res ;
2017-01-29 17:13:01 +01:00
2020-01-04 16:15:24 +01:00
//Inject ticks for two seconds
for ( int i = 0 ; i < 30 ; + + i ) {
domain - > tick ( tickSize , res ) ;
}
2017-01-29 17:13:01 +01:00
2021-06-18 22:44:30 +02:00
ASSERT_NOT_EQUAL ( freeEntity1 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , WFMath : : Point < 3 > ( 10 , 30 , 10 ) ) ;
ASSERT_NOT_EQUAL ( freeEntity2 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , WFMath : : Point < 3 > ( 20 , 22.6006 , 20 ) ) ;
ASSERT_FUZZY_EQUAL ( plantedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , WFMath : : Point < 3 > ( 30 , 18.4325 , 30 ) , epsilon ) ;
ASSERT_FUZZY_EQUAL ( fixedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , WFMath : : Point < 3 > ( 40 , 50 , 40 ) , epsilon ) ;
2020-01-04 16:15:24 +01:00
}
2017-01-29 17:13:01 +01:00
2020-07-05 01:33:34 +02:00
void test_static_entities_no_move ( TestContext & context )
{ }
2020-01-04 16:15:24 +01:00
2020-07-05 01:33:34 +02:00
void test_determinism ( TestContext & context )
2020-01-04 16:15:24 +01:00
{
double tickSize = 1.0 / 15.0 ;
2021-05-23 21:31:36 +02:00
TypeNode rockType ( " rock " ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
Entity rootEntity ( context . newId ( ) ) ;
rootEntity . incRef ( ) ;
TerrainProperty terrainProperty { } ;
rootEntity . setProperty ( " terrain " , std : : unique_ptr < PropertyBase > ( terrainProperty . copy ( ) ) ) ;
Mercator : : Terrain & terrain = terrainProperty . getData ( rootEntity ) ;
2020-01-04 16:15:24 +01:00
terrain . setBasePoint ( 0 , 0 , Mercator : : BasePoint ( 40 ) ) ;
terrain . setBasePoint ( 0 , 1 , Mercator : : BasePoint ( 40 ) ) ;
terrain . setBasePoint ( 1 , 0 , Mercator : : BasePoint ( 10 ) ) ;
terrain . setBasePoint ( 1 , 1 , Mercator : : BasePoint ( 10 ) ) ;
2021-06-18 22:44:30 +02:00
rootEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
rootEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( 0 , 0 , - 64 ) , WFMath : : Point < 3 > ( 64 , 64 , 64 ) ) ;
2021-05-23 21:31:36 +02:00
std : : unique_ptr < TestPhysicalDomain > domain ( new TestPhysicalDomain ( rootEntity ) ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
Property < double > massProp { } ;
massProp . data ( ) = 100 ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
std : : vector < Ref < Entity > > entities ;
2020-01-04 16:15:24 +01:00
for ( size_t i = 0 ; i < 10 ; + + i ) {
for ( size_t j = 0 ; j < 10 ; + + j ) {
2021-05-23 21:31:36 +02:00
Ref < Entity > freeEntity ( new Entity ( context . newId ( ) ) ) ;
freeEntity - > setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
freeEntity - > setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
freeEntity - > requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( i , j , i + j ) ;
freeEntity - > requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 0.25f , 0 , - 0.25f ) , WFMath : : Point < 3 > ( - 0.25f , 0.5f , - 0.25f ) ) ;
2020-01-04 16:15:24 +01:00
domain - > addEntity ( * freeEntity ) ;
entities . push_back ( freeEntity ) ;
}
2017-01-29 17:13:01 +01:00
}
2020-01-04 16:15:24 +01:00
OpVector res ;
2017-01-29 17:13:01 +01:00
2020-01-04 16:15:24 +01:00
//First tick is setup, so we'll exclude that from time measurement
2017-01-29 17:13:01 +01:00
domain - > tick ( tickSize , res ) ;
2020-01-04 16:15:24 +01:00
//Inject ticks for two seconds
for ( int i = 0 ; i < 29 ; + + i ) {
domain - > tick ( tickSize , res ) ;
}
2017-01-29 17:13:01 +01:00
2020-01-04 16:15:24 +01:00
//Sample a couple of selected entities
//Note: this perhaps differs depending on version of Bullet and machine setup?
2021-06-18 22:44:30 +02:00
// ASSERT_EQUAL(entities[0]->requirePropertyClassFixed<PositionProperty>().data(), WFMath::Point<3>(0.495543, -0, 19.949));
// ASSERT_EQUAL(entities[10]->requirePropertyClassFixed<PositionProperty>().data(), WFMath::Point<3>(1, -0, 18.0217));
// ASSERT_EQUAL(entities[15]->requirePropertyClassFixed<PositionProperty>().data(), WFMath::Point<3>(2.61429, 0.0884429, 26.4489));
// ASSERT_EQUAL(entities[16]->requirePropertyClassFixed<PositionProperty>().data(), WFMath::Point<3>(0.948305, 0.105805, 18.7352));
// ASSERT_EQUAL(entities[55]->requirePropertyClassFixed<PositionProperty>().data(), WFMath::Point<3>(6.30361, -1.19749f, 28.0569));
2017-01-29 17:13:01 +01:00
2020-01-04 16:15:24 +01:00
}
2017-01-29 17:13:01 +01:00
2017-02-14 17:57:40 +01:00
2020-07-05 01:33:34 +02:00
void test_zoffset ( TestContext & context )
2020-01-04 16:15:24 +01:00
{
2017-02-14 17:57:40 +01:00
2021-05-23 21:31:36 +02:00
TypeNode rockType ( " rock " ) ;
ModeProperty modePlantedProperty { } ;
modePlantedProperty . set ( " planted " ) ;
2017-02-14 17:57:40 +01:00
2021-05-23 21:31:36 +02:00
Property < double > plantedOffsetBase { } ;
plantedOffsetBase . data ( ) = - 2 ;
2017-02-14 17:57:40 +01:00
2021-05-23 21:31:36 +02:00
Entity rootEntity ( context . newId ( ) ) ;
rootEntity . incRef ( ) ;
TerrainProperty terrainProperty { } ;
rootEntity . setProperty ( " terrain " , std : : unique_ptr < PropertyBase > ( terrainProperty . copy ( ) ) ) ;
Mercator : : Terrain & terrain = terrainProperty . getData ( rootEntity ) ;
2020-01-04 16:15:24 +01:00
terrain . setBasePoint ( 0 , 0 , Mercator : : BasePoint ( 10 ) ) ;
terrain . setBasePoint ( 0 , 1 , Mercator : : BasePoint ( 10 ) ) ;
terrain . setBasePoint ( 1 , 0 , Mercator : : BasePoint ( 10 ) ) ;
terrain . setBasePoint ( 1 , 1 , Mercator : : BasePoint ( 10 ) ) ;
2021-06-18 22:44:30 +02:00
rootEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
rootEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( 0 , - 64 , 0 ) , WFMath : : Point < 3 > ( 64 , 64 , 64 ) ) ;
2021-05-23 21:31:36 +02:00
std : : unique_ptr < TestPhysicalDomain > domain ( new TestPhysicalDomain ( rootEntity ) ) ;
2017-02-14 17:57:40 +01:00
2021-05-23 21:31:36 +02:00
TestWorld testWorld ( & rootEntity ) ;
2017-02-14 17:57:40 +01:00
2022-07-04 15:37:51 +02:00
Entity plantedEntity ( RouterId ( " planted " , context . newId ( ) ) ) ;
2021-05-23 21:31:36 +02:00
plantedEntity . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modePlantedProperty . copy ( ) ) ) ;
plantedEntity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
plantedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 30 , 10 , 30 ) ;
plantedEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , 0 , - 1 ) , WFMath : : Point < 3 > ( 1 , 10 , 1 ) ) ;
auto plantedOffset = ( Property < double > * ) plantedEntity . setProperty ( " planted_offset " , std : : unique_ptr < PropertyBase > ( plantedOffsetBase . copy ( ) ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( plantedEntity ) ;
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( plantedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , WFMath : : Point < 3 > ( 30 , 8.01695 , 30 ) , epsilon ) ;
2017-02-14 17:57:40 +01:00
2020-01-04 16:15:24 +01:00
plantedOffset - > data ( ) = - 3 ;
2021-05-31 00:05:25 +02:00
plantedOffset - > apply ( plantedEntity ) ;
2021-05-23 21:31:36 +02:00
plantedEntity . propertyApplied . emit ( " planted_offset " , * plantedOffset ) ;
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( plantedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , WFMath : : Point < 3 > ( 30 , 7.01695 , 30 ) , epsilon ) ;
2017-02-14 17:57:40 +01:00
2020-01-04 16:15:24 +01:00
}
2017-02-14 17:57:40 +01:00
2020-07-05 01:33:34 +02:00
void test_zscaledoffset ( TestContext & context )
2020-01-04 16:15:24 +01:00
{
2021-05-23 21:31:36 +02:00
TypeNode rockType ( " rock " ) ;
ModeProperty modePlantedProperty { } ;
modePlantedProperty . set ( " planted " ) ;
Property < double > plantedScaledOffsetBase { } ;
plantedScaledOffsetBase . data ( ) = - 0.2 ;
Entity rootEntity ( context . newId ( ) ) ;
rootEntity . incRef ( ) ;
TerrainProperty terrainProperty { } ;
rootEntity . setProperty ( " terrain " , std : : unique_ptr < PropertyBase > ( terrainProperty . copy ( ) ) ) ;
Mercator : : Terrain & terrain = terrainProperty . getData ( rootEntity ) ;
2020-01-04 16:15:24 +01:00
terrain . setBasePoint ( 0 , 0 , Mercator : : BasePoint ( 10 ) ) ;
terrain . setBasePoint ( 0 , 1 , Mercator : : BasePoint ( 10 ) ) ;
terrain . setBasePoint ( 1 , 0 , Mercator : : BasePoint ( 10 ) ) ;
terrain . setBasePoint ( 1 , 1 , Mercator : : BasePoint ( 10 ) ) ;
2021-06-18 22:44:30 +02:00
rootEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
rootEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( 0 , - 64 , 0 ) , WFMath : : Point < 3 > ( 64 , 64 , 64 ) ) ;
2021-05-23 21:31:36 +02:00
std : : unique_ptr < TestPhysicalDomain > domain ( new TestPhysicalDomain ( rootEntity ) ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
TestWorld testWorld ( & rootEntity ) ;
2020-01-04 16:15:24 +01:00
2022-07-04 15:37:51 +02:00
Entity plantedEntity ( RouterId ( " planted " , context . newId ( ) ) ) ;
2021-05-23 21:31:36 +02:00
plantedEntity . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modePlantedProperty . copy ( ) ) ) ;
plantedEntity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
plantedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 30 , 10 , 30 ) ;
plantedEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 1 , 0 , - 1 ) , WFMath : : Point < 3 > ( 1 , 10 , 10 ) ) ;
auto plantedScaledOffset = ( Property < double > * ) plantedEntity . setProperty ( " planted_scaled_offset " , std : : unique_ptr < PropertyBase > ( plantedScaledOffsetBase . copy ( ) ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( plantedEntity ) ;
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( plantedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , WFMath : : Point < 3 > ( 30 , 8.01695 , 30 ) , epsilon ) ;
2020-01-04 16:15:24 +01:00
plantedScaledOffset - > data ( ) = - 0.3 ;
2021-05-31 00:05:25 +02:00
plantedScaledOffset - > apply ( plantedEntity ) ;
2021-05-23 21:31:36 +02:00
plantedEntity . propertyApplied . emit ( " planted_offset " , * plantedScaledOffset ) ;
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( plantedEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) , WFMath : : Point < 3 > ( 30 , 7.01695 , 30 ) , epsilon ) ;
2017-02-14 17:57:40 +01:00
2020-01-04 16:15:24 +01:00
}
2017-02-14 21:41:01 +01:00
2020-01-04 16:15:24 +01:00
2020-07-05 01:33:34 +02:00
void test_visibility ( TestContext & context )
2017-02-14 21:41:01 +01:00
{
2021-05-23 21:31:36 +02:00
TypeNode rockType ( " rock " ) ;
TypeNode humanType ( " human " ) ;
ModeProperty modePlantedProperty { } ;
modePlantedProperty . set ( " planted " ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
VisibilityDistanceProperty visibilityProperty { } ;
visibilityProperty . set ( 1000.f ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
Entity rootEntity ( context . newId ( ) ) ;
rootEntity . incRef ( ) ;
2021-06-18 22:44:30 +02:00
rootEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
rootEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 64 , 0 , - 64 ) , WFMath : : Point < 3 > ( 64 , 64 , 64 ) ) ;
2021-05-23 21:31:36 +02:00
std : : unique_ptr < TestPhysicalDomain > domain ( new TestPhysicalDomain ( rootEntity ) ) ;
2020-01-04 16:15:24 +01:00
2021-05-23 21:31:36 +02:00
TestWorld testWorld ( & rootEntity ) ;
2020-01-04 16:15:24 +01:00
2022-07-04 15:37:51 +02:00
Entity smallEntity1 ( RouterId ( " small1 " , context . newId ( ) ) ) ;
2021-05-23 21:31:36 +02:00
smallEntity1 . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modePlantedProperty . copy ( ) ) ) ;
smallEntity1 . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
smallEntity1 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 30 , 0 , 30 ) ;
smallEntity1 . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 0.2f , 0 , - 0.2f ) , WFMath : : Point < 3 > ( 0.2 , 0.4 , 0.2 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( smallEntity1 ) ;
2020-01-04 16:15:24 +01:00
2022-07-04 15:37:51 +02:00
Entity smallEntity2 ( RouterId ( " small2 " , context . newId ( ) ) ) ;
2021-05-23 21:31:36 +02:00
smallEntity2 . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modePlantedProperty . copy ( ) ) ) ;
smallEntity2 . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
smallEntity2 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( - 31 , 0 , - 31 ) ;
smallEntity2 . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 0.2f , 0 , - 0.2f ) , WFMath : : Point < 3 > ( 0.2 , 0.4 , 0.2 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( smallEntity2 ) ;
2020-01-04 16:15:24 +01:00
//This entity should always be seen, as "visibility" is specified.
2022-07-04 15:37:51 +02:00
Entity smallVisibleEntity ( RouterId ( " smallVisible " , context . newId ( ) ) ) ;
2021-05-23 21:31:36 +02:00
smallVisibleEntity . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modePlantedProperty . copy ( ) ) ) ;
smallVisibleEntity . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
smallVisibleEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( - 63 , 0 , - 63 ) ;
smallVisibleEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 0.2f , 0 , - 0.2f ) , WFMath : : Point < 3 > ( 0.2 , 0.4 , 0.2 ) ) ;
2021-05-23 21:31:36 +02:00
smallVisibleEntity . setProperty ( VisibilityDistanceProperty : : property_name , std : : unique_ptr < PropertyBase > ( visibilityProperty . copy ( ) ) ) ;
domain - > addEntity ( smallVisibleEntity ) ;
2022-07-04 15:37:51 +02:00
Entity largeEntity1 ( RouterId ( " large1 " , context . newId ( ) ) ) ;
2021-05-23 21:31:36 +02:00
largeEntity1 . setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modePlantedProperty . copy ( ) ) ) ;
largeEntity1 . setType ( & rockType ) ;
2021-06-18 22:44:30 +02:00
largeEntity1 . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 0 , 0 , 0 ) ;
largeEntity1 . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 10.f , 0 , - 10.f ) , WFMath : : Point < 3 > ( 10 , 20 , 10 ) ) ;
2021-05-23 21:31:36 +02:00
domain - > addEntity ( largeEntity1 ) ;
2022-07-04 15:37:51 +02:00
Entity observerEntity ( RouterId ( " observer " , context . newId ( ) ) ) ;
2021-05-23 21:31:36 +02:00
observerEntity . setType ( & humanType ) ;
2021-06-18 22:44:30 +02:00
observerEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( - 30 , 0 , - 30 ) ;
observerEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 0.2f , 0 , - 0.2f ) , WFMath : : Point < 3 > ( 0.2 , 2 , 0.2 ) ) ;
2021-05-23 21:31:36 +02:00
observerEntity . addFlags ( entity_perceptive ) ;
domain - > addEntity ( observerEntity ) ;
2017-02-14 21:41:01 +01:00
2020-01-04 16:15:24 +01:00
OpVector res ;
std : : set < LocatedEntity * > transformedEntities ;
domain - > tick ( 0.1 , res ) ;
2017-02-14 21:41:01 +01:00
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( domain - > isEntityVisibleFor ( observerEntity , observerEntity ) ) ;
2018-04-19 10:19:35 +02:00
2020-01-04 16:15:24 +01:00
{
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( domain - > isEntityVisibleFor ( observerEntity , smallVisibleEntity ) ) ;
ASSERT_TRUE ( domain - > isEntityVisibleFor ( observerEntity , smallEntity2 ) ) ;
ASSERT_TRUE ( domain - > isEntityVisibleFor ( observerEntity , largeEntity1 ) ) ;
ASSERT_FALSE ( domain - > isEntityVisibleFor ( observerEntity , smallEntity1 ) ) ;
2020-01-04 16:15:24 +01:00
std : : list < LocatedEntity * > observedList ;
2021-05-23 21:31:36 +02:00
domain - > getVisibleEntitiesFor ( observerEntity , observedList ) ;
2020-01-04 16:15:24 +01:00
ASSERT_EQUAL ( 5u , observedList . size ( ) ) ;
ASSERT_TRUE ( std : : find_if ( observedList . begin ( ) , observedList . end ( ) , [ ] ( const LocatedEntity * entity ) { return entity - > getId ( ) = = " small2 " ; } ) ! = observedList . end ( ) ) ;
ASSERT_TRUE ( std : : find_if ( observedList . begin ( ) , observedList . end ( ) , [ ] ( const LocatedEntity * entity ) { return entity - > getId ( ) = = " smallVisible " ; } ) ! = observedList . end ( ) ) ;
ASSERT_TRUE ( std : : find_if ( observedList . begin ( ) , observedList . end ( ) , [ ] ( const LocatedEntity * entity ) { return entity - > getId ( ) = = " large1 " ; } ) ! = observedList . end ( ) ) ;
ASSERT_TRUE ( std : : find_if ( observedList . begin ( ) , observedList . end ( ) , [ ] ( const LocatedEntity * entity ) { return entity - > getId ( ) = = " observer " ; } ) ! = observedList . end ( ) ) ;
}
//Now move the observer to "small1"
2021-05-23 21:31:36 +02:00
domain - > applyTransform ( observerEntity , Domain : : TransformData { WFMath : : Quaternion ( ) , WFMath : : Point < 3 > ( 30 , 0 , 30 ) , nullptr , { } } , transformedEntities ) ;
2020-01-04 16:15:24 +01:00
//Force visibility updates
domain - > tick ( 2 , res ) ;
{
2021-05-23 21:31:36 +02:00
ASSERT_TRUE ( domain - > isEntityVisibleFor ( observerEntity , smallVisibleEntity ) ) ;
ASSERT_TRUE ( domain - > isEntityVisibleFor ( observerEntity , smallEntity1 ) ) ;
ASSERT_TRUE ( domain - > isEntityVisibleFor ( observerEntity , largeEntity1 ) ) ;
ASSERT_FALSE ( domain - > isEntityVisibleFor ( observerEntity , smallEntity2 ) ) ;
2017-02-14 21:41:01 +01:00
2020-01-04 16:15:24 +01:00
std : : list < LocatedEntity * > observedList ;
2017-02-14 21:41:01 +01:00
2021-05-23 21:31:36 +02:00
domain - > getVisibleEntitiesFor ( observerEntity , observedList ) ;
2017-02-14 21:41:01 +01:00
2020-01-04 16:15:24 +01:00
ASSERT_EQUAL ( 5u , observedList . size ( ) ) ;
ASSERT_TRUE ( std : : find_if ( observedList . begin ( ) , observedList . end ( ) , [ ] ( const LocatedEntity * entity ) { return entity - > getId ( ) = = " small1 " ; } ) ! = observedList . end ( ) ) ;
ASSERT_TRUE ( std : : find_if ( observedList . begin ( ) , observedList . end ( ) , [ ] ( const LocatedEntity * entity ) { return entity - > getId ( ) = = " smallVisible " ; } ) ! = observedList . end ( ) ) ;
ASSERT_TRUE ( std : : find_if ( observedList . begin ( ) , observedList . end ( ) , [ ] ( const LocatedEntity * entity ) { return entity - > getId ( ) = = " large1 " ; } ) ! = observedList . end ( ) ) ;
ASSERT_TRUE ( std : : find_if ( observedList . begin ( ) , observedList . end ( ) , [ ] ( const LocatedEntity * entity ) { return entity - > getId ( ) = = " observer " ; } ) ! = observedList . end ( ) ) ;
2018-04-19 10:19:35 +02:00
2020-01-04 16:15:24 +01:00
}
2017-02-14 21:41:01 +01:00
}
2017-02-15 21:48:43 +01:00
2020-01-04 16:15:24 +01:00
2020-07-05 01:33:34 +02:00
void test_visibilityPerformance ( TestContext & context ) ;
2020-01-04 16:15:24 +01:00
2020-07-05 01:33:34 +02:00
void test_stairs ( TestContext & context )
2020-01-04 16:15:24 +01:00
{
2021-05-23 21:31:36 +02:00
TypeNode rockType ( " rock " ) ;
TypeNode humanType ( " human " ) ;
ModeProperty modePlantedProperty { } ;
modePlantedProperty . set ( " planted " ) ;
Property < double > massProp { } ;
massProp . data ( ) = 100 ;
Property < double > speedGroundProperty { } ;
speedGroundProperty . data ( ) = 5.0 ;
PropelProperty propelProperty { } ;
propelProperty . data ( ) = WFMath : : Vector < 3 > ( 0 , 0 , 1.0 / speedGroundProperty . data ( ) ) ;
2020-01-04 16:15:24 +01:00
AngularFactorProperty angularZeroFactorProperty ;
angularZeroFactorProperty . data ( ) = WFMath : : Vector < 3 > : : ZERO ( ) ;
GeometryProperty capsuleProperty ;
capsuleProperty . set ( Atlas : : Message : : MapType ( { { " type " , " capsule-y " } } ) ) ;
2017-06-20 22:28:51 +02:00
// Property<double>* stepFactorProp = new Property<double>();
// stepFactorProp->data() = 0.3;
2017-03-24 17:19:10 +01:00
2021-05-23 21:31:36 +02:00
humanType . injectProperty ( " speed_ground " , std : : unique_ptr < PropertyBase > ( speedGroundProperty . copy ( ) ) ) ;
2018-02-15 12:39:15 +01:00
2017-03-24 17:19:10 +01:00
2021-05-23 21:31:36 +02:00
Entity rootEntity ( context . newId ( ) ) ;
rootEntity . incRef ( ) ;
2021-06-18 22:44:30 +02:00
rootEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
rootEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 64 , 0 , - 64 ) , WFMath : : Point < 3 > ( 64 , 64 , 64 ) ) ;
2021-05-23 21:31:36 +02:00
std : : unique_ptr < TestPhysicalDomain > domain ( new TestPhysicalDomain ( rootEntity ) ) ;
2017-03-24 17:19:10 +01:00
2021-05-23 21:31:36 +02:00
TestWorld testWorld ( & rootEntity ) ;
2017-03-24 17:19:10 +01:00
2021-05-23 21:31:36 +02:00
std : : vector < Ref < Entity > > stepElements ;
2020-01-04 16:15:24 +01:00
//Create 10 entities at increasing height, forming a stair.
for ( int i = 0 ; i < 10 ; + + i ) {
2021-05-23 21:31:36 +02:00
Ref < Entity > stepElement ( new Entity ( context . newId ( ) ) ) ;
stepElement - > setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modePlantedProperty . copy ( ) ) ) ;
2020-01-04 16:15:24 +01:00
float height = 0.1f + ( i * 0.1f ) ;
float zPos = i * 0.2f ;
WFMath : : Point < 3 > pos ( 0 , 0 , zPos ) ;
WFMath : : AxisBox < 3 > bbox ( WFMath : : Point < 3 > ( - 0.4f , 0 , - 0.1f ) , WFMath : : Point < 3 > ( 0.4f , height , 0.1f ) ) ;
2021-06-18 22:44:30 +02:00
stepElement - > requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = bbox ;
stepElement - > requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = pos ;
2021-05-23 21:31:36 +02:00
stepElement - > setType ( & rockType ) ;
2020-01-04 16:15:24 +01:00
domain - > addEntity ( * stepElement ) ;
2021-05-23 21:31:36 +02:00
stepElements . emplace_back ( stepElement ) ;
2020-01-04 16:15:24 +01:00
}
2017-03-24 17:19:10 +01:00
2020-01-04 16:15:24 +01:00
//First with an entity which doesn't step; it should collide and be kept in place
{
2022-07-04 15:37:51 +02:00
Ref < Entity > human = new Entity ( RouterId { " human " , context . newId ( ) } ) ;
2020-01-04 16:15:24 +01:00
human - > setProperty ( AngularFactorProperty : : property_name , std : : unique_ptr < PropertyBase > ( angularZeroFactorProperty . copy ( ) ) ) ;
2021-05-23 21:31:36 +02:00
human - > setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
human - > setProperty ( PropelProperty : : property_name , std : : unique_ptr < PropertyBase > ( propelProperty . copy ( ) ) ) ;
human - > setType ( & humanType ) ;
2021-06-18 22:44:30 +02:00
human - > requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = { 0 , 0 , - 1 } ;
human - > requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = { { - 0.4f , 0 , - 0.4f } ,
{ 0.4 , 1.8 , 0.4 } } ;
2020-01-04 16:15:24 +01:00
domain - > addEntity ( * human ) ;
2017-03-24 17:19:10 +01:00
2020-01-04 16:15:24 +01:00
OpVector res ;
domain - > tick ( 2 , res ) ;
2017-03-24 17:19:10 +01:00
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( - 0.5f , human - > requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . z ( ) , 0.1f ) ;
2020-01-04 16:15:24 +01:00
domain - > removeEntity ( * human ) ;
}
2017-03-24 17:19:10 +01:00
2020-01-04 16:15:24 +01:00
//Then with an entity with a capsule geometry, it should step
{
2022-07-04 15:37:51 +02:00
Ref < Entity > human = new Entity ( RouterId { " human " , context . newId ( ) } ) ;
2020-01-04 16:15:24 +01:00
//human->setProperty("step_factor", stepFactorProp));
human - > setProperty ( AngularFactorProperty : : property_name , std : : unique_ptr < PropertyBase > ( angularZeroFactorProperty . copy ( ) ) ) ;
2021-05-23 21:31:36 +02:00
human - > setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
human - > setProperty ( PropelProperty : : property_name , std : : unique_ptr < PropertyBase > ( propelProperty . copy ( ) ) ) ;
2020-01-04 16:15:24 +01:00
human - > setProperty ( GeometryProperty : : property_name , std : : unique_ptr < PropertyBase > ( capsuleProperty . copy ( ) ) ) ;
2021-05-23 21:31:36 +02:00
human - > setType ( & humanType ) ;
2021-06-18 22:44:30 +02:00
human - > requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 0 , 0 , - 1 ) ;
human - > requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 0.4f , 0 , - 0.4f ) , WFMath : : Point < 3 > ( 0.4 , 1.8 , 0.4 ) ) ;
2020-01-04 16:15:24 +01:00
domain - > addEntity ( * human ) ;
2017-03-24 17:19:10 +01:00
2020-01-04 16:15:24 +01:00
OpVector res ;
domain - > tick ( 2 , res ) ;
2017-03-24 17:19:10 +01:00
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( 0.5 , human - > requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . z ( ) , 0.3f ) ;
2020-01-04 16:15:24 +01:00
domain - > removeEntity ( * human ) ;
}
2017-03-24 17:19:10 +01:00
2020-01-04 16:15:24 +01:00
//Also place a tilted square entity, which is too tilted to allow for stepping on
//The human entity shouldn't step up on the tilted entity
{
2017-03-24 17:19:10 +01:00
2022-07-04 15:37:51 +02:00
Ref < Entity > stepElement = new Entity ( RouterId { " tilted " , context . newId ( ) } ) ;
2021-05-23 21:31:36 +02:00
stepElement - > setProperty ( ModeProperty : : property_name , std : : unique_ptr < PropertyBase > ( modePlantedProperty . copy ( ) ) ) ;
2020-01-04 16:15:24 +01:00
WFMath : : Point < 3 > pos ( 20 , 0 , 0 ) ;
WFMath : : AxisBox < 3 > bbox ( WFMath : : Point < 3 > ( - 0.4f , 0.f , 0 ) , WFMath : : Point < 3 > ( 0.4f , 1 , 0.4f ) ) ;
2021-06-18 22:44:30 +02:00
stepElement - > requirePropertyClassFixed < OrientationProperty > ( ) . data ( ) . rotate ( WFMath : : Quaternion ( 0 , WFMath : : numeric_constants < float > : : pi ( ) * 0.2f ) ) ;
stepElement - > requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = bbox ;
stepElement - > requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = pos ;
2021-05-23 21:31:36 +02:00
stepElement - > setType ( & rockType ) ;
2020-01-04 16:15:24 +01:00
domain - > addEntity ( * stepElement ) ;
2022-07-04 15:37:51 +02:00
Ref < Entity > human = new Entity ( RouterId { " human " , context . newId ( ) } ) ;
2020-01-04 16:15:24 +01:00
//human->setProperty("step_factor", stepFactorProp));
human - > setProperty ( AngularFactorProperty : : property_name , std : : unique_ptr < PropertyBase > ( angularZeroFactorProperty . copy ( ) ) ) ;
2021-05-23 21:31:36 +02:00
human - > setProperty ( " mass " , std : : unique_ptr < PropertyBase > ( massProp . copy ( ) ) ) ;
human - > setProperty ( PropelProperty : : property_name , std : : unique_ptr < PropertyBase > ( propelProperty . copy ( ) ) ) ;
2020-01-04 16:15:24 +01:00
human - > setProperty ( GeometryProperty : : property_name , std : : unique_ptr < PropertyBase > ( capsuleProperty . copy ( ) ) ) ;
2021-05-23 21:31:36 +02:00
human - > setType ( & humanType ) ;
2021-06-18 22:44:30 +02:00
human - > requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > ( 20 , 0 , - 1 ) ;
human - > requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 0.4f , 0 , - 0.4f ) , WFMath : : Point < 3 > ( 0.4 , 1.8 , 0.4 ) ) ;
2020-01-04 16:15:24 +01:00
domain - > addEntity ( * human ) ;
2017-03-24 17:19:10 +01:00
2020-01-04 16:15:24 +01:00
OpVector res ;
domain - > tick ( 2 , res ) ;
2017-03-24 17:19:10 +01:00
2021-06-18 22:44:30 +02:00
ASSERT_FUZZY_EQUAL ( 0 , human - > requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . y ( ) , 0.01f ) ;
ASSERT_FUZZY_EQUAL ( - 0.4f , human - > requirePropertyClassFixed < PositionProperty > ( ) . data ( ) . z ( ) , 0.1f ) ;
2020-01-04 16:15:24 +01:00
}
2017-03-24 17:19:10 +01:00
2020-01-04 16:15:24 +01:00
}
2017-09-01 13:19:27 +02:00
2020-07-05 01:33:34 +02:00
void test_terrainPrecision ( TestContext & context )
2020-01-04 16:15:24 +01:00
{
2017-09-01 13:19:27 +02:00
2021-05-23 21:31:36 +02:00
Entity rootEntity ( context . newId ( ) ) ;
rootEntity . incRef ( ) ;
TerrainProperty terrainProperty { } ;
rootEntity . setProperty ( " terrain " , std : : unique_ptr < PropertyBase > ( terrainProperty . copy ( ) ) ) ;
Mercator : : Terrain & terrain = terrainProperty . getData ( rootEntity ) ;
2020-01-04 16:15:24 +01:00
terrain . setBasePoint ( 0 , 0 , Mercator : : BasePoint ( 10 ) ) ;
terrain . setBasePoint ( 0 , 1 , Mercator : : BasePoint ( 15 ) ) ;
terrain . setBasePoint ( 0 , - 1 , Mercator : : BasePoint ( 15 ) ) ;
terrain . setBasePoint ( 1 , 0 , Mercator : : BasePoint ( 20 ) ) ;
terrain . setBasePoint ( 1 , 1 , Mercator : : BasePoint ( 25 ) ) ;
terrain . setBasePoint ( 1 , - 1 , Mercator : : BasePoint ( 30 ) ) ;
terrain . setBasePoint ( - 1 , 0 , Mercator : : BasePoint ( 35 ) ) ;
terrain . setBasePoint ( - 1 , 1 , Mercator : : BasePoint ( 40 ) ) ;
terrain . setBasePoint ( - 1 , - 1 , Mercator : : BasePoint ( 45 ) ) ;
2021-06-18 22:44:30 +02:00
rootEntity . requirePropertyClassFixed < PositionProperty > ( ) . data ( ) = WFMath : : Point < 3 > : : ZERO ( ) ;
rootEntity . requirePropertyClassFixed < BBoxProperty > ( ) . data ( ) = WFMath : : AxisBox < 3 > ( WFMath : : Point < 3 > ( - 64 , - 64 , - 64 ) , WFMath : : Point < 3 > ( 64 , 64 , 64 ) ) ;
2021-05-23 21:31:36 +02:00
std : : unique_ptr < TestPhysicalDomain > domain ( new TestPhysicalDomain ( rootEntity ) ) ;
2020-01-04 16:15:24 +01:00
auto checkHeightFunc = [ & ] ( float x , float z ) {
PhysicalWorld * physicalWorld = domain - > test_getPhysicalWorld ( ) ;
float mercatorHeight ;
WFMath : : Vector < 3 > normal ;
terrain . getHeightAndNormal ( x , z , mercatorHeight , normal ) ;
btVector3 from ( x , 63 , z ) ;
btVector3 to ( x , - 63 , z ) ;
btCollisionWorld : : ClosestRayResultCallback callback ( from , to ) ;
physicalWorld - > rayTest ( from , to , callback ) ;
ASSERT_FUZZY_EQUAL ( mercatorHeight , callback . m_hitPointWorld . y ( ) , 0.1 ) ;
2018-01-10 15:11:20 +01:00
/*
ASSERT_FUZZY_EQUAL ( normal . x ( ) , callback . m_hitNormalWorld . x ( ) , 0.1 ) ;
ASSERT_FUZZY_EQUAL ( normal . y ( ) , callback . m_hitNormalWorld . y ( ) , 0.1 ) ;
ASSERT_FUZZY_EQUAL ( normal . z ( ) , callback . m_hitNormalWorld . z ( ) , 0.1 ) ;
*/
2020-01-04 16:15:24 +01:00
} ;
checkHeightFunc ( 1 , 1 ) ;
checkHeightFunc ( 10 , 10 ) ;
checkHeightFunc ( 15 , 15 ) ;
checkHeightFunc ( - 15 , 15 ) ;
checkHeightFunc ( - 15 , - 15 ) ;
checkHeightFunc ( 15 , - 15 ) ;
}
} ;
2017-09-01 13:19:27 +02:00
2017-01-29 17:13:01 +01:00
int main ( )
{
2020-07-05 01:33:34 +02:00
Tested t ;
2017-01-29 17:13:01 +01:00
return t . run ( ) ;
}