From ebeacf571a2a37065490632b1664b979c5b6069c Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Fri, 26 Dec 2025 16:04:11 -0500 Subject: [PATCH 01/28] some work on camera --- Client/App/App.vcproj | 8 + Client/App/include/v8datamodel/Camera.h | 115 +++++++++++++ Client/App/v8datamodel/Camera.cpp | 215 ++++++++++++++++++++++++ 3 files changed, 338 insertions(+) create mode 100644 Client/App/include/v8datamodel/Camera.h create mode 100644 Client/App/v8datamodel/Camera.cpp diff --git a/Client/App/App.vcproj b/Client/App/App.vcproj index 3aa2dbcc..d82428b9 100644 --- a/Client/App/App.vcproj +++ b/Client/App/App.vcproj @@ -781,6 +781,10 @@ RelativePath=".\include\v8datamodel\BrickColor.h" > + + @@ -1166,6 +1170,10 @@ RelativePath=".\v8datamodel\BrickColor.cpp" > + + diff --git a/Client/App/include/v8datamodel/Camera.h b/Client/App/include/v8datamodel/Camera.h new file mode 100644 index 00000000..14679832 --- /dev/null +++ b/Client/App/include/v8datamodel/Camera.h @@ -0,0 +1,115 @@ +#pragma once +#include +#include "reflection/reflection.h" +#include "v8tree/Instance.h" +#include "v8world/ContactManager.h" +#include "util/Extents.h" + +namespace RBX +{ + extern const char* sCamera; + + class ICameraOwner; + class ICameraSubject; + class Camera : public RBX::DescribedCreatable + { + public: + enum CameraType + { + FIXED_CAMERA = 0, + ATTACH_CAMERA = 1, + WATCH_CAMERA = 2, + TRACK_CAMERA = 3, + FOLLOW_CAMERA = 4, + CUSTOM_CAMERA = 5, + NUM_CAMERA_TYPE = 6, + }; + enum AnimationType + { + ALWAYS = 0, + AUTO = 1, + }; + enum ZoomType + { + ZOOM_IN_OR_OUT = 0, + ZOOM_OUT_ONLY = 1, + ZOOM_CHAR_PART_DRAG = 2, + }; + private: + G3D::GCamera gCamera; + G3D::CoordinateFrame cameraGoal; + G3D::CoordinateFrame cameraFocus; + RBX::Camera::CameraType cameraType; + RBX::Camera::AnimationType animationType; + boost::shared_ptr cameraSubject; + bool cameraExternallyAdjusted; + private: + RBX::ICameraOwner* getCameraOwner(); + void updateFocus(); + void updateGoal(); + bool characterZoom(float); + bool nonCharacterZoom(float); + void tryZoomExtents(float, float, float, const RBX::Extents&, const G3D::Rect2D&); + RBX::ContactManager& getContactManager(); + float goalToFocusDistance() const; + void setGCameraCoordinateFrame(const G3D::CoordinateFrame&); + G3D::CoordinateFrame computeLineOfSiteGoal(); + void getHeadingElevationDistance(float &heading, float &elevation, float &distance); + void setHeadingElevationDistance(float, float, float); + void tellCameraMoved(); + void getIgnorePrims(G3D::Array&); + virtual bool askSetParent(const RBX::Instance*) const; + + public: + //Camera(const RBX::Camera&); + Camera(); + virtual ~Camera(); + public: + const G3D::GCamera& getGCamera() const + { + return gCamera; + } + void onHeartbeat(); + void autoMode(); + void alwaysMode(); + bool isCharacterCamera() const; + bool isFirstPersonCamera() const; + RBX::ICameraSubject* getCameraSubject() const; + RBX::Instance* getCameraSubjectInstance() const; + void setCameraSubject(RBX::Instance*); + const G3D::CoordinateFrame& getCameraFocus() const; + void setCameraFocus(const G3D::CoordinateFrame&); + G3D::CoordinateFrame getCameraCoordinateFrame() const; + void setCameraCoordinateFrameNoLerp(const G3D::CoordinateFrame&); + void goalToCamera(); + RBX::Camera::CameraType getCameraType() const; + void setCameraType(RBX::Camera::CameraType); + bool canZoom(int) const; + bool canTilt(int) const; + void onWrapMouse(const G3D::Vector2&); + bool zoom(float); + bool setDistanceFromTarget(float); + void zoomExtents(RBX::Extents, const G3D::Rect2D&, RBX::Camera::ZoomType); + bool zoomExtents(const G3D::Rect2D&); + void panRadians(float); + void panUnits(int); + bool tiltRadians(float); + bool tiltUnits(int); + void lookAt(const G3D::Vector3&); + void setImageServerViewNoLerp(const G3D::CoordinateFrame&, const G3D::Rect2D&); + //RBX::Camera& operator=(const RBX::Camera&); + + public: + static float distanceDefault(); + static float distanceMin(); + static float distanceMax(); + static float distanceMaxCharacter(); + static float distanceMinOcclude(); + static float getNewZoomDistance(float, float); + + static const Reflection::PropDescriptor desc_cameraType; + static const Reflection::PropDescriptor desc_CoordFrame; + static const Reflection::PropDescriptor desc_Focus; + static const Reflection::PropDescriptor cameraSubjectProp; + }; +} \ No newline at end of file diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp new file mode 100644 index 00000000..68c29521 --- /dev/null +++ b/Client/App/v8datamodel/Camera.cpp @@ -0,0 +1,215 @@ +#include "v8datamodel/Camera.h" +#include "v8datamodel/Workspace.h" +#include "util/Math.h" +#include "util/Debug.h" + +namespace RBX +{ + const char* sCamera = "Camera"; + + const G3D::CoordinateFrame& Camera::getCameraFocus() const + { + return cameraFocus; + } + + G3D::CoordinateFrame Camera::getCameraCoordinateFrame() const + { + return gCamera.getCoordinateFrame(); + } + + bool Camera::askSetParent(const RBX::Instance *instance) const + { + return fastDynamicCast(instance) != NULL; + } + + ICameraOwner* Camera::getCameraOwner() + { + Instance* instance = getParent(); + while(instance != NULL) + { + RBX::ICameraOwner* cameraOwner = fastDynamicCast(instance); + if(cameraOwner) + return cameraOwner; + + instance = getParent(); + } + + return NULL; + } + + void Camera::lookAt(const G3D::Vector3 &point) + { + cameraFocus.translation = point; + cameraGoal.lookAt(point); + } + + void Camera::getHeadingElevationDistance(float &heading, float &elevation, float &distance) + { + Math::getHeadingElevation(cameraGoal, heading, elevation); + distance = (cameraGoal.translation - cameraFocus.translation).magnitude(); + } + + void Camera::alwaysMode() + { + animationType = ALWAYS; + } + + bool Camera::nonCharacterZoom(float in) + { + G3D::Vector3 lookVector = cameraFocus.translation - cameraGoal.translation; + + float currentDistance = lookVector.magnitude(); + float newZoomDistance = getNewZoomDistance(currentDistance, in); + + if(currentDistance == newZoomDistance) + return false; + + cameraGoal.translation -= lookVector * (newZoomDistance / currentDistance - 1.0F); + + ICameraOwner *owner = getCameraOwner(); + if(owner) + owner->cameraMoved(); + + return true; + } + + void Camera::panRadians(float angle) + { + float heading; + float elevation; + float distance; + + RBXASSERT(angle > -100); + RBXASSERT(angle < 100); + + if(angle != 0) + { + getHeadingElevationDistance(heading, elevation, distance); + heading = Math::radWrap(heading + angle); + setHeadingElevationDistance(heading, elevation, distance); + + ICameraOwner *owner = getCameraOwner(); + if(owner) + owner->cameraMoved(); + } + } + + void Camera::updateFocus() + { + ICameraSubject* cameraSubject = getCameraSubject(); + cameraFocus = cameraSubject->getLocation(); + } + + bool Camera::zoom(float in) + { + if(cameraType == CUSTOM_CAMERA) + { + ICameraSubject* cameraSubject = getCameraSubject(); + if(cameraSubject) + return cameraSubject->zoom(in, cameraGoal, cameraFocus); + } + else if(getCameraSubjectInstance() && (cameraType == FOLLOW_CAMERA || cameraType == ATTACH_CAMERA || cameraType == TRACK_CAMERA)) + { + return characterZoom(in); + } + else + { + return nonCharacterZoom(in); + } + + return false; + } + + Instance* Camera::getCameraSubjectInstance() const + { + return cameraSubject.get(); + } + + ICameraSubject* Camera::getCameraSubject() const + { + Instance* instance = getCameraSubjectInstance(); + if(instance) + { + ICameraSubject* subject = fastDynamicCast(instance); + RBXASSERT(subject != NULL); + return subject; + } + return NULL; + } + + void Camera::autoMode() + { + if(animationType != AUTO) + { + animationType = AUTO; + + ICameraOwner *owner = getCameraOwner(); + if(owner) + owner->cameraMoved(); + } + } + + void Camera::setCameraType(CameraType type) + { + if(cameraType != type) + { + cameraType = type; + raisePropertyChanged(desc_cameraType); + + ICameraOwner *owner = getCameraOwner(); + if(owner) + owner->cameraMoved(); + } + } + + void Camera::setCameraFocus(const G3D::CoordinateFrame &value) + { + if(value != cameraFocus) + { + cameraFocus = value; + raisePropertyChanged(desc_Focus); + + ICameraOwner *owner = getCameraOwner(); + if(owner) + owner->cameraMoved(); + } + } + + void Camera::goalToCamera() + { + if(gCamera.getCoordinateFrame() != cameraGoal) + { + cameraExternallyAdjusted = true; + + #if defined(_DEBUG) || defined(_RELEASEASSERT) + if(Math::legalCameraCoord(cameraGoal)) + gCamera.setCoordinateFrame(cameraGoal); + else if(Debugable::assertAction == CrashOnAssert) + Debugable::doCrash(); + #endif + + raisePropertyChanged(desc_CoordFrame); + + ICameraOwner *owner = getCameraOwner(); + if(owner) + owner->cameraMoved(); + } + } + + bool Camera::zoomExtents(const G3D::Rect2D &viewPort) + { + ICameraOwner *owner = getCameraOwner(); + if(owner) + { + zoomExtents(owner->computeCameraOwnerExtents(), viewPort, ZOOM_IN_OR_OUT); + return true; + } + return false; + } + + void Camera::setCameraCoordinateFrameNoLerp(const G3D::CoordinateFrame &value) + { + cameraGoal = value; + goalToCamera(); + } +} \ No newline at end of file From 888a4a323c679e0f135fa8a27b0ded658c270e6c Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Fri, 26 Dec 2025 16:18:53 -0500 Subject: [PATCH 02/28] headers --- Client/App/include/v8datamodel/Camera.h | 42 ++++++++++++------------- Client/App/v8datamodel/Camera.cpp | 9 ++++-- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/Client/App/include/v8datamodel/Camera.h b/Client/App/include/v8datamodel/Camera.h index 14679832..06ae47b7 100644 --- a/Client/App/include/v8datamodel/Camera.h +++ b/Client/App/include/v8datamodel/Camera.h @@ -11,7 +11,7 @@ namespace RBX class ICameraOwner; class ICameraSubject; - class Camera : public RBX::DescribedCreatable + class Camera : public DescribedCreatable { public: enum CameraType @@ -39,26 +39,26 @@ namespace RBX G3D::GCamera gCamera; G3D::CoordinateFrame cameraGoal; G3D::CoordinateFrame cameraFocus; - RBX::Camera::CameraType cameraType; - RBX::Camera::AnimationType animationType; - boost::shared_ptr cameraSubject; + CameraType cameraType; + AnimationType animationType; + boost::shared_ptr cameraSubject; bool cameraExternallyAdjusted; private: - RBX::ICameraOwner* getCameraOwner(); + ICameraOwner* getCameraOwner(); void updateFocus(); void updateGoal(); bool characterZoom(float); - bool nonCharacterZoom(float); - void tryZoomExtents(float, float, float, const RBX::Extents&, const G3D::Rect2D&); - RBX::ContactManager& getContactManager(); + bool nonCharacterZoom(float in); + void tryZoomExtents(float, float, float, const Extents&, const G3D::Rect2D&); + ContactManager& getContactManager(); float goalToFocusDistance() const; void setGCameraCoordinateFrame(const G3D::CoordinateFrame&); G3D::CoordinateFrame computeLineOfSiteGoal(); void getHeadingElevationDistance(float &heading, float &elevation, float &distance); void setHeadingElevationDistance(float, float, float); void tellCameraMoved(); - void getIgnorePrims(G3D::Array&); - virtual bool askSetParent(const RBX::Instance*) const; + void getIgnorePrims(G3D::Array&); + virtual bool askSetParent(const Instance *instance) const; public: //Camera(const RBX::Camera&); @@ -74,28 +74,28 @@ namespace RBX void alwaysMode(); bool isCharacterCamera() const; bool isFirstPersonCamera() const; - RBX::ICameraSubject* getCameraSubject() const; - RBX::Instance* getCameraSubjectInstance() const; - void setCameraSubject(RBX::Instance*); + ICameraSubject* getCameraSubject() const; + Instance* getCameraSubjectInstance() const; + void setCameraSubject(Instance*); const G3D::CoordinateFrame& getCameraFocus() const; - void setCameraFocus(const G3D::CoordinateFrame&); + void setCameraFocus(const G3D::CoordinateFrame &value); G3D::CoordinateFrame getCameraCoordinateFrame() const; void setCameraCoordinateFrameNoLerp(const G3D::CoordinateFrame&); void goalToCamera(); - RBX::Camera::CameraType getCameraType() const; - void setCameraType(RBX::Camera::CameraType); + CameraType getCameraType() const; + void setCameraType(CameraType type); bool canZoom(int) const; bool canTilt(int) const; void onWrapMouse(const G3D::Vector2&); - bool zoom(float); + bool zoom(float in); bool setDistanceFromTarget(float); - void zoomExtents(RBX::Extents, const G3D::Rect2D&, RBX::Camera::ZoomType); - bool zoomExtents(const G3D::Rect2D&); - void panRadians(float); + void zoomExtents(Extents, const G3D::Rect2D&, ZoomType); + bool zoomExtents(const G3D::Rect2D &viewPort); + void panRadians(float angle); void panUnits(int); bool tiltRadians(float); bool tiltUnits(int); - void lookAt(const G3D::Vector3&); + void lookAt(const G3D::Vector3 &point); void setImageServerViewNoLerp(const G3D::CoordinateFrame&, const G3D::Rect2D&); //RBX::Camera& operator=(const RBX::Camera&); diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp index 68c29521..696125b9 100644 --- a/Client/App/v8datamodel/Camera.cpp +++ b/Client/App/v8datamodel/Camera.cpp @@ -17,7 +17,7 @@ namespace RBX return gCamera.getCoordinateFrame(); } - bool Camera::askSetParent(const RBX::Instance *instance) const + bool Camera::askSetParent(const Instance *instance) const { return fastDynamicCast(instance) != NULL; } @@ -27,7 +27,7 @@ namespace RBX Instance* instance = getParent(); while(instance != NULL) { - RBX::ICameraOwner* cameraOwner = fastDynamicCast(instance); + ICameraOwner* cameraOwner = fastDynamicCast(instance); if(cameraOwner) return cameraOwner; @@ -108,7 +108,10 @@ namespace RBX if(cameraSubject) return cameraSubject->zoom(in, cameraGoal, cameraFocus); } - else if(getCameraSubjectInstance() && (cameraType == FOLLOW_CAMERA || cameraType == ATTACH_CAMERA || cameraType == TRACK_CAMERA)) + else if(getCameraSubjectInstance() && + (cameraType == FOLLOW_CAMERA || + cameraType == ATTACH_CAMERA || + cameraType == TRACK_CAMERA)) { return characterZoom(in); } From b030d0f129c21bdaddcf121cfaece37244869244 Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Fri, 26 Dec 2025 16:25:18 -0500 Subject: [PATCH 03/28] moved some functions to header --- Client/App/include/v8datamodel/Camera.h | 8 +++++++- Client/App/v8datamodel/Camera.cpp | 10 ---------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/Client/App/include/v8datamodel/Camera.h b/Client/App/include/v8datamodel/Camera.h index 06ae47b7..9598e9f2 100644 --- a/Client/App/include/v8datamodel/Camera.h +++ b/Client/App/include/v8datamodel/Camera.h @@ -78,8 +78,14 @@ namespace RBX Instance* getCameraSubjectInstance() const; void setCameraSubject(Instance*); const G3D::CoordinateFrame& getCameraFocus() const; + { + return cameraFocus; + } void setCameraFocus(const G3D::CoordinateFrame &value); - G3D::CoordinateFrame getCameraCoordinateFrame() const; + G3D::CoordinateFrame getCameraCoordinateFrame() const + { + return gCamera.getCoordinateFrame(); + } void setCameraCoordinateFrameNoLerp(const G3D::CoordinateFrame&); void goalToCamera(); CameraType getCameraType() const; diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp index 696125b9..c1e9e75f 100644 --- a/Client/App/v8datamodel/Camera.cpp +++ b/Client/App/v8datamodel/Camera.cpp @@ -7,16 +7,6 @@ namespace RBX { const char* sCamera = "Camera"; - const G3D::CoordinateFrame& Camera::getCameraFocus() const - { - return cameraFocus; - } - - G3D::CoordinateFrame Camera::getCameraCoordinateFrame() const - { - return gCamera.getCoordinateFrame(); - } - bool Camera::askSetParent(const Instance *instance) const { return fastDynamicCast(instance) != NULL; From 4c121ae24238234c7077711ac322d71668aa9b17 Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Fri, 26 Dec 2025 16:32:45 -0500 Subject: [PATCH 04/28] alright --- Client/App/include/v8datamodel/Camera.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Client/App/include/v8datamodel/Camera.h b/Client/App/include/v8datamodel/Camera.h index 9598e9f2..e167eb00 100644 --- a/Client/App/include/v8datamodel/Camera.h +++ b/Client/App/include/v8datamodel/Camera.h @@ -77,7 +77,7 @@ namespace RBX ICameraSubject* getCameraSubject() const; Instance* getCameraSubjectInstance() const; void setCameraSubject(Instance*); - const G3D::CoordinateFrame& getCameraFocus() const; + const G3D::CoordinateFrame& getCameraFocus() const { return cameraFocus; } From 79b58f0d2e88158d3b1c775db5e1d44bc30b0c8e Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Fri, 26 Dec 2025 16:34:47 -0500 Subject: [PATCH 05/28] Update Camera.h --- Client/App/include/v8datamodel/Camera.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Client/App/include/v8datamodel/Camera.h b/Client/App/include/v8datamodel/Camera.h index e167eb00..1a9b2446 100644 --- a/Client/App/include/v8datamodel/Camera.h +++ b/Client/App/include/v8datamodel/Camera.h @@ -113,7 +113,7 @@ namespace RBX static float distanceMinOcclude(); static float getNewZoomDistance(float, float); - static const Reflection::PropDescriptor desc_cameraType; + static const Reflection::EnumPropDescriptor desc_cameraType; static const Reflection::PropDescriptor desc_CoordFrame; static const Reflection::PropDescriptor desc_Focus; static const Reflection::PropDescriptor cameraSubjectProp; From 110862f4eb8057a137a04b46312d82baa15c107d Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Fri, 26 Dec 2025 17:10:19 -0500 Subject: [PATCH 06/28] first time with doing reflections --- Client/App/include/v8datamodel/Camera.h | 2 +- Client/App/v8datamodel/Camera.cpp | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Client/App/include/v8datamodel/Camera.h b/Client/App/include/v8datamodel/Camera.h index 1a9b2446..8a129ce0 100644 --- a/Client/App/include/v8datamodel/Camera.h +++ b/Client/App/include/v8datamodel/Camera.h @@ -116,6 +116,6 @@ namespace RBX static const Reflection::EnumPropDescriptor desc_cameraType; static const Reflection::PropDescriptor desc_CoordFrame; static const Reflection::PropDescriptor desc_Focus; - static const Reflection::PropDescriptor cameraSubjectProp; + static const Reflection::RefPropDescriptor cameraSubjectProp; }; } \ No newline at end of file diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp index c1e9e75f..c5da47ba 100644 --- a/Client/App/v8datamodel/Camera.cpp +++ b/Client/App/v8datamodel/Camera.cpp @@ -7,6 +7,11 @@ namespace RBX { const char* sCamera = "Camera"; + static const Reflection::EnumPropDescriptor desc_cameraType("CameraType", "Camera", &Camera::getCameraType, &Camera::setCameraType, Reflection::PropertyDescriptor::STANDARD); + static const Reflection::PropDescriptor desc_CoordFrame("CoordinateFrame", "Data", &Camera::getCameraCoordinateFrame, &Camera::setCameraCoordinateFrameNoLerp, Reflection::PropertyDescriptor::STREAMING); + static const Reflection::PropDescriptor desc_Focus("Focus", "Data", &Camera::getCameraFocus, &Camera::setCameraFocus, Reflection::PropertyDescriptor::STREAMING); + static const Reflection::RefPropDescriptor cameraSubjectProp("CameraSubject", "Camera", &Camera::getCameraSubjectInstance, &Camera::setCameraSubject, Reflection::PropertyDescriptor::STANDARD); + bool Camera::askSetParent(const Instance *instance) const { return fastDynamicCast(instance) != NULL; From 5e27d869332007a0562bacbb62e6418bcc5acfaf Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Fri, 26 Dec 2025 19:15:15 -0500 Subject: [PATCH 07/28] the removal of descriptors in the header --- Client/App/include/v8datamodel/Camera.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Client/App/include/v8datamodel/Camera.h b/Client/App/include/v8datamodel/Camera.h index 8a129ce0..5a21abc6 100644 --- a/Client/App/include/v8datamodel/Camera.h +++ b/Client/App/include/v8datamodel/Camera.h @@ -112,10 +112,5 @@ namespace RBX static float distanceMaxCharacter(); static float distanceMinOcclude(); static float getNewZoomDistance(float, float); - - static const Reflection::EnumPropDescriptor desc_cameraType; - static const Reflection::PropDescriptor desc_CoordFrame; - static const Reflection::PropDescriptor desc_Focus; - static const Reflection::RefPropDescriptor cameraSubjectProp; }; } \ No newline at end of file From ea2c7ba5d7c1fd73a382976784d46b99133d5564 Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Fri, 26 Dec 2025 19:18:34 -0500 Subject: [PATCH 08/28] changed assertion to be less lazy --- Client/App/v8datamodel/Camera.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp index c5da47ba..e3c16c89 100644 --- a/Client/App/v8datamodel/Camera.cpp +++ b/Client/App/v8datamodel/Camera.cpp @@ -1,7 +1,6 @@ #include "v8datamodel/Camera.h" #include "v8datamodel/Workspace.h" #include "util/Math.h" -#include "util/Debug.h" namespace RBX { @@ -178,14 +177,14 @@ namespace RBX if(gCamera.getCoordinateFrame() != cameraGoal) { cameraExternallyAdjusted = true; - - #if defined(_DEBUG) || defined(_RELEASEASSERT) - if(Math::legalCameraCoord(cameraGoal)) + if (Math::legalCameraCoord(cameraGoal)) + { gCamera.setCoordinateFrame(cameraGoal); - else if(Debugable::assertAction == CrashOnAssert) - Debugable::doCrash(); - #endif - + } + else + { + RBXASSERT(0); + } raisePropertyChanged(desc_CoordFrame); ICameraOwner *owner = getCameraOwner(); From 5fd20b66f9920933aa44644a427aa73e4b77ed8b Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Fri, 26 Dec 2025 19:21:00 -0500 Subject: [PATCH 09/28] styling! --- Client/App/v8datamodel/Camera.cpp | 38 +++++++++++++++---------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp index e3c16c89..8ecc7ddd 100644 --- a/Client/App/v8datamodel/Camera.cpp +++ b/Client/App/v8datamodel/Camera.cpp @@ -19,10 +19,10 @@ namespace RBX ICameraOwner* Camera::getCameraOwner() { Instance* instance = getParent(); - while(instance != NULL) + while (instance != NULL) { ICameraOwner* cameraOwner = fastDynamicCast(instance); - if(cameraOwner) + if (cameraOwner) return cameraOwner; instance = getParent(); @@ -55,13 +55,13 @@ namespace RBX float currentDistance = lookVector.magnitude(); float newZoomDistance = getNewZoomDistance(currentDistance, in); - if(currentDistance == newZoomDistance) + if (currentDistance == newZoomDistance) return false; cameraGoal.translation -= lookVector * (newZoomDistance / currentDistance - 1.0F); ICameraOwner *owner = getCameraOwner(); - if(owner) + if (owner) owner->cameraMoved(); return true; @@ -76,14 +76,14 @@ namespace RBX RBXASSERT(angle > -100); RBXASSERT(angle < 100); - if(angle != 0) + if (angle != 0) { getHeadingElevationDistance(heading, elevation, distance); heading = Math::radWrap(heading + angle); setHeadingElevationDistance(heading, elevation, distance); ICameraOwner *owner = getCameraOwner(); - if(owner) + if (owner) owner->cameraMoved(); } } @@ -96,13 +96,13 @@ namespace RBX bool Camera::zoom(float in) { - if(cameraType == CUSTOM_CAMERA) + if (cameraType == CUSTOM_CAMERA) { ICameraSubject* cameraSubject = getCameraSubject(); - if(cameraSubject) + if (cameraSubject) return cameraSubject->zoom(in, cameraGoal, cameraFocus); } - else if(getCameraSubjectInstance() && + else if (getCameraSubjectInstance() && (cameraType == FOLLOW_CAMERA || cameraType == ATTACH_CAMERA || cameraType == TRACK_CAMERA)) @@ -125,7 +125,7 @@ namespace RBX ICameraSubject* Camera::getCameraSubject() const { Instance* instance = getCameraSubjectInstance(); - if(instance) + if (instance) { ICameraSubject* subject = fastDynamicCast(instance); RBXASSERT(subject != NULL); @@ -136,45 +136,45 @@ namespace RBX void Camera::autoMode() { - if(animationType != AUTO) + if (animationType != AUTO) { animationType = AUTO; ICameraOwner *owner = getCameraOwner(); - if(owner) + if (owner) owner->cameraMoved(); } } void Camera::setCameraType(CameraType type) { - if(cameraType != type) + if (cameraType != type) { cameraType = type; raisePropertyChanged(desc_cameraType); ICameraOwner *owner = getCameraOwner(); - if(owner) + if (owner) owner->cameraMoved(); } } void Camera::setCameraFocus(const G3D::CoordinateFrame &value) { - if(value != cameraFocus) + if (value != cameraFocus) { cameraFocus = value; raisePropertyChanged(desc_Focus); ICameraOwner *owner = getCameraOwner(); - if(owner) + if (owner) owner->cameraMoved(); } } void Camera::goalToCamera() { - if(gCamera.getCoordinateFrame() != cameraGoal) + if (gCamera.getCoordinateFrame() != cameraGoal) { cameraExternallyAdjusted = true; if (Math::legalCameraCoord(cameraGoal)) @@ -188,7 +188,7 @@ namespace RBX raisePropertyChanged(desc_CoordFrame); ICameraOwner *owner = getCameraOwner(); - if(owner) + if (owner) owner->cameraMoved(); } } @@ -196,7 +196,7 @@ namespace RBX bool Camera::zoomExtents(const G3D::Rect2D &viewPort) { ICameraOwner *owner = getCameraOwner(); - if(owner) + if (owner) { zoomExtents(owner->computeCameraOwnerExtents(), viewPort, ZOOM_IN_OR_OUT); return true; From 77eb8ab2df02b1555afcbc30355aa48dba88600e Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Fri, 26 Dec 2025 19:25:49 -0500 Subject: [PATCH 10/28] moved vars into if block less ugly --- Client/App/v8datamodel/Camera.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp index 8ecc7ddd..da40dd37 100644 --- a/Client/App/v8datamodel/Camera.cpp +++ b/Client/App/v8datamodel/Camera.cpp @@ -69,15 +69,13 @@ namespace RBX void Camera::panRadians(float angle) { - float heading; - float elevation; - float distance; - RBXASSERT(angle > -100); RBXASSERT(angle < 100); if (angle != 0) { + float heading, elevation, distance; + getHeadingElevationDistance(heading, elevation, distance); heading = Math::radWrap(heading + angle); setHeadingElevationDistance(heading, elevation, distance); From e88d1319ff2f51f62fbd68c5dde47255da2b7637 Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Fri, 26 Dec 2025 19:32:55 -0500 Subject: [PATCH 11/28] lowercased and made code less ugly --- Client/App/v8datamodel/Camera.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp index da40dd37..029ac27a 100644 --- a/Client/App/v8datamodel/Camera.cpp +++ b/Client/App/v8datamodel/Camera.cpp @@ -58,7 +58,7 @@ namespace RBX if (currentDistance == newZoomDistance) return false; - cameraGoal.translation -= lookVector * (newZoomDistance / currentDistance - 1.0F); + cameraGoal.translation -= lookVector * (newZoomDistance / currentDistance - 1.0f); ICameraOwner *owner = getCameraOwner(); if (owner) @@ -101,9 +101,9 @@ namespace RBX return cameraSubject->zoom(in, cameraGoal, cameraFocus); } else if (getCameraSubjectInstance() && - (cameraType == FOLLOW_CAMERA || - cameraType == ATTACH_CAMERA || - cameraType == TRACK_CAMERA)) + (cameraType == FOLLOW_CAMERA || + cameraType == ATTACH_CAMERA || + cameraType == TRACK_CAMERA)) { return characterZoom(in); } From 2e8e8e7ac82fddeb15247b917c0cbd961d5b36f3 Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Sat, 27 Dec 2025 16:37:57 -0500 Subject: [PATCH 12/28] removed something unnecessary --- Client/App/v8datamodel/Camera.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp index 029ac27a..c7664a52 100644 --- a/Client/App/v8datamodel/Camera.cpp +++ b/Client/App/v8datamodel/Camera.cpp @@ -126,7 +126,7 @@ namespace RBX if (instance) { ICameraSubject* subject = fastDynamicCast(instance); - RBXASSERT(subject != NULL); + RBXASSERT(subject); return subject; } return NULL; From 97ff24cc0fcf41321fcf5ff03a335f3dbafb417b Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Sun, 28 Dec 2025 14:51:25 -0500 Subject: [PATCH 13/28] Camera::Camera() --- Client/App/v8datamodel/Camera.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp index c7664a52..0e460390 100644 --- a/Client/App/v8datamodel/Camera.cpp +++ b/Client/App/v8datamodel/Camera.cpp @@ -11,6 +11,31 @@ namespace RBX static const Reflection::PropDescriptor desc_Focus("Focus", "Data", &Camera::getCameraFocus, &Camera::setCameraFocus, Reflection::PropertyDescriptor::STREAMING); static const Reflection::RefPropDescriptor cameraSubjectProp("CameraSubject", "Camera", &Camera::getCameraSubjectInstance, &Camera::setCameraSubject, Reflection::PropertyDescriptor::STANDARD); + Camera::Camera() + : Base(), + cameraFocus(G3D::Vector3(0, 0, -5)), + cameraType(FIXED_CAMERA), + animationType(AUTO), + cameraExternallyAdjusted(false) + { + setName("Camera"); + gCamera.setNearPlaneZ(1.25); + gCamera.setFarPlaneZ(5000); + gCamera.setFieldOfView(G3D::toRadians(60)); + + G3D::CoordinateFrame cameraCoord(G3D::Vector3(0, 5, 5)); + cameraCoord.lookAt(G3D::Vector3::zero()); + + if (Math::legalCameraCoord(cameraCoord)) + { + gCamera.setCoordinateFrame(cameraCoord); + } + else + { + RBXASSERT(0); + } + } + bool Camera::askSetParent(const Instance *instance) const { return fastDynamicCast(instance) != NULL; From 8f80071391e0c002e47f05d28d293d9e9785973b Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Sun, 28 Dec 2025 15:49:09 -0500 Subject: [PATCH 14/28] Camera::setCameraSubject --- Client/App/v8datamodel/Camera.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp index 0e460390..014a1a9c 100644 --- a/Client/App/v8datamodel/Camera.cpp +++ b/Client/App/v8datamodel/Camera.cpp @@ -182,6 +182,22 @@ namespace RBX } } + void Camera::setCameraSubject(Instance *newSubject) + { + if (newSubject != getCameraSubjectInstance()) + { + if (fastDynamicCast(newSubject)) + { + cameraSubject = shared_from((ModelInstance*) newSubject); + raisePropertyChanged(cameraSubjectProp); + + ICameraOwner *owner = getCameraOwner(); + if (owner) + owner->cameraMoved(); + } + } + } + void Camera::setCameraFocus(const G3D::CoordinateFrame &value) { if (value != cameraFocus) From 2796b6511f8270392e069c37f6f62249de36f2cd Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Sun, 28 Dec 2025 15:54:41 -0500 Subject: [PATCH 15/28] more styling --- Client/App/v8datamodel/Camera.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp index 014a1a9c..d389c0f9 100644 --- a/Client/App/v8datamodel/Camera.cpp +++ b/Client/App/v8datamodel/Camera.cpp @@ -36,7 +36,7 @@ namespace RBX } } - bool Camera::askSetParent(const Instance *instance) const + bool Camera::askSetParent(const Instance* instance) const { return fastDynamicCast(instance) != NULL; } @@ -56,13 +56,13 @@ namespace RBX return NULL; } - void Camera::lookAt(const G3D::Vector3 &point) + void Camera::lookAt(const G3D::Vector3& point) { cameraFocus.translation = point; cameraGoal.lookAt(point); } - void Camera::getHeadingElevationDistance(float &heading, float &elevation, float &distance) + void Camera::getHeadingElevationDistance(float& heading, float& elevation, float& distance) { Math::getHeadingElevation(cameraGoal, heading, elevation); distance = (cameraGoal.translation - cameraFocus.translation).magnitude(); @@ -163,7 +163,7 @@ namespace RBX { animationType = AUTO; - ICameraOwner *owner = getCameraOwner(); + ICameraOwner* owner = getCameraOwner(); if (owner) owner->cameraMoved(); } @@ -176,7 +176,7 @@ namespace RBX cameraType = type; raisePropertyChanged(desc_cameraType); - ICameraOwner *owner = getCameraOwner(); + ICameraOwner* owner = getCameraOwner(); if (owner) owner->cameraMoved(); } @@ -191,21 +191,21 @@ namespace RBX cameraSubject = shared_from((ModelInstance*) newSubject); raisePropertyChanged(cameraSubjectProp); - ICameraOwner *owner = getCameraOwner(); + ICameraOwner* owner = getCameraOwner(); if (owner) owner->cameraMoved(); } } } - void Camera::setCameraFocus(const G3D::CoordinateFrame &value) + void Camera::setCameraFocus(const G3D::CoordinateFrame& value) { if (value != cameraFocus) { cameraFocus = value; raisePropertyChanged(desc_Focus); - ICameraOwner *owner = getCameraOwner(); + ICameraOwner* owner = getCameraOwner(); if (owner) owner->cameraMoved(); } @@ -226,15 +226,15 @@ namespace RBX } raisePropertyChanged(desc_CoordFrame); - ICameraOwner *owner = getCameraOwner(); + ICameraOwner* owner = getCameraOwner(); if (owner) owner->cameraMoved(); } } - bool Camera::zoomExtents(const G3D::Rect2D &viewPort) + bool Camera::zoomExtents(const G3D::Rect2D& viewPort) { - ICameraOwner *owner = getCameraOwner(); + ICameraOwner* owner = getCameraOwner(); if (owner) { zoomExtents(owner->computeCameraOwnerExtents(), viewPort, ZOOM_IN_OR_OUT); @@ -243,7 +243,7 @@ namespace RBX return false; } - void Camera::setCameraCoordinateFrameNoLerp(const G3D::CoordinateFrame &value) + void Camera::setCameraCoordinateFrameNoLerp(const G3D::CoordinateFrame& value) { cameraGoal = value; goalToCamera(); From 85920f29070dc89c501ea1c18e271b77ee0b3cad Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Sun, 28 Dec 2025 15:59:14 -0500 Subject: [PATCH 16/28] forgot some --- Client/App/v8datamodel/Camera.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp index d389c0f9..b43cf366 100644 --- a/Client/App/v8datamodel/Camera.cpp +++ b/Client/App/v8datamodel/Camera.cpp @@ -85,7 +85,7 @@ namespace RBX cameraGoal.translation -= lookVector * (newZoomDistance / currentDistance - 1.0f); - ICameraOwner *owner = getCameraOwner(); + ICameraOwner* owner = getCameraOwner(); if (owner) owner->cameraMoved(); @@ -105,7 +105,7 @@ namespace RBX heading = Math::radWrap(heading + angle); setHeadingElevationDistance(heading, elevation, distance); - ICameraOwner *owner = getCameraOwner(); + ICameraOwner* owner = getCameraOwner(); if (owner) owner->cameraMoved(); } @@ -182,7 +182,7 @@ namespace RBX } } - void Camera::setCameraSubject(Instance *newSubject) + void Camera::setCameraSubject(Instance* newSubject) { if (newSubject != getCameraSubjectInstance()) { From 98faa13ba23944964597918fe63fa4a02ff38f0b Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Mon, 29 Dec 2025 12:35:16 -0500 Subject: [PATCH 17/28] merge conflict fix attempt I moved G3D. I was having compiler errors when having it in between Instance and Extents. --- Client/App/include/v8datamodel/Camera.h | 76 +++++++++++++------------ 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/Client/App/include/v8datamodel/Camera.h b/Client/App/include/v8datamodel/Camera.h index 5a21abc6..73dbab95 100644 --- a/Client/App/include/v8datamodel/Camera.h +++ b/Client/App/include/v8datamodel/Camera.h @@ -1,40 +1,45 @@ #pragma once -#include -#include "reflection/reflection.h" +#include +#include +#include +#include #include "v8tree/Instance.h" -#include "v8world/ContactManager.h" #include "util/Extents.h" namespace RBX { - extern const char* sCamera; - - class ICameraOwner; + class Primitive; + class ContactManager; class ICameraSubject; + class ICameraOwner; + + extern const char* sCamera; class Camera : public DescribedCreatable { - public: - enum CameraType + private: + enum AnimationType { - FIXED_CAMERA = 0, - ATTACH_CAMERA = 1, - WATCH_CAMERA = 2, - TRACK_CAMERA = 3, - FOLLOW_CAMERA = 4, - CUSTOM_CAMERA = 5, - NUM_CAMERA_TYPE = 6, + ALWAYS, + AUTO }; - enum AnimationType + public: + enum CameraType { - ALWAYS = 0, - AUTO = 1, + FIXED_CAMERA, + ATTACH_CAMERA, + WATCH_CAMERA, + TRACK_CAMERA, + FOLLOW_CAMERA, + CUSTOM_CAMERA, + NUM_CAMERA_TYPE }; - enum ZoomType + enum ZoomType { - ZOOM_IN_OR_OUT = 0, - ZOOM_OUT_ONLY = 1, - ZOOM_CHAR_PART_DRAG = 2, + ZOOM_IN_OR_OUT, + ZOOM_OUT_ONLY, + ZOOM_CHAR_PART_DRAG, }; + private: G3D::GCamera gCamera; G3D::CoordinateFrame cameraGoal; @@ -43,6 +48,7 @@ namespace RBX AnimationType animationType; boost::shared_ptr cameraSubject; bool cameraExternallyAdjusted; + private: ICameraOwner* getCameraOwner(); void updateFocus(); @@ -54,14 +60,13 @@ namespace RBX float goalToFocusDistance() const; void setGCameraCoordinateFrame(const G3D::CoordinateFrame&); G3D::CoordinateFrame computeLineOfSiteGoal(); - void getHeadingElevationDistance(float &heading, float &elevation, float &distance); + void getHeadingElevationDistance(float& heading, float& elevation, float& distance); void setHeadingElevationDistance(float, float, float); void tellCameraMoved(); - void getIgnorePrims(G3D::Array&); - virtual bool askSetParent(const Instance *instance) const; - + void getIgnorePrims(G3D::Array&); + virtual bool askSetParent(const Instance* instance) const; public: - //Camera(const RBX::Camera&); + //Camera(const Camera&); Camera(); virtual ~Camera(); public: @@ -76,17 +81,17 @@ namespace RBX bool isFirstPersonCamera() const; ICameraSubject* getCameraSubject() const; Instance* getCameraSubjectInstance() const; - void setCameraSubject(Instance*); + void setCameraSubject(Instance* newSubject); const G3D::CoordinateFrame& getCameraFocus() const { return cameraFocus; } - void setCameraFocus(const G3D::CoordinateFrame &value); + void setCameraFocus(const G3D::CoordinateFrame& value); G3D::CoordinateFrame getCameraCoordinateFrame() const { return gCamera.getCoordinateFrame(); } - void setCameraCoordinateFrameNoLerp(const G3D::CoordinateFrame&); + void setCameraCoordinateFrameNoLerp(const G3D::CoordinateFrame& value); void goalToCamera(); CameraType getCameraType() const; void setCameraType(CameraType type); @@ -96,16 +101,17 @@ namespace RBX bool zoom(float in); bool setDistanceFromTarget(float); void zoomExtents(Extents, const G3D::Rect2D&, ZoomType); - bool zoomExtents(const G3D::Rect2D &viewPort); + bool zoomExtents(const G3D::Rect2D& viewPort); void panRadians(float angle); void panUnits(int); bool tiltRadians(float); bool tiltUnits(int); - void lookAt(const G3D::Vector3 &point); + void lookAt(const G3D::Vector3& point); void setImageServerViewNoLerp(const G3D::CoordinateFrame&, const G3D::Rect2D&); - //RBX::Camera& operator=(const RBX::Camera&); - - public: + public: + //Camera& operator=(const Camera&); + + public: static float distanceDefault(); static float distanceMin(); static float distanceMax(); From 24b0926d2ed5a9047d1ffbed75e9ae2abcaf6eeb Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Sun, 4 Jan 2026 10:27:30 -0500 Subject: [PATCH 18/28] More Functions! --- Client/App/v8datamodel/Camera.cpp | 35 +++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp index b43cf366..52d41682 100644 --- a/Client/App/v8datamodel/Camera.cpp +++ b/Client/App/v8datamodel/Camera.cpp @@ -1,5 +1,6 @@ #include "v8datamodel/Camera.h" #include "v8datamodel/Workspace.h" +#include "v8datamodel/ICharacterSubject.h" #include "util/Math.h" namespace RBX @@ -36,6 +37,10 @@ namespace RBX } } + Camera::~Camera() + { + } + bool Camera::askSetParent(const Instance* instance) const { return fastDynamicCast(instance) != NULL; @@ -140,6 +145,36 @@ namespace RBX return false; } + void Camera::onHeartbeat() + { + updateGoal(); + G3D::CoordinateFrame adjustedGoal = cameraGoal; + ICameraSubject* cameraSubject = getCameraSubject(); + ICharacterSubject* characterSubject = dynamic_cast(cameraSubject); + + if(characterSubject) + characterSubject->onHeartBeat(cameraGoal, cameraFocus); + + G3D::CoordinateFrame cameraCoord = gCamera.getCoordinateFrame(); + G3D::CoordinateFrame LerpFrame = cameraCoord.lerp(adjustedGoal, 0.9f); + + if (Math::legalCameraCoord(LerpFrame)) + { + gCamera.setCoordinateFrame(LerpFrame); + } + else + { + RBXASSERT(0); + } + + if(animationType == ALWAYS || !Math::fuzzyEq(LerpFrame, cameraCoord, 0.01f, 0.01f)) + { + ICameraOwner* owner = getCameraOwner(); + if (owner) + owner->cameraMoved(); + } + } + Instance* Camera::getCameraSubjectInstance() const { return cameraSubject.get(); From 221811d170793453a611e9fed4cfd070aebd9b83 Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Sun, 4 Jan 2026 14:25:46 -0500 Subject: [PATCH 19/28] agonizing work --- Client/App/v8datamodel/Camera.cpp | 114 ++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp index 52d41682..c2560896 100644 --- a/Client/App/v8datamodel/Camera.cpp +++ b/Client/App/v8datamodel/Camera.cpp @@ -97,6 +97,16 @@ namespace RBX return true; } + void Camera::setHeadingElevationDistance(float heading, float elevation, float distance) + { + Math::setHeadingElevation(cameraGoal, heading, elevation); + cameraFocus.rotation = cameraGoal.rotation; + + G3D::Vector3 lookVector = cameraFocus.lookVector(); + cameraGoal.translation = cameraFocus.translation - lookVector * distance; + cameraExternallyAdjusted = true; + } + void Camera::panRadians(float angle) { RBXASSERT(angle > -100); @@ -122,6 +132,75 @@ namespace RBX cameraFocus = cameraSubject->getLocation(); } + //63% matching. This needs to be rechecked as functionality might be incorrect. + void Camera::updateGoal() + { + switch(cameraType) + { + case ATTACH_CAMERA: + { + G3D::Vector3 v1 = cameraGoal.translation - cameraFocus.translation; + G3D::Vector2 v2 = v1.xz(); + + double distance = G3D::distance(v2.x, v2.y); + + updateFocus(); + + G3D::Vector3 lookVector = cameraFocus.lookVector(); + G3D::Vector2 v3 = lookVector.xz(); + + G3D::Vector2 direction = v3.direction(); + + cameraGoal.translation.x = cameraFocus.translation.x - direction.x * distance; + cameraGoal.translation.y = cameraFocus.translation.y + v1.y; + cameraGoal.translation.z = cameraFocus.translation.z - direction.y * distance; + break; + } + case WATCH_CAMERA: + { + updateFocus(); + break; + } + case TRACK_CAMERA: + { + G3D::Vector3 v1 = cameraFocus.translation; + + updateFocus(); + + cameraGoal.translation += cameraFocus.translation - v1; + break; + } + case FOLLOW_CAMERA: + { + G3D::Vector3 v1 = cameraFocus.translation - cameraGoal.translation; + G3D::Vector2 v2 = v1.xz(); + + double distance = G3D::distance(v2.x, v2.y); + + updateFocus(); + + G3D::Vector2 v3 = cameraGoal.translation.xz(); + G3D::Vector2 v4 = cameraFocus.translation.xz(); + + G3D::Vector2 direction = (v4 - v3).direction(); + + cameraGoal.translation.x = cameraFocus.translation.x - direction.x * distance; + cameraGoal.translation.y = cameraFocus.translation.y - v1.y; + cameraGoal.translation.z = cameraFocus.translation.z - direction.y * distance; + break; + } + case CUSTOM_CAMERA: + { + ICameraSubject* cameraSubject = getCameraSubject(); + if(cameraSubject) + cameraSubject->stepGoalAndFocus(cameraGoal, cameraFocus, cameraExternallyAdjusted); + cameraExternallyAdjusted = false; + break; + } + } + cameraGoal.lookAt(cameraFocus.translation); + } + bool Camera::zoom(float in) { if (cameraType == CUSTOM_CAMERA) @@ -175,6 +254,21 @@ namespace RBX } } + bool Camera::setDistanceFromTarget(float newDistance) + { + G3D::Vector3 lookVector = cameraFocus.translation - cameraGoal.translation; + float currentDistance = lookVector.magnitude(); + + if (newDistance < 0.5f && currentDistance == 0.5f || newDistance > 1000.0f && currentDistance == 1000.0f) + return false; + //TODO: WORK ON THIS + ICameraOwner* owner = getCameraOwner(); + if (owner) + owner->cameraMoved(); + + return true; + } + Instance* Camera::getCameraSubjectInstance() const { return cameraSubject.get(); @@ -267,6 +361,26 @@ namespace RBX } } + void Camera::tryZoomExtents(float low, float current, float high, const RBX::Extents& extents, const G3D::Rect2D& viewPort) + { + RBXASSERT(current >= low); + RBXASSERT(current <= high); + + if(high - low < 0.1) + { + setDistanceFromTarget(current); + updateGoal(); + goalToCamera(); + + if (extents.containedByFrustum(gCamera.frustum(viewPort))) + { + //TODO: FIGURE THIS OUT + } + + tryZoomExtents(low, (low + high) * 0.5, high, extents, viewPort); + } + } + bool Camera::zoomExtents(const G3D::Rect2D& viewPort) { ICameraOwner* owner = getCameraOwner(); From 9992a67c2e72ce70a96d22265cd5db9d5407fb0d Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Sun, 4 Jan 2026 15:35:35 -0500 Subject: [PATCH 20/28] i gave up --- Client/App/v8datamodel/Camera.cpp | 41 +++---------------------------- 1 file changed, 3 insertions(+), 38 deletions(-) diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp index c2560896..69e28a5f 100644 --- a/Client/App/v8datamodel/Camera.cpp +++ b/Client/App/v8datamodel/Camera.cpp @@ -132,7 +132,7 @@ namespace RBX cameraFocus = cameraSubject->getLocation(); } - //63% matching. This needs to be rechecked as functionality might be incorrect. + //63% matching. This needs to be rechecked as functionality is most likely incorrect. void Camera::updateGoal() { switch(cameraType) @@ -231,7 +231,7 @@ namespace RBX ICameraSubject* cameraSubject = getCameraSubject(); ICharacterSubject* characterSubject = dynamic_cast(cameraSubject); - if(characterSubject) + if (characterSubject) characterSubject->onHeartBeat(cameraGoal, cameraFocus); G3D::CoordinateFrame cameraCoord = gCamera.getCoordinateFrame(); @@ -246,7 +246,7 @@ namespace RBX RBXASSERT(0); } - if(animationType == ALWAYS || !Math::fuzzyEq(LerpFrame, cameraCoord, 0.01f, 0.01f)) + if (animationType == ALWAYS || !Math::fuzzyEq(LerpFrame, cameraCoord, 0.01f, 0.01f)) { ICameraOwner* owner = getCameraOwner(); if (owner) @@ -254,21 +254,6 @@ namespace RBX } } - bool Camera::setDistanceFromTarget(float newDistance) - { - G3D::Vector3 lookVector = cameraFocus.translation - cameraGoal.translation; - float currentDistance = lookVector.magnitude(); - - if (newDistance < 0.5f && currentDistance == 0.5f || newDistance > 1000.0f && currentDistance == 1000.0f) - return false; - //TODO: WORK ON THIS - ICameraOwner* owner = getCameraOwner(); - if (owner) - owner->cameraMoved(); - - return true; - } - Instance* Camera::getCameraSubjectInstance() const { return cameraSubject.get(); @@ -361,26 +346,6 @@ namespace RBX } } - void Camera::tryZoomExtents(float low, float current, float high, const RBX::Extents& extents, const G3D::Rect2D& viewPort) - { - RBXASSERT(current >= low); - RBXASSERT(current <= high); - - if(high - low < 0.1) - { - setDistanceFromTarget(current); - updateGoal(); - goalToCamera(); - - if (extents.containedByFrustum(gCamera.frustum(viewPort))) - { - //TODO: FIGURE THIS OUT - } - - tryZoomExtents(low, (low + high) * 0.5, high, extents, viewPort); - } - } - bool Camera::zoomExtents(const G3D::Rect2D& viewPort) { ICameraOwner* owner = getCameraOwner(); From 32832cadb5eca1773b9be43be6578e3824499b08 Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Sat, 17 Jan 2026 16:57:52 -0500 Subject: [PATCH 21/28] Update App.vcproj --- Client/App/App.vcproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Client/App/App.vcproj b/Client/App/App.vcproj index 69a3788c..d247a295 100644 --- a/Client/App/App.vcproj +++ b/Client/App/App.vcproj @@ -1270,6 +1270,10 @@ RelativePath=".\v8datamodel\BrickColor.cpp" > + + From efd9a613b1f4ecb66508efaca37c1519ec3f5729 Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Tue, 20 Jan 2026 11:44:11 -0500 Subject: [PATCH 22/28] ok --- Client/App/v8datamodel/Camera.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp index 69e28a5f..fefddfd8 100644 --- a/Client/App/v8datamodel/Camera.cpp +++ b/Client/App/v8datamodel/Camera.cpp @@ -132,11 +132,16 @@ namespace RBX cameraFocus = cameraSubject->getLocation(); } - //63% matching. This needs to be rechecked as functionality is most likely incorrect. + //72.84% matching. This needs to be rechecked as functionality is most likely incorrect. void Camera::updateGoal() { switch(cameraType) { + case WATCH_CAMERA: + { + updateFocus(); + break; + } case ATTACH_CAMERA: { G3D::Vector3 v1 = cameraGoal.translation - cameraFocus.translation; @@ -156,11 +161,6 @@ namespace RBX cameraGoal.translation.z = cameraFocus.translation.z - direction.y * distance; break; } - case WATCH_CAMERA: - { - updateFocus(); - break; - } case TRACK_CAMERA: { G3D::Vector3 v1 = cameraFocus.translation; From d4edbd8c60702728d38b275a50fe14c66e5b638b Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Tue, 20 Jan 2026 13:46:13 -0500 Subject: [PATCH 23/28] zoomExtents 87.82% matching --- Client/App/include/util/Extents.h | 6 +++- Client/App/v8datamodel/Camera.cpp | 49 ++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/Client/App/include/util/Extents.h b/Client/App/include/util/Extents.h index 8e28bb5f..b711c765 100644 --- a/Client/App/include/util/Extents.h +++ b/Client/App/include/util/Extents.h @@ -42,7 +42,11 @@ namespace RBX NormalId closestFace(const G3D::Vector3& point); void unionWith(const Extents& other); void shift(const G3D::Vector3&); - void scale(float); + void scale(float scale) + { + this->low *= scale; + this->high *= scale; + } void expand(float f) { this->low -= G3D::Vector3(f, f, f); diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp index fefddfd8..0de3e170 100644 --- a/Client/App/v8datamodel/Camera.cpp +++ b/Client/App/v8datamodel/Camera.cpp @@ -132,7 +132,7 @@ namespace RBX cameraFocus = cameraSubject->getLocation(); } - //72.84% matching. This needs to be rechecked as functionality is most likely incorrect. + //72.84% matching. void Camera::updateGoal() { switch(cameraType) @@ -346,6 +346,53 @@ namespace RBX } } + //87.82% matching. + void Camera::zoomExtents(Extents extents, const G3D::Rect2D& viewPort, Camera::ZoomType zoomType) + { + G3D::CoordinateFrame currentCoord = gCamera.getCoordinateFrame(); + extents.expand(0.1f); + + if (zoomType != ZOOM_CHAR_PART_DRAG || cameraType == CUSTOM_CAMERA) + { + double low = 0.5; + + if (cameraType == FIXED_CAMERA) + { + G3D::Vector3 scaler = extents.center() - cameraFocus.translation; + + cameraFocus.translation += scaler; + cameraGoal.translation += scaler; + } + + if (zoomType == ZOOM_OUT_ONLY || zoomType == ZOOM_CHAR_PART_DRAG) + low = (cameraGoal.translation - cameraFocus.translation).magnitude(); + + double current = (cameraGoal.translation - cameraFocus.translation).magnitude(); + + RBXASSERT(G3D::isFinite(current)); + + if (zoomType == ZOOM_CHAR_PART_DRAG) + extents.scale(1.1f); + + if (G3D::isFinite(low) && G3D::isFinite(current) && G3D::isFinite(1000.0)) + tryZoomExtents(low, current, 1000, extents, viewPort); + + cameraGoal = gCamera.getCoordinateFrame(); + if (Math::legalCameraCoord(currentCoord)) + { + gCamera.setCoordinateFrame(currentCoord); + } + else + { + RBXASSERT(0); + } + + ICameraOwner* owner = getCameraOwner(); + if (owner) + owner->cameraMoved(); + } + } + bool Camera::zoomExtents(const G3D::Rect2D& viewPort) { ICameraOwner* owner = getCameraOwner(); From d005f1fcf211e816ef129bb16323ac21bd1c8b0f Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Tue, 20 Jan 2026 23:32:54 -0500 Subject: [PATCH 24/28] updateGoal matching to 87.80% --- Client/App/v8datamodel/Camera.cpp | 33 +++++++++++-------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp index 0de3e170..de50e374 100644 --- a/Client/App/v8datamodel/Camera.cpp +++ b/Client/App/v8datamodel/Camera.cpp @@ -132,7 +132,7 @@ namespace RBX cameraFocus = cameraSubject->getLocation(); } - //72.84% matching. + //87.80% matching. void Camera::updateGoal() { switch(cameraType) @@ -145,20 +145,15 @@ namespace RBX case ATTACH_CAMERA: { G3D::Vector3 v1 = cameraGoal.translation - cameraFocus.translation; - G3D::Vector2 v2 = v1.xz(); - - double distance = G3D::distance(v2.x, v2.y); + double distance = v1.xz().length(); updateFocus(); - G3D::Vector3 lookVector = cameraFocus.lookVector(); - G3D::Vector2 v3 = lookVector.xz(); - - G3D::Vector2 direction = v3.direction(); + G3D::Vector2 direction = cameraFocus.lookVector().xz().direction(); - cameraGoal.translation.x = cameraFocus.translation.x - direction.x * distance; - cameraGoal.translation.y = cameraFocus.translation.y + v1.y; - cameraGoal.translation.z = cameraFocus.translation.z - direction.y * distance; + cameraGoal.translation = G3D::Vector3(cameraFocus.translation.x - direction.x * distance, + cameraFocus.translation.y + v1.y, + cameraFocus.translation.z - direction.y * distance); break; } case TRACK_CAMERA: @@ -173,20 +168,16 @@ namespace RBX case FOLLOW_CAMERA: { G3D::Vector3 v1 = cameraFocus.translation - cameraGoal.translation; - G3D::Vector2 v2 = v1.xz(); - - double distance = G3D::distance(v2.x, v2.y); + double distance = v1.xz().length(); updateFocus(); - - G3D::Vector2 v3 = cameraGoal.translation.xz(); - G3D::Vector2 v4 = cameraFocus.translation.xz(); - G3D::Vector2 direction = (v4 - v3).direction(); + G3D::Vector2 direction = (cameraGoal.translation.xz() - cameraFocus.translation.xz()).direction(); + + cameraGoal.translation = G3D::Vector3(cameraFocus.translation.x - direction.x * distance, + cameraFocus.translation.y - v1.y, + cameraFocus.translation.z - direction.y * distance); - cameraGoal.translation.x = cameraFocus.translation.x - direction.x * distance; - cameraGoal.translation.y = cameraFocus.translation.y - v1.y; - cameraGoal.translation.z = cameraFocus.translation.z - direction.y * distance; break; } case CUSTOM_CAMERA: From 36e00d3b46a85b3ffe7255327841174a677a27bd Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Wed, 21 Jan 2026 07:49:48 -0500 Subject: [PATCH 25/28] tryZoomExtents and headers --- Client/App/include/v8datamodel/Camera.h | 4 ++-- Client/App/v8datamodel/Camera.cpp | 24 +++++++++++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/Client/App/include/v8datamodel/Camera.h b/Client/App/include/v8datamodel/Camera.h index 327e20fa..19014832 100644 --- a/Client/App/include/v8datamodel/Camera.h +++ b/Client/App/include/v8datamodel/Camera.h @@ -55,7 +55,7 @@ namespace RBX void updateGoal(); bool characterZoom(float); bool nonCharacterZoom(float in); - void tryZoomExtents(float, float, float, const Extents&, const G3D::Rect2D&); + void tryZoomExtents(float low, float current, float high, const RBX::Extents& extents, const G3D::Rect2D& viewPort); ContactManager& getContactManager(); float goalToFocusDistance() const; void setGCameraCoordinateFrame(const G3D::CoordinateFrame&); @@ -100,7 +100,7 @@ namespace RBX void onWrapMouse(const G3D::Vector2&); bool zoom(float in); bool setDistanceFromTarget(float); - void zoomExtents(Extents, const G3D::Rect2D&, ZoomType); + void zoomExtents(Extents extents, const G3D::Rect2D& viewPort, ZoomType zoomType); bool zoomExtents(const G3D::Rect2D& viewPort); void panRadians(float angle); void panUnits(int); diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp index de50e374..904df4bd 100644 --- a/Client/App/v8datamodel/Camera.cpp +++ b/Client/App/v8datamodel/Camera.cpp @@ -337,6 +337,28 @@ namespace RBX } } + //84.84% matching. + void Camera::tryZoomExtents(float low, float current, float high, const RBX::Extents& extents, const G3D::Rect2D& viewPort) + { + RBXASSERT(current >= low); + RBXASSERT(current <= high); + + if (high - low > 0.1) + { + setDistanceFromTarget(current); + updateGoal(); + goalToCamera(); + + bool isContained = extents.containedByFrustum(gCamera.frustum(viewPort)); + + float newLow = (isContained) ? low : current; + float newHigh = (isContained) ? current : high; + float newCurrent = (newHigh + newLow) * 0.5; + + tryZoomExtents(newLow, newCurrent, newHigh, extents, viewPort); + } + } + //87.82% matching. void Camera::zoomExtents(Extents extents, const G3D::Rect2D& viewPort, Camera::ZoomType zoomType) { @@ -366,7 +388,7 @@ namespace RBX extents.scale(1.1f); if (G3D::isFinite(low) && G3D::isFinite(current) && G3D::isFinite(1000.0)) - tryZoomExtents(low, current, 1000, extents, viewPort); + tryZoomExtents(low, current, 1000.0, extents, viewPort); cameraGoal = gCamera.getCoordinateFrame(); if (Math::legalCameraCoord(currentCoord)) From 3aca5c5e68156045baafcbd1082d9d81c3359db2 Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Wed, 21 Jan 2026 07:58:04 -0500 Subject: [PATCH 26/28] simplification --- Client/App/v8datamodel/Camera.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp index 904df4bd..e40e5994 100644 --- a/Client/App/v8datamodel/Camera.cpp +++ b/Client/App/v8datamodel/Camera.cpp @@ -128,8 +128,7 @@ namespace RBX void Camera::updateFocus() { - ICameraSubject* cameraSubject = getCameraSubject(); - cameraFocus = cameraSubject->getLocation(); + cameraFocus = getCameraSubject()->getLocation(); } //87.80% matching. From 06a2a36560c08251cf57d6a60c2e9b1ce508cc99 Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Wed, 21 Jan 2026 18:47:29 -0500 Subject: [PATCH 27/28] setDistanceFromTarget --- Client/App/include/v8datamodel/Camera.h | 2 +- Client/App/v8datamodel/Camera.cpp | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Client/App/include/v8datamodel/Camera.h b/Client/App/include/v8datamodel/Camera.h index 19014832..6e3c8e12 100644 --- a/Client/App/include/v8datamodel/Camera.h +++ b/Client/App/include/v8datamodel/Camera.h @@ -99,7 +99,7 @@ namespace RBX bool canTilt(int) const; void onWrapMouse(const G3D::Vector2&); bool zoom(float in); - bool setDistanceFromTarget(float); + bool setDistanceFromTarget(float newDistance); void zoomExtents(Extents extents, const G3D::Rect2D& viewPort, ZoomType zoomType); bool zoomExtents(const G3D::Rect2D& viewPort); void panRadians(float angle); diff --git a/Client/App/v8datamodel/Camera.cpp b/Client/App/v8datamodel/Camera.cpp index e40e5994..0bddea9d 100644 --- a/Client/App/v8datamodel/Camera.cpp +++ b/Client/App/v8datamodel/Camera.cpp @@ -73,6 +73,28 @@ namespace RBX distance = (cameraGoal.translation - cameraFocus.translation).magnitude(); } + //70.53% matching. + bool Camera::setDistanceFromTarget(float newDistance) + { + G3D::Vector3 lookVector = cameraFocus.translation - cameraGoal.translation; + float currentDistance = lookVector.magnitude(); + + if (newDistance < 0.5 && currentDistance == 0.5 || newDistance > 1000.0 && currentDistance == 1000.0) + return false; + + newDistance = (newDistance < 0.5) ? 0.5 : newDistance; + newDistance = (newDistance > 1000.0) ? 1000.0 : newDistance; + + lookVector *= newDistance; + cameraGoal.translation = cameraFocus.translation - (lookVector / currentDistance); + + ICameraOwner* owner = getCameraOwner(); + if (owner) + owner->cameraMoved(); + + return true; + } + void Camera::alwaysMode() { animationType = ALWAYS; From 374c111f164d8fde79b554bf7bb810aaf4297f0f Mon Sep 17 00:00:00 2001 From: Tad Walter Date: Mon, 23 Feb 2026 15:25:54 -0500 Subject: [PATCH 28/28] Update App.vcproj --- Client/App/App.vcproj | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Client/App/App.vcproj b/Client/App/App.vcproj index 813b5c2f..7e86a783 100644 --- a/Client/App/App.vcproj +++ b/Client/App/App.vcproj @@ -804,11 +804,11 @@ - - + - + @@ -1286,6 +1286,10 @@ RelativePath=".\v8datamodel\BrickColor.cpp" > + +