mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-04 20:57:49 +00:00
182 lines
6.0 KiB
C++
182 lines
6.0 KiB
C++
#pragma once
|
|
|
|
#include "Voxel/Cell.h"
|
|
#include "v8kernel/BuoyancyConnector.h"
|
|
#include "v8World/Geometry.h"
|
|
#include "v8World/Contact.h"
|
|
|
|
/*
|
|
The Buoyancy feature manages all aspects of parts' interaction with water when they have come
|
|
into contact with water.
|
|
|
|
The Buoyancy contact is implemented as a standard contact type managed by ContactManager.
|
|
|
|
Each BuoyancyContact manages a few BuoyancyConnectors that represent the buoyancy and water
|
|
viscosity forces applied on the part.
|
|
|
|
Box Buoyancy is divided into 8 voxels, each voxel contributes one connector that represents
|
|
the buoyancy and viscosity force applied on that voxel shape.
|
|
*/
|
|
|
|
namespace RBX {
|
|
|
|
namespace Voxel { class Grid; }
|
|
namespace Voxel2 { class Grid; }
|
|
|
|
class BuoyancyContact : public Contact
|
|
{
|
|
public:
|
|
static const int MAX_CONNECTORS = 8;
|
|
static float waterViscosity;
|
|
static const float waterDensity;
|
|
|
|
typedef RBX::FixedArray<BuoyancyConnector*, MAX_CONNECTORS> ConnectorArray;
|
|
|
|
static Geometry::GeometryType determineGeometricType( Primitive *prim );
|
|
static BuoyancyContact* create( Primitive* p0, Primitive *p1 );
|
|
|
|
BuoyancyContact( Primitive* p0, Primitive* p1 );
|
|
~BuoyancyContact();
|
|
|
|
virtual Geometry::GeometryType getType() = 0;
|
|
|
|
ContactType getContactType() const override { return Contact_Buoyancy; }
|
|
|
|
void onPrimitiveContactParametersChanged() override;
|
|
|
|
private:
|
|
void deleteConnectors();
|
|
|
|
void updateBuoyancyFloatingForce();
|
|
|
|
protected:
|
|
ConnectorArray connectors;
|
|
Primitive* floaterPrim;
|
|
|
|
Voxel::Grid* voxelGrid;
|
|
Voxel2::Grid* smoothGrid;
|
|
|
|
float radius;
|
|
float fullSurfaceArea;
|
|
Vector3 fullBuoyancy;
|
|
|
|
bool worldPosUnderWater( const Vector3& pos );
|
|
bool isTouchingWater( Primitive* prim );
|
|
|
|
Voxel::Cell getWaterCell( Vector3int16 pos );
|
|
bool cellHasWater( Vector3int16 pos );
|
|
|
|
bool hasDistanceSubmergedUnderWater( const Vector3& worldpos, float& waterLevel, const Vector3& searchEnd );
|
|
bool worldPosAboveWater( const Vector3& worldpos, int minY, float& waterLevel );
|
|
Vector3 cellVelocity( const Vector3& worldpos );
|
|
|
|
void removeAllConnectorsFromKernel();
|
|
void putAllConnectorsInKernel();
|
|
void computeExtentsWaterBand( const Extents& extents, float& floatDistance, float& sinkDistance );
|
|
void updateConnectors();
|
|
|
|
// Contact API
|
|
void deleteAllConnectors() override;
|
|
int numConnectors() const override { return connectors.size(); }
|
|
ContactConnector* getConnector( int i ) override { return connectors[i]; }
|
|
bool stepContact() override;
|
|
bool computeIsColliding(float overlapIgnored) override;
|
|
bool computeIsCollidingUi(float overlapIgnored) override; // override to always return false so can build underwater; shouldn't affect HumanoidState code
|
|
|
|
// Buoyancy Shape API
|
|
virtual Vector3 getWaterVelocity(int i);
|
|
virtual void createConnectors() = 0;
|
|
virtual void updateWaterBand() = 0;
|
|
virtual void updateSubmergeRatio();
|
|
virtual void getSurfaceAreaInDirection(const Vector3& relativeVelocity, float& crossArea, float& tangentArea) = 0;
|
|
virtual void initializeCrossSections() = 0;
|
|
virtual Vector3 getCrossSections(int i, const Vector3& velocity) = 0;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
class BuoyancyBallContact : public BuoyancyContact
|
|
{
|
|
|
|
protected:
|
|
float crossSectionArea;
|
|
|
|
bool computeIsColliding(float overlapIgnored);
|
|
void createConnectors();
|
|
Vector3 getWaterVelocity(int i);
|
|
void updateWaterBand();
|
|
void updateSubmergeRatio();
|
|
void getSurfaceAreaInDirection(const Vector3& relativeVelocity, float& crossArea, float& tangentArea);
|
|
void initializeCrossSections();
|
|
virtual Vector3 getCrossSections(int, const Vector3&);
|
|
|
|
public:
|
|
BuoyancyBallContact( Primitive* p0, Primitive* p1 ) : BuoyancyContact(p0, p1) {}
|
|
Geometry::GeometryType getType() { return Geometry::GEOMETRY_BALL; }
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
class BuoyancyBoxContact : public BuoyancyContact
|
|
{
|
|
|
|
protected:
|
|
Vector3 crossSectionSurfaceAreas;
|
|
Vector3 tangentSurfaceAreas;
|
|
|
|
void createConnectors();
|
|
void updateWaterBand();
|
|
virtual void getSurfaceAreaInDirection(const Vector3& relativeVelocity, float& crossSectionArea, float& tangentSurfaceAread);
|
|
virtual void initializeCrossSections();
|
|
Vector3 getCrossSections( int i, const Vector3& velocity );
|
|
public:
|
|
BuoyancyBoxContact( Primitive* p0, Primitive* p1 );
|
|
Geometry::GeometryType getType() { return Geometry::GEOMETRY_BLOCK; }
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
class BuoyancyCylinderContact : public BuoyancyBoxContact
|
|
{
|
|
protected:
|
|
void updateSubmergeRatio();
|
|
void initializeCrossSections();
|
|
|
|
public:
|
|
BuoyancyCylinderContact( Primitive* p0, Primitive* p1 ) : BuoyancyBoxContact(p0, p1) {}
|
|
Geometry::GeometryType getType() { return Geometry::GEOMETRY_CYLINDER; }
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
class BuoyancyWedgeContact : public BuoyancyBoxContact
|
|
{
|
|
|
|
protected:
|
|
void updateSubmergeRatio();
|
|
void initializeCrossSections();
|
|
|
|
public:
|
|
BuoyancyWedgeContact( Primitive* p0, Primitive* p1 ) : BuoyancyBoxContact(p0, p1) {}
|
|
Geometry::GeometryType getType() { return Geometry::GEOMETRY_WEDGE; }
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
class BuoyancyCornerWedgeContact : public BuoyancyBoxContact
|
|
{
|
|
protected:
|
|
void updateSubmergeRatio();
|
|
void initializeCrossSections();
|
|
|
|
public:
|
|
BuoyancyCornerWedgeContact( Primitive* p0, Primitive* p1 ) : BuoyancyBoxContact(p0, p1) {}
|
|
Geometry::GeometryType getType() { return Geometry::GEOMETRY_CORNERWEDGE; }
|
|
};
|
|
}
|