This commit is contained in:
watrabi
2025-09-18 17:55:52 -04:00
commit 977f1ff4b8
15030 changed files with 17324420 additions and 0 deletions
+52
View File
@@ -0,0 +1,52 @@
#ifndef RBXG3D_FRUSTUM_H
#define RBXG3D_FRUSTUM_H
#include "G3D/Plane.h"
#include "G3D/Vector3.h"
namespace G3D
{
class CoordinateFrame;
}
namespace RBX {
class Extents;
class Frustum
{
public:
Frustum() {};
// fovx, fovy are in radians
Frustum(const G3D::Vector3& apex, const G3D::Vector3& dir, const G3D::Vector3& up, float nearDist, float farDist, float fovx, float fovy);
enum FrustumPlane
{
kPlaneNear = 0,
kPlaneRight,
kPlaneLeft,
kPlaneBottom,
kPlaneTop,
kPlaneFar,
kPlaneInvalid,
};
/** The faces in the frustum. When the
far plane is at infinity, there are 5 faces,
otherwise there are 6. The faces are in the order
N,R,L,B,T,[F].
*/
G3D::Array<G3D::Plane> faceArray;
bool containsPoint(const G3D::Vector3& point) const;
bool intersectsSphere(const G3D::Vector3& center, float radius) const;
bool containsAABB(const RBX::Extents& aabb) const;
bool intersectsAABB(const RBX::Extents& aabb, const G3D::CoordinateFrame& extentsFrame) const;
bool containsAABB(const RBX::Extents& aabb, const G3D::CoordinateFrame& extentsFrame) const;
};
} // namespace RBX
#endif
+272
View File
@@ -0,0 +1,272 @@
/**
Roblox
This is not the G3D 8.0 GCamera, instead it is from the old G3D release modified by Roblox.
@file RbxCamera.h
@maintainer Morgan McGuire, matrix@graphics3d.com
@created 2001-06-02
@edited 2006-02-11
*/
#ifndef G3D_RBX_CAMERA_H
#define G3D_RBX_CAMERA_H
#include "G3D/platform.h"
#include "G3D/CoordinateFrame.h"
#include "G3D/Vector3.h"
#include "G3D/Plane.h"
#include "G3D/Rect2D.h"
#include "G3D/debugAssert.h"
namespace RBX {
using G3D::CoordinateFrame;
using G3D::Array;
using G3D::Vector3;
using G3D::Vector4;
using G3D::Matrix4;
/**
There is a viewport of width x height size in world space that corresponds to
a screenWidth x screenHeight pixel grid on a
renderDevice->getWidth() x renderDevice->getHeight()
window.
All viewport arguments are the pixel bounds of the viewport-- e.g.,
RenderDevice::getViewport().
*/
class RbxCamera {
private:
/**
Vertical field of view (in radians)
*/
float fieldOfView;
/**
The image plane depth corresponding to a vertical field of
view, where the film size is 1x1.
*/
float imagePlaneDepth;
/**
Clipping plane, *not* imaging plane. Positive numbers.
*/
float nearPlane;
/**
Positive
*/
float farPlane;
CoordinateFrame cframe;
public:
class Frustum {
public:
class Face {
public:
/** Counter clockwise indices into vertexPos */
int vertexIndex[4];
/** The plane containing the face. */
Plane plane;
};
/** The vertices, in homogeneous space. If w == 0,
a vertex is at infinity. */
Array<G3D::Vector4> vertexPos;
/** The faces in the frustum. When the
far plane is at infinity, there are 5 faces,
otherwise there are 6. The faces are in the order
N,R,L,B,T,[F].
*/
Array<Face> faceArray;
bool containsPoint(const Vector3& point) const;
bool intersectsSphere(const Vector3& center, float radius) const;
};
RbxCamera();
virtual ~RbxCamera();
CoordinateFrame coordinateFrame() const;
void getCoordinateFrame(CoordinateFrame& c) const;
void setCoordinateFrame(const CoordinateFrame& c);
/**
Sets the horizontal field of view, in radians. The
initial angle is toRadians(55).
<UL>
<LI> toRadians(50) - Telephoto
<LI> toRadians(110) - Normal
<LI> toRadians(140) - Wide angle
</UL>
*/
void setFieldOfView(float angle);
/**
Sets the field of view based on a desired image plane depth
(<I>s'</I>) and film dimensions in world space. Depth must be positive. Width,
depth, and height are measured in the same units (meters are
recommended). The field of view will span the diagonal to the
image.<P> <I>Note</I>: to simulate a 35mm RbxCamera, set width =
0.36 mm and height = 0.24 mm. The width and height used are
generally not the pixel dimensions of the image.
*/
void setImagePlaneDepth(
float depth,
const class G3D::Rect2D& viewport);
inline double getFieldOfView() const {
return fieldOfView;
}
/**
Projects a world space point onto a width x height screen. The
returned coordinate uses pixmap addressing: x = right and y =
down. The resulting z value is <I>rhw</I>.
If the point is behind the camera, Vector3::inf() is returned.
*/
Vector3 project(
const G3D::Vector3& point,
const class G3D::Rect2D& viewport) const;
Vector3 inverseProject(
const Vector3& point,
const G3D::Rect2D& viewport) const;
Matrix4 projectionMatrix(const class G3D::Rect2D& viewport) const;
/**
Returns the pixel area covered by a shape of the given
world space area at the given z value (z must be negative).
*/
float worldToScreenSpaceArea(float area, float z, const class G3D::Rect2D& viewport) const;
/**
Returns the world space 3D viewport corners. These
are at the near clipping plane. The corners are constructed
from the nearPlaneZ, getViewportWidth, and getViewportHeight.
"left" and "right" are from the RbxCamera's perspective.
*/
void get3DViewportCorners(
const class G3D::Rect2D& viewport,
Vector3& outUR,
Vector3& outUL,
Vector3& outLL,
Vector3& outLR) const;
/**
Returns the image plane depth, <I>s'</I>, given the current field
of view for film of dimensions width x height. See
setImagePlaneDepth for a discussion of worldspace values width and height.
*/
float getImagePlaneDepth(
const class G3D::Rect2D& viewport) const;
/**
Returns the world space ray passing through the center of pixel
(x, y) on the image plane. The pixel x and y axes are opposite
the 3D object space axes: (0,0) is the upper left corner of the screen.
They are in viewport coordinates, not screen coordinates.
Integer (x, y) values correspond to
the upper left corners of pixels. If you want to cast rays
through pixel centers, add 0.5 to x and y.
*/
RBX::RbxRay worldRay(
float x,
float y,
const class G3D::Rect2D& viewport) const;
/**
Returns a negative z-value.
*/
inline float nearPlaneZ() const {
return -nearPlane;
}
/**
Returns a negative z-value.
*/
inline float farPlaneZ() const {
return -farPlane;
}
inline void setFarPlaneZ(float z) {
debugAssert(z < 0);
farPlane = -z;
}
inline void setNearPlaneZ(float z) {
debugAssert(z < 0);
nearPlane = -z;
}
/**
Returns the RbxCamera space width of the viewport.
*/
float getViewportWidth(
const class G3D::Rect2D& viewport) const;
/**
Returns the RbxCamera space height of the viewport.
*/
float getViewportHeight(
const class G3D::Rect2D& viewport) const;
/**
Read back a RbxCamera space z-value at pixel (x, y) from the depth buffer.
double getZValue(
double x,
double y,
const class G3D::Rect2D& viewport,
double polygonOffset = 0) const;
*/
void setPosition(const Vector3& t);
void lookAt(const Vector3& position, const Vector3& up = Vector3::unitY());
/**
Returns the clipping planes of the frustum, in world space.
The planes have normals facing <B>into</B> the view frustum.
The plane order is guaranteed to be:
Near, Right, Left, Top, Bottom, [Far]
If the far plane is at infinity, the resulting array will have
5 planes, otherwise there will be 6.
The viewport is used only to determine the aspect ratio of the screen; the
absolute dimensions and xy values don't matter.
*/
void getClipPlanes(
const G3D::Rect2D& viewport,
Array<Plane>& outClip) const;
/**
Returns the world space view frustum, which is a truncated pyramid describing
the volume of space seen by this camera.
*/
void frustum(const G3D::Rect2D& viewport, RbxCamera::Frustum& f) const;
RbxCamera::Frustum frustum(const G3D::Rect2D& viewport) const;
};
} // namespace G3D
#endif
+371
View File
@@ -0,0 +1,371 @@
/**
@file RbxRay.h
RbxRay class
@maintainer Morgan McGuire, matrix@graphics3d.com
@created 2002-07-12
@edited 2006-02-21
// ROBLOX: from the old g3d (previous to upgrade to g3d 8.0). This version make our code happier.
// It doesn't requires to have unit() vectors.
// We should fix this and remove de need of thise file in the future and use the G3D ones.
*/
#ifndef G3D_RbxRay_H
#define G3D_RbxRay_H
#include "G3D/platform.h"
#include "G3D/Vector3.h"
#include "G3D/Triangle.h"
#include "G3D/Sphere.h"
#include "G3D/Box.h"
#include "G3D/AABox.h"
#include "G3D/Plane.h"
namespace RBX {
using G3D::Vector3;
using G3D::Triangle;
using G3D::Plane;
using G3D::Sphere;
using G3D::Box;
using G3D::inf;
using G3D::sign;
using G3D::AABox;
/**
A 3D RbxRay.
*/
class RbxRay {
private:
Vector3 m_origin;
/**
Not unit length
*/
Vector3 m_direction;
public:
RbxRay(const Vector3& origin, const Vector3& direction) {
this->m_origin = origin;
this->m_direction = direction;
}
RbxRay() : m_origin(Vector3::zero()), m_direction(Vector3::zero()) {}
virtual ~RbxRay() {}
bool operator==(const RbxRay& rhs) const {
return m_origin == rhs.origin() && m_direction == rhs.direction();
}
bool operator!=(const RbxRay& other) const {
return m_origin!=other.origin() || m_direction!=other.direction();
}
inline const Vector3& origin() const {
return m_origin;
}
/** Not-Unit direction vector. */
inline const Vector3& direction() const {
return m_direction;
}
inline float length() const {
return m_direction.length();
}
/// Non Cost versions of above, in lieu of exposing private data.
inline Vector3& origin() {
return m_origin;
}
/** Not-Unit direction vector. */
inline Vector3& direction() {
return m_direction;
}
/**
Creates a Ray from a origin and a (nonzero) direction.
*/
static RbxRay fromOriginAndDirection(const Vector3& point, const Vector3& direction) {
return RbxRay(point, direction);
}
RbxRay unit() const {
return RbxRay(m_origin, m_direction.unit());
}
/**
Returns the closest point on the Ray to point.
*/
Vector3 closestPoint(const Vector3& point) const {
float t = m_direction.dot(point - this->m_origin);
if (t < 0) {
return this->m_origin;
} else {
return this->m_origin + m_direction * t;
}
}
/**
Returns the closest distance between point and the Ray
*/
float distance(const Vector3& point) const {
return (closestPoint(point) - point).magnitude();
}
/**
// modified from G3D - returns intersection of Ray/plane regardless of which side ray is on
*/
Vector3 intersectionPlane(const class Plane& plane) const;
/**
Returns the distance until intersection with the (solid) sphere.
Will be 0 if inside the sphere, inf if there is no intersection.
The ray direction is <B>not</B> normalized. If the ray direction
has unit length, the distance from the origin to intersection
is equal to the time. If the direction does not have unit length,
the distance = time * direction.length().
See also the G3D::CollisionDetection "movingPoint" methods,
which give more information about the intersection.
*/
float intersectionTime(const class Sphere& sphere) const;
float intersectionTime(const class Plane& plane) const;
float intersectionTime(const class Box& box) const;
float intersectionTime(const class AABox& box) const;
/**
The three extra arguments are the weights of vertices 0, 1, and 2
at the intersection point; they are useful for texture mapping
and interpolated normals.
*/
float intersectionTime(
const Vector3& v0, const Vector3& v1, const Vector3& v2,
const Vector3& edge01, const Vector3& edge02,
double& w0, double& w1, double& w2) const;
/**
Ray-triangle intersection for a 1-sided triangle. Fastest version.
@cite http://www.acm.org/jgt/papers/MollerTrumbore97/
http://www.graphics.cornell.edu/pubs/1997/MT97.html
*/
inline float intersectionTime(
const Vector3& vert0,
const Vector3& vert1,
const Vector3& vert2,
const Vector3& edge01,
const Vector3& edge02) const;
inline float intersectionTime(
const Vector3& vert0,
const Vector3& vert1,
const Vector3& vert2) const {
return intersectionTime(vert0, vert1, vert2, vert1 - vert0, vert2 - vert0);
}
inline float intersectionTime(
const Vector3& vert0,
const Vector3& vert1,
const Vector3& vert2,
double& w0,
double& w1,
double& w2) const {
return intersectionTime(vert0, vert1, vert2, vert1 - vert0, vert2 - vert0, w0, w1, w2);
}
/* One-sided triangle
*/
inline float intersectionTime(const Triangle& triangle) const {
return intersectionTime(
triangle.vertex(0), triangle.vertex(1), triangle.vertex(2),
triangle.edge01(), triangle.edge02());
}
inline float intersectionTime(
const Triangle& triangle,
double& w0,
double& w1,
double& w2) const {
return intersectionTime(triangle.vertex(0), triangle.vertex(1), triangle.vertex(2),
triangle.edge01(), triangle.edge02(), w0, w1, w2);
}
/** Refracts about the normal
using G3D::Vector3::refractionDirection
and bumps the ray slightly from the newOrigin. */
RbxRay refract(
const Vector3& newOrigin,
const Vector3& normal,
float iInside,
float iOutside) const;
/** Reflects about the normal
using G3D::Vector3::reflectionDirection
and bumps the ray slightly from
the newOrigin. */
RbxRay reflect(
const Vector3& newOrigin,
const Vector3& normal) const;
};
#define EPSILON 0.000001
#define CROSS(dest,v1,v2) \
dest[0]=v1[1]*v2[2]-v1[2]*v2[1]; \
dest[1]=v1[2]*v2[0]-v1[0]*v2[2]; \
dest[2]=v1[0]*v2[1]-v1[1]*v2[0];
#define DOT(v1,v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2])
#define SUB(dest,v1,v2) \
dest[0]=v1[0]-v2[0]; \
dest[1]=v1[1]-v2[1]; \
dest[2]=v1[2]-v2[2];
inline float RbxRay::intersectionTime(
const Vector3& vert0,
const Vector3& vert1,
const Vector3& vert2,
const Vector3& edge1,
const Vector3& edge2) const {
(void)vert1;
(void)vert2;
// Barycenteric coords
float u, v;
float tvec[3], pvec[3], qvec[3];
// begin calculating determinant - also used to calculate U parameter
CROSS(pvec, m_direction, edge2);
// if determinant is near zero, ray lies in plane of triangle
const float det = DOT(edge1, pvec);
if (det < EPSILON) {
return (float)inf();
}
// calculate distance from vert0 to ray origin
SUB(tvec, m_origin, vert0);
// calculate U parameter and test bounds
u = DOT(tvec, pvec);
if ((u < 0.0f) || (u > det)) {
// Hit the plane outside the triangle
return (float)inf();
}
// prepare to test V parameter
CROSS(qvec, tvec, edge1);
// calculate V parameter and test bounds
v = DOT(m_direction, qvec);
if ((v < 0.0f) || (u + v > det)) {
// Hit the plane outside the triangle
return (float)inf();
}
// Case where we don't need correct (u, v):
const float t = DOT(edge2, qvec);
if (t >= 0.0f) {
// Note that det must be positive
return t / det;
} else {
// We had to travel backwards in time to intersect
return (float)inf();
}
}
inline float RbxRay::intersectionTime(
const Vector3& vert0,
const Vector3& vert1,
const Vector3& vert2,
const Vector3& edge1,
const Vector3& edge2,
double& w0,
double& w1,
double& w2) const {
(void)vert1;
(void)vert2;
// Barycenteric coords
float u, v;
float tvec[3], pvec[3], qvec[3];
// begin calculating determinant - also used to calculate U parameter
CROSS(pvec, m_direction, edge2);
// if determinant is near zero, ray lies in plane of triangle
const float det = DOT(edge1, pvec);
if (det < EPSILON) {
return (float)inf();
}
// calculate distance from vert0 to ray origin
SUB(tvec, m_origin, vert0);
// calculate U parameter and test bounds
u = DOT(tvec, pvec);
if ((u < 0.0f) || (u > det)) {
// Hit the plane outside the triangle
return (float)inf();
}
// prepare to test V parameter
CROSS(qvec, tvec, edge1);
// calculate V parameter and test bounds
v = DOT(m_direction, qvec);
if ((v < 0.0f) || (u + v > det)) {
// Hit the plane outside the triangle
return (float)inf();
}
float t = DOT(edge2, qvec);
if (t >= 0) {
const float inv_det = 1.0f / det;
t *= inv_det;
u *= inv_det;
v *= inv_det;
w0 = (1.0f - u - v);
w1 = u;
w2 = v;
return t;
} else {
// We had to travel backwards in time to intersect
return (float)inf();
}
}
#undef EPSILON
#undef CROSS
#undef DOT
#undef SUB
}// namespace
#endif
+17
View File
@@ -0,0 +1,17 @@
#ifndef RBX_TIME_H
#define RBX_TIME_H
#include "G3D/G3DGameUnits.h"
namespace RBX
{
class RbxTime
{
public:
static G3D::RealTime getTick();
private:
static G3D::RealTime m_startTime;
};
}
#endif