mirror of
https://github.com/Ttanasart-pt/Pixel-Composer.git
synced 2025-02-15 22:55:13 +01:00
296 lines
8.8 KiB
Text
296 lines
8.8 KiB
Text
/// @func BBMOD_AABBCollider([_position[, _size]])
|
|
///
|
|
/// @extends BBMOD_Collider
|
|
///
|
|
/// @desc An axis-aligned bounding box (AABB) collider.
|
|
///
|
|
/// @param {Struct.BBMOD_Vec3} [_position] The position (center) of the AABB.
|
|
/// Defaults to `(0, 0, 0)`.
|
|
/// @param {Struct.BBMOD_Vec3} [_size] The size of the AABB on each
|
|
/// axis in both directions (e.g. `new BBMOD_Vec3(2)` would make a 4x4x4 box).
|
|
/// Defaults to `(0.5, 0.5, 0.5)`.
|
|
///
|
|
/// @see BBMOD_FrustumCollider
|
|
/// @see BBMOD_PlaneCollider
|
|
/// @see BBMOD_SphereCollider
|
|
function BBMOD_AABBCollider(
|
|
_position=new BBMOD_Vec3(),
|
|
_size=new BBMOD_Vec3(0.5)
|
|
) : BBMOD_Collider() constructor
|
|
{
|
|
BBMOD_CLASS_GENERATED_BODY;
|
|
|
|
/// @var {Struct.BBMOD_Vec3} The center position of the AABB.
|
|
Position = _position;
|
|
|
|
/// @var {Struct.BBMOD_Vec3} The size of the AABB on each axis in both
|
|
/// directions (e.g. `new BBMOD_Vec3(2)` would be a 4x4x4 box).
|
|
Size = _size;
|
|
|
|
/// @func FromMinMax(_min, _max)
|
|
///
|
|
/// @desc Initializes the AABB using its minimum and maximum coordinates.
|
|
///
|
|
/// @param {Struct.BBMOD_Vec3} _min The minimum coordinate of the AABB.
|
|
/// @param {Struct.BBMOD_Vec3} _max The maximum coordinate of the AABB.
|
|
///
|
|
/// @return {Struct.BBMOD_AABBCollider} Returns `self`.
|
|
// Source: https://github.com/gszauer/GamePhysicsCookbook/blob/a0b8ee0c39fed6d4b90bb6d2195004dfcf5a1115/Code/Geometry3D.cpp#L37
|
|
static FromMinMax = function (_min, _max) {
|
|
gml_pragma("forceinline");
|
|
Position = _min.Add(_max).Scale(0.5);
|
|
Size = _max.Sub(_min).Scale(0.5);
|
|
return self;
|
|
};
|
|
|
|
/// @func GetMin()
|
|
///
|
|
/// @desc Retrieves the minimum coordinate of the AABB.
|
|
///
|
|
/// @return {Struct.BBMOD_Vec3} The minimum coordinate.
|
|
// Source: https://github.com/gszauer/GamePhysicsCookbook/blob/a0b8ee0c39fed6d4b90bb6d2195004dfcf5a1115/Code/Geometry3D.cpp#L24
|
|
static GetMin = function () {
|
|
gml_pragma("forceinline");
|
|
var _p1 = Position.Add(Size);
|
|
var _p2 = Position.Sub(Size);
|
|
return _p1.Minimize(_p2);
|
|
};
|
|
|
|
/// @func GetMax()
|
|
///
|
|
/// @desc Retrieves the maximum coordinate of the AABB.
|
|
///
|
|
/// @return {Struct.BBMOD_Vec3} The maximum coordinate.
|
|
// Source: https://github.com/gszauer/GamePhysicsCookbook/blob/a0b8ee0c39fed6d4b90bb6d2195004dfcf5a1115/Code/Geometry3D.cpp#L30
|
|
static GetMax = function () {
|
|
gml_pragma("forceinline");
|
|
var _p1 = Position.Add(Size);
|
|
var _p2 = Position.Sub(Size);
|
|
return _p1.Maximize(_p2);
|
|
};
|
|
|
|
// Source: https://github.com/gszauer/GamePhysicsCookbook/blob/a0b8ee0c39fed6d4b90bb6d2195004dfcf5a1115/Code/Geometry3D.cpp#L149
|
|
static GetClosestPoint = function (_point) {
|
|
gml_pragma("forceinline");
|
|
return _point.Clamp(GetMin(), GetMax());
|
|
};
|
|
|
|
// Source: https://github.com/gszauer/GamePhysicsCookbook/blob/a0b8ee0c39fed6d4b90bb6d2195004dfcf5a1115/Code/Geometry3D.cpp#L340
|
|
static TestAABB = function (_aabb) {
|
|
gml_pragma("forceinline");
|
|
var _aMin = GetMin();
|
|
var _aMax = GetMax();
|
|
var _bMin = _aabb.GetMin();
|
|
var _bMax = _aabb.GetMax();
|
|
return ((_aMin.X <= _bMax.X && _aMax.X >= _bMin.X)
|
|
&& (_aMin.Y <= _bMax.Y && _aMax.Y >= _bMin.Y)
|
|
&& (_aMin.Z <= _bMax.Z && _aMax.Z >= _bMin.Z));
|
|
};
|
|
|
|
// Source: https://github.com/gszauer/GamePhysicsCookbook/blob/a0b8ee0c39fed6d4b90bb6d2195004dfcf5a1115/Code/Geometry3D.cpp#L482
|
|
static TestPlane = function (_plane) {
|
|
gml_pragma("forceinline");
|
|
var _pLen = (Size.X * abs(_plane.Normal.X)
|
|
+ Size.Y * abs(_plane.Normal.Y)
|
|
+ Size.Z * abs(_plane.Normal.Z));
|
|
var _dist = _plane.Normal.Dot(Position) - _plane.Distance;
|
|
return (abs(_dist) <= _pLen);
|
|
};
|
|
|
|
// Source: https://github.com/gszauer/GamePhysicsCookbook/blob/a0b8ee0c39fed6d4b90bb6d2195004dfcf5a1115/Code/Geometry3D.cpp#L108
|
|
static TestPoint = function (_point) {
|
|
gml_pragma("forceinline");
|
|
var _min = GetMin();
|
|
var _max = GetMax();
|
|
if (_point.X < _min.X || _point.Y < _min.Y || _point.Z < _min.Z)
|
|
{
|
|
return false;
|
|
}
|
|
if (_point.X > _max.X || _point.Y > _max.Y || _point.Z > _max.Z)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
static TestSphere = function (_sphere) {
|
|
gml_pragma("forceinline");
|
|
return _sphere.TestAABB(self);
|
|
};
|
|
|
|
// Source: https://github.com/gszauer/GamePhysicsCookbook/blob/a0b8ee0c39fed6d4b90bb6d2195004dfcf5a1115/Code/Geometry3D.cpp#L707
|
|
static Raycast = function (_ray, _result=undefined) {
|
|
if (_result != undefined)
|
|
{
|
|
_result.Reset();
|
|
}
|
|
|
|
var _min = GetMin();
|
|
var _max = GetMax();
|
|
|
|
var _t1 = (_min.X - _ray.Origin.X)
|
|
/ (bbmod_cmp(_ray.Direction.X, 0.0) ? 0.00001 : _ray.Direction.X);
|
|
var _t2 = (_max.X - _ray.Origin.X)
|
|
/ (bbmod_cmp(_ray.Direction.X, 0.0) ? 0.00001 : _ray.Direction.X);
|
|
var _t3 = (_min.Y - _ray.Origin.Y)
|
|
/ (bbmod_cmp(_ray.Direction.Y, 0.0) ? 0.00001 : _ray.Direction.Y);
|
|
var _t4 = (_max.Y - _ray.Origin.Y)
|
|
/ (bbmod_cmp(_ray.Direction.Y, 0.0) ? 0.00001 : _ray.Direction.Y);
|
|
var _t5 = (_min.Z - _ray.Origin.Z)
|
|
/ (bbmod_cmp(_ray.Direction.Z, 0.0) ? 0.00001 : _ray.Direction.Z);
|
|
var _t6 = (_max.Z - _ray.Origin.Z)
|
|
/ (bbmod_cmp(_ray.Direction.Z, 0.0) ? 0.00001 : _ray.Direction.Z);
|
|
|
|
var _tmin = max(max(min(_t1, _t2), min(_t3, _t4)), min(_t5, _t6));
|
|
var _tmax = min(min(max(_t1, _t2), max(_t3, _t4)), max(_t5, _t6));
|
|
|
|
if (_tmax < 0.0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (_tmin > _tmax)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (_result != undefined)
|
|
{
|
|
var _tResult = (_tmin < 0.0) ? _tmax : _tmin;
|
|
|
|
_result.Distance = _tResult;
|
|
_result.Point = _ray.Origin.Add(_ray.Direction.Scale(_tResult));
|
|
|
|
for (var i = 0; i < 6; ++i)
|
|
{
|
|
var _ti;
|
|
|
|
switch (i)
|
|
{
|
|
case 0:
|
|
_ti = _t1;
|
|
break;
|
|
|
|
case 1:
|
|
_ti = _t2;
|
|
break;
|
|
|
|
case 2:
|
|
_ti = _t3;
|
|
break;
|
|
|
|
case 3:
|
|
_ti = _t4;
|
|
break;
|
|
|
|
case 4:
|
|
_ti = _t5;
|
|
break;
|
|
|
|
case 5:
|
|
_ti = _t6;
|
|
break;
|
|
}
|
|
|
|
if (bbmod_cmp(_tResult, _ti))
|
|
{
|
|
switch (i)
|
|
{
|
|
case 0:
|
|
_result.Normal = new BBMOD_Vec3(-1.0, 0.0, 0.0);
|
|
break;
|
|
|
|
case 1:
|
|
_result.Normal = new BBMOD_Vec3(1.0, 0.0, 0.0);
|
|
break;
|
|
|
|
case 2:
|
|
_result.Normal = new BBMOD_Vec3(0.0, -1.0, 0.0);
|
|
break;
|
|
|
|
case 3:
|
|
_result.Normal = new BBMOD_Vec3(0.0, 1.0, 0.0);
|
|
break;
|
|
|
|
case 4:
|
|
_result.Normal = new BBMOD_Vec3(0.0, 0.0, -1.0);
|
|
break;
|
|
|
|
case 5:
|
|
_result.Normal = new BBMOD_Vec3(0.0, 0.0, 1.0);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
static DrawDebug = function (_color=c_white, _alpha=1.0) {
|
|
var _vbuffer = global.__bbmodVBufferDebug;
|
|
|
|
var _x1 = Position.X - Size.X;
|
|
var _x2 = Position.X + Size.X;
|
|
var _y1 = Position.Y - Size.Y;
|
|
var _y2 = Position.Y + Size.Y;
|
|
var _z1 = Position.Z - Size.Z;
|
|
var _z2 = Position.Z + Size.Z;
|
|
|
|
vertex_begin(_vbuffer, BBMOD_VFORMAT_DEBUG.Raw);
|
|
|
|
// Bottom
|
|
// 1--2
|
|
// | |
|
|
// 4--3
|
|
vertex_position_3d(_vbuffer, _x1, _y1, _z1); vertex_color(_vbuffer, _color, _alpha);
|
|
vertex_position_3d(_vbuffer, _x2, _y1, _z1); vertex_color(_vbuffer, _color, _alpha);
|
|
|
|
vertex_position_3d(_vbuffer, _x2, _y1, _z1); vertex_color(_vbuffer, _color, _alpha);
|
|
vertex_position_3d(_vbuffer, _x2, _y2, _z1); vertex_color(_vbuffer, _color, _alpha);
|
|
|
|
vertex_position_3d(_vbuffer, _x2, _y2, _z1); vertex_color(_vbuffer, _color, _alpha);
|
|
vertex_position_3d(_vbuffer, _x1, _y2, _z1); vertex_color(_vbuffer, _color, _alpha);
|
|
|
|
vertex_position_3d(_vbuffer, _x1, _y2, _z1); vertex_color(_vbuffer, _color, _alpha);
|
|
vertex_position_3d(_vbuffer, _x1, _y1, _z1); vertex_color(_vbuffer, _color, _alpha);
|
|
|
|
// Top
|
|
// 1--2
|
|
// | |
|
|
// 4--3
|
|
vertex_position_3d(_vbuffer, _x1, _y1, _z2); vertex_color(_vbuffer, _color, _alpha);
|
|
vertex_position_3d(_vbuffer, _x2, _y1, _z2); vertex_color(_vbuffer, _color, _alpha);
|
|
|
|
vertex_position_3d(_vbuffer, _x2, _y1, _z2); vertex_color(_vbuffer, _color, _alpha);
|
|
vertex_position_3d(_vbuffer, _x2, _y2, _z2); vertex_color(_vbuffer, _color, _alpha);
|
|
|
|
vertex_position_3d(_vbuffer, _x2, _y2, _z2); vertex_color(_vbuffer, _color, _alpha);
|
|
vertex_position_3d(_vbuffer, _x1, _y2, _z2); vertex_color(_vbuffer, _color, _alpha);
|
|
|
|
vertex_position_3d(_vbuffer, _x1, _y2, _z2); vertex_color(_vbuffer, _color, _alpha);
|
|
vertex_position_3d(_vbuffer, _x1, _y1, _z2); vertex_color(_vbuffer, _color, _alpha);
|
|
|
|
// Sides
|
|
// 1--2
|
|
// | |
|
|
// 4--3
|
|
vertex_position_3d(_vbuffer, _x1, _y1, _z1); vertex_color(_vbuffer, _color, _alpha);
|
|
vertex_position_3d(_vbuffer, _x1, _y1, _z2); vertex_color(_vbuffer, _color, _alpha);
|
|
|
|
vertex_position_3d(_vbuffer, _x2, _y1, _z1); vertex_color(_vbuffer, _color, _alpha);
|
|
vertex_position_3d(_vbuffer, _x2, _y1, _z2); vertex_color(_vbuffer, _color, _alpha);
|
|
|
|
vertex_position_3d(_vbuffer, _x2, _y2, _z1); vertex_color(_vbuffer, _color, _alpha);
|
|
vertex_position_3d(_vbuffer, _x2, _y2, _z2); vertex_color(_vbuffer, _color, _alpha);
|
|
|
|
vertex_position_3d(_vbuffer, _x1, _y2, _z1); vertex_color(_vbuffer, _color, _alpha);
|
|
vertex_position_3d(_vbuffer, _x1, _y2, _z2); vertex_color(_vbuffer, _color, _alpha);
|
|
|
|
vertex_end(_vbuffer);
|
|
|
|
vertex_submit(_vbuffer, pr_linelist, -1);
|
|
|
|
return self;
|
|
};
|
|
}
|