respect raylib style-guide

This commit is contained in:
Alexey Karnachev 2023-12-30 16:35:55 +04:00
parent 64eb5b1a7a
commit 4901d375ac
2 changed files with 396 additions and 307 deletions

View File

@ -1,3 +1,18 @@
/*******************************************************************************************
*
* raylib [gizmo] example - Gizmo gadget for an interactive object 3D transformations
*
* Example originally created with raylib 5.0, last time updated with raylib 5.0
*
* Example contributed by Alexey Karnachev (@alexeykarnachev) and reviewed by Ramon Santamaria (@raysan5)
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2023-2024 Alexey Karnachev (@alexeykarnachev)
*
********************************************************************************************/
#include "raylib.h" #include "raylib.h"
#include "rcamera.h" #include "rcamera.h"
@ -5,39 +20,46 @@
#include "gizmo.h" #include "gizmo.h"
#undef RAYGIZMO_IMPLEMENTATION #undef RAYGIZMO_IMPLEMENTATION
void updateCamera(Camera3D* camera) { #define CAMERA_ROT_SPEED 0.003f
float rot_speed = 0.003f; #define CAMERA_MOVE_SPEED 0.01f
float move_speed = 0.01f; #define CAMERA_ZOOM_SPEED 1.0f
float zoom_speed = 1.0f;
bool is_middle = IsMouseButtonDown(2); // Updates the camera in the orbital-style, i.e camera rotates around the look-at point by the orbit
bool is_shift = IsKeyDown(KEY_LEFT_SHIFT); static void updateCamera(Camera3D* camera) {
Vector2 mouse_delta = GetMouseDelta(); bool isMMBDown = IsMouseButtonDown(2);
bool isShiftDown = IsKeyDown(KEY_LEFT_SHIFT);
Vector2 mouseDelta = GetMouseDelta();
if (is_middle && is_shift) { // Shift + MMB + mouse move -> change the camera position in the right-direction plane
CameraMoveRight(camera, -move_speed * mouse_delta.x, true); if (isMMBDown && isShiftDown) {
CameraMoveRight(camera, -CAMERA_MOVE_SPEED * mouseDelta.x, true);
Vector3 right = GetCameraRight(camera); Vector3 right = GetCameraRight(camera);
Vector3 up = Vector3CrossProduct( Vector3 up = Vector3CrossProduct(
Vector3Subtract(camera->position, camera->target), right Vector3Subtract(camera->position, camera->target), right
); );
up = Vector3Scale(Vector3Normalize(up), move_speed * mouse_delta.y); up = Vector3Scale(Vector3Normalize(up), CAMERA_MOVE_SPEED * mouseDelta.y);
camera->position = Vector3Add(camera->position, up); camera->position = Vector3Add(camera->position, up);
camera->target = Vector3Add(camera->target, up); camera->target = Vector3Add(camera->target, up);
} else if (is_middle) { // Rotate the camera around the look-at point
CameraYaw(camera, -rot_speed * mouse_delta.x, true); } else if (isMMBDown) {
CameraPitch(camera, rot_speed * mouse_delta.y, true, true, false); CameraYaw(camera, -CAMERA_ROT_SPEED * mouseDelta.x, true);
CameraPitch(camera, CAMERA_ROT_SPEED * mouseDelta.y, true, true, false);
} }
CameraMoveToTarget(camera, -GetMouseWheelMove() * zoom_speed); // Bring camera closer (or move away), to the look-at point
CameraMoveToTarget(camera, -GetMouseWheelMove() * CAMERA_ZOOM_SPEED);
} }
int main(void) { int main(void)
const int screen_width = 800; {
const int screen_height = 450; // Initialization
InitWindow(screen_width, screen_height, "Gizmo"); //--------------------------------------------------------------------------------------
SetTargetFPS(60); const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [gizmo] example - gizmo gadget");
// Define 3D perspective camera
Camera3D camera; Camera3D camera;
camera.fovy = 45.0f; camera.fovy = 45.0f;
camera.target = (Vector3){0.0f, 0.0f, 0.0f}; camera.target = (Vector3){0.0f, 0.0f, 0.0f};
@ -45,20 +67,25 @@ int main(void) {
camera.up = (Vector3){0.0f, 1.0f, 0.0f}; camera.up = (Vector3){0.0f, 1.0f, 0.0f};
camera.projection = CAMERA_PERSPECTIVE; camera.projection = CAMERA_PERSPECTIVE;
Model model = LoadModelFromMesh(GenMeshTorus(0.3, 1.5, 16.0, 16.0)); Model model = LoadModelFromMesh(GenMeshTorus(0.3, 1.5, 16.0, 16.0)); // Create simple torus model
loadGizmo(); // Load gizmo
LoadGizmo(); SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
while (!WindowShouldClose()) { while (!WindowShouldClose())
{
// Update
//----------------------------------------------------------------------------------
updateCamera(&camera); updateCamera(&camera);
// Draw
//----------------------------------------------------------------------------------
BeginDrawing(); BeginDrawing();
{
ClearBackground(DARKGRAY); ClearBackground(DARKGRAY);
rlEnableDepthTest(); rlEnableDepthTest();
BeginMode3D(camera); BeginMode3D(camera);
{
// Draw main model // Draw main model
DrawModel(model, (Vector3){0.0, 0.0, 0.0}, 1.0, PURPLE); DrawModel(model, (Vector3){0.0, 0.0, 0.0}, 1.0, PURPLE);
@ -83,13 +110,12 @@ int main(void) {
(Vector3){0.0f, 0.0f, 50.0f}, (Vector3){0.0f, 0.0f, 50.0f},
DARKBLUE DARKBLUE
); );
}
EndMode3D(); EndMode3D();
// Immediately update and draw gizmo // Immediately update and draw gizmo
Vector3 position = { Vector3 position = {
model.transform.m12, model.transform.m13, model.transform.m14}; model.transform.m12, model.transform.m13, model.transform.m14};
Matrix transform = UpdateGizmo(camera, position); Matrix transform = updateAndDrawGizmo(camera, position);
// Apply gizmo-produced transformation to the model // Apply gizmo-produced transformation to the model
model.transform = MatrixMultiply(model.transform, transform); model.transform = MatrixMultiply(model.transform, transform);
@ -100,13 +126,16 @@ int main(void) {
DrawText(" zoom: wheel", 5, 25, 20, RED); DrawText(" zoom: wheel", 5, 25, 20, RED);
DrawText(" rotate: mmb", 5, 45, 20, RED); DrawText(" rotate: mmb", 5, 45, 20, RED);
DrawText(" translate: shift + mmb", 5, 65, 20, RED); DrawText(" translate: shift + mmb", 5, 65, 20, RED);
}
EndDrawing(); EndDrawing();
} }
UnloadGizmo(); // De-Initialization
UnloadModel(model); //--------------------------------------------------------------------------------------
CloseWindow(); unloadGizmo(); // Unload gizmo
UnloadModel(model); // Unload model
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0; return 0;
} }

View File

@ -1,17 +1,60 @@
#include <raylib.h> /*******************************************************************************************
#include <stdlib.h> Alexey Karnachev License
---------------------------------------------------------------------------------
MIT License
void LoadGizmo(); Copyright (c) 2023 Alexey Karnachev
void UnloadGizmo();
Matrix UpdateGizmo(Camera3D camera, Vector3 position); Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
---------------------------------------------------------------------------------
Copyright (c) 2015-2023 Ramon Santamaria (@raysan5)
This software is provided "as-is", without any express or implied warranty. In no event
will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you
wrote the original software. If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented
as being the original software.
3. This notice may not be removed or altered from any source distribution.
**********************************************************************************************/
#include <raylib.h>
void loadGizmo();
void unloadGizmo();
Matrix updateAndDrawGizmo(Camera3D camera, Vector3 position);
#ifdef RAYGIZMO_IMPLEMENTATION #ifdef RAYGIZMO_IMPLEMENTATION
#include "raymath.h" #include <stdlib.h>
#include <math.h>
#include <rlgl.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#include <rlgl.h>
#include "raymath.h"
// This will be multiplied by the distance from the camera to the gizmo, // This will be multiplied by the distance from the camera to the gizmo,
// Which keeps the screen-space gizmo size constant. // Which keeps the screen-space gizmo size constant.
@ -22,23 +65,24 @@ Matrix UpdateGizmo(Camera3D camera, Vector3 position);
#define GIZMO_ACTIVE_AXIS_DRAW_THICKNESS 2.0f #define GIZMO_ACTIVE_AXIS_DRAW_THICKNESS 2.0f
// These sizes are relative to the gizmo radius // These sizes are relative to the gizmo radius
#define GIZMO_AXIS_HANDLE_LENGTH 1.2; #define GIZMO_AXIS_HANDLE_LENGTH 1.2f;
#define GIZMO_AXIS_HANDLE_TIP_LENGTH 0.3; #define GIZMO_AXIS_HANDLE_TIP_LENGTH 0.3f;
#define GIZMO_AXIS_HANDLE_TIP_RADIUS 0.1; #define GIZMO_AXIS_HANDLE_TIP_RADIUS 0.1f;
#define GIZMO_PLANE_HANDLE_OFFSET 0.4; #define GIZMO_PLANE_HANDLE_OFFSET 0.4f;
#define GIZMO_PLANE_HANDLE_SIZE 0.2; #define GIZMO_PLANE_HANDLE_SIZE 0.2f;
#define X_AXIS \ #define X_AXIS (Vector3){ 1.0, 0.0, 0.0 }
(Vector3) { 1.0, 0.0, 0.0 } #define Y_AXIS (Vector3){ 0.0, 1.0, 0.0 }
#define Y_AXIS \ #define Z_AXIS (Vector3){ 0.0, 0.0, 1.0 }
(Vector3) { 0.0, 1.0, 0.0 }
#define Z_AXIS \
(Vector3) { 0.0, 0.0, 1.0 }
#define MASK_FRAMEBUFFER_WIDTH 500.0 // Size of the additional buffer to pre-render the gizmo into.
#define MASK_FRAMEBUFFER_HEIGHT 500.0 // Used for the mouse picking.
#define MASK_FRAMEBUFFER_WIDTH 500
#define MASK_FRAMEBUFFER_HEIGHT 500
#define swap(x, y) \ #define ID_TO_RED_COLOR(id) (Color){ id, 0, 0, 0 }
#define SWAP(x, y) \
do { \ do { \
unsigned char \ unsigned char \
swap_temp[sizeof(x) == sizeof(y) ? (signed)sizeof(x) : -1]; \ swap_temp[sizeof(x) == sizeof(y) ? (signed)sizeof(x) : -1]; \
@ -47,9 +91,8 @@ Matrix UpdateGizmo(Camera3D camera, Vector3 position);
memcpy(&x, swap_temp, sizeof(x)); \ memcpy(&x, swap_temp, sizeof(x)); \
} while (0) } while (0)
#define id_to_red_color(id) \
(Color) { id, 0, 0, 0 }
#if defined(PLATFORM_DESKTOP) // Shaders for PLATFORM_DESKTOP
static const char* SHADER_COLOR_VERT = "\ static const char* SHADER_COLOR_VERT = "\
#version 330\n\ #version 330\n\
in vec3 vertexPosition; \ in vec3 vertexPosition; \
@ -57,21 +100,23 @@ in vec4 vertexColor; \
out vec4 fragColor; \ out vec4 fragColor; \
out vec3 fragPosition; \ out vec3 fragPosition; \
uniform mat4 mvp; \ uniform mat4 mvp; \
void main() { \ void main() \
{ \
fragColor = vertexColor; \ fragColor = vertexColor; \
fragPosition = vertexPosition; \ fragPosition = vertexPosition; \
gl_Position = mvp * vec4(vertexPosition, 1.0); \ gl_Position = mvp * vec4(vertexPosition, 1.0); \
} \ } \
"; ";
static const char* SHADER_ROT_HANDLE_COLOR_FRAG = "\ static const char* shaderRotHandleColor_FRAG = "\
#version 330\n\ #version 330\n\
in vec4 fragColor; \ in vec4 fragColor; \
in vec3 fragPosition; \ in vec3 fragPosition; \
uniform vec3 cameraPosition; \ uniform vec3 cameraPosition; \
uniform vec3 gizmoPosition; \ uniform vec3 gizmoPosition; \
out vec4 finalColor; \ out vec4 finalColor; \
void main() { \ void main() \
{ \
vec3 r = normalize(fragPosition - gizmoPosition); \ vec3 r = normalize(fragPosition - gizmoPosition); \
vec3 c = normalize(fragPosition - cameraPosition); \ vec3 c = normalize(fragPosition - cameraPosition); \
if (dot(r, c) > 0.1) discard; \ if (dot(r, c) > 0.1) discard; \
@ -79,15 +124,48 @@ void main() { \
} \ } \
"; ";
static Shader SHADER_ROT_HANDLE_COLOR; #else // Shaders for PLATFORM_ANDROID, PLATFORM_WEB
static int SHADER_ROT_HANDLE_CAMERA_POS_LOC;
static int SHADER_ROT_HANDLE_GIZMO_POS_LOC;
static unsigned int MASK_FRAMEBUFFER; static const char* SHADER_COLOR_VERT = "\
static unsigned int MASK_TEXTURE; #version 100\n\
attribute vec3 vertexPosition; \
attribute vec4 vertexColor; \
varying vec4 fragColor; \
varying vec3 fragPosition; \
uniform mat4 mvp; \
void main() \
{ \
fragColor = vertexColor; \
fragPosition = vertexPosition; \
gl_Position = mvp * vec4(vertexPosition, 1.0); \
} \
";
static bool IS_GIZMO_LOADED; static const char* shaderRotHandleColor_FRAG = "\
static Vector3 GIZMO_CURRENT_AXIS; #version 100\n\
precision mediump float; \
varying vec4 fragColor; \
varying vec3 fragPosition; \
uniform vec3 cameraPosition; \
uniform vec3 gizmoPosition; \
void main() { \
vec3 r = normalize(fragPosition - gizmoPosition); \
vec3 c = normalize(fragPosition - cameraPosition); \
if (dot(r, c) > 0.1) discard; \
gl_FragColor = fragColor; \
} \
";
#endif
static Shader shaderRotHandleColor;
static int ShaderRotHandleCameraPosLoc;
static int ShaderRotHandleGizmoPosLoc;
static unsigned int maskFramebuffer;
static unsigned int maskTexture;
static bool isGizmoLoaded;
static Vector3 gizmoCurrentAxis;
typedef enum HandleId { typedef enum HandleId {
HANDLE_X, HANDLE_X,
@ -129,7 +207,7 @@ typedef struct Handle {
Vector3 position; Vector3 position;
Vector3 axis; Vector3 axis;
Color color; Color color;
float dist_to_cam; float distToCamera;
} Handle; } Handle;
typedef struct HandleColors { typedef struct HandleColors {
@ -142,17 +220,17 @@ typedef struct Handles {
Handle arr[3]; Handle arr[3];
} Handles; } Handles;
static GizmoState GIZMO_STATE; static GizmoState gizmoState;
bool check_if_mouse_moved() { static bool checkIfMouseMoved() {
Vector2 mouse_delta = GetMouseDelta(); Vector2 mouseDelta = GetMouseDelta();
return (fabs(mouse_delta.x) + fabs(mouse_delta.y)) > EPSILON; return (fabs(mouseDelta.x) + fabs(mouseDelta.y)) > EPSILON;
} }
static float vector2_get_angle(Vector2 v1, Vector2 v2) { static float getAngleBetweenTwoVector2(Vector2 v1, Vector2 v2) {
Vector2 v1_norm = Vector2Normalize(v1); Vector2 v1Normal = Vector2Normalize(v1);
Vector2 v2_norm = Vector2Normalize(v2); Vector2 v2Normal = Vector2Normalize(v2);
float dot = Vector2DotProduct(v1_norm, v2_norm); float dot = Vector2DotProduct(v1Normal, v2Normal);
if (1.0 - fabs(dot) < EPSILON) return 0.0; if (1.0 - fabs(dot) < EPSILON) return 0.0;
float angle = acos(dot); float angle = acos(dot);
@ -163,71 +241,63 @@ static float vector2_get_angle(Vector2 v1, Vector2 v2) {
else return -angle; else return -angle;
} }
static int isect_line_plane( static int intersectLinePlane(
Vector3* out_p, Vector3* outPoint,
Vector3 line_p0, Vector3 linePoint0,
Vector3 line_p1, Vector3 linePoint1,
Vector3 plane_p, Vector3 planePoint,
Vector3 plane_normal Vector3 planeNormal
) { ) {
Vector3 u = Vector3Subtract(line_p1, line_p0); Vector3 u = Vector3Subtract(linePoint1, linePoint0);
float dot = Vector3DotProduct(plane_normal, u); float dot = Vector3DotProduct(planeNormal, u);
if (fabs(dot) <= EPSILON) { if (fabs(dot) <= EPSILON) return 0;
return 0;
}
Vector3 w = Vector3Subtract(line_p0, plane_p); Vector3 w = Vector3Subtract(linePoint0, planePoint);
float k = -Vector3DotProduct(plane_normal, w) / dot; float k = -Vector3DotProduct(planeNormal, w) / dot;
u = Vector3Scale(u, k); u = Vector3Scale(u, k);
*out_p = Vector3Add(line_p0, u); *outPoint = Vector3Add(linePoint0, u);
return 1; return 1;
} }
static int get_two_vecs_nearest_point( static int getTwoLinesNearestPoint(
Vector3* vec0_out_nearest_point, Vector3* outPoint,
Vector3 vec0_p0, Vector3 line0Point0,
Vector3 vec0_p1, Vector3 line0Point1,
Vector3 vec1_p0, Vector3 line1Point0,
Vector3 vec1_p1 Vector3 line1Point1
) { ) {
Vector3 vec0 = Vector3Subtract(vec0_p1, vec0_p0); Vector3 vec0 = Vector3Subtract(line0Point1, line0Point0);
Vector3 vec1 = Vector3Subtract(vec1_p1, vec1_p0); Vector3 vec1 = Vector3Subtract(line1Point1, line1Point0);
Vector3 plane_vec = Vector3CrossProduct(vec0, vec1); Vector3 planeVec = Vector3Normalize(Vector3CrossProduct(vec0, vec1));
plane_vec = Vector3Normalize(plane_vec); Vector3 planeNormal = Vector3Normalize(Vector3CrossProduct(vec0, planeVec));
Vector3 plane_normal = Vector3CrossProduct(vec0, plane_vec);
plane_normal = Vector3Normalize(plane_normal);
int is_isect = isect_line_plane( int isIntersected = intersectLinePlane(
vec0_out_nearest_point, vec1_p0, vec1_p1, vec0_p0, plane_normal outPoint, line1Point0, line1Point1, line0Point0, planeNormal
); );
return is_isect; return isIntersected;
} }
static RayCollision get_ray_plane_collision( static RayCollision getRayPlaneCollision(
Ray ray, Vector3 plane_point, Vector3 plane_normal Ray ray, Vector3 planePoint, Vector3 planeNormal
) { ) {
RayCollision collision = {0}; RayCollision collision = {0};
// Calculate the parameter t // Calculate the parameter t
float denominator = ray.direction.x * plane_normal.x float denominator = ray.direction.x * planeNormal.x
+ ray.direction.y * plane_normal.y + ray.direction.y * planeNormal.y
+ ray.direction.z * plane_normal.z; + ray.direction.z * planeNormal.z;
if (denominator == 0) {
// Ray is parallel to the plane, no collision // Ray is parallel to the plane, no collision
return collision; if (denominator == 0) return collision;
}
float t = ((plane_point.x - ray.position.x) * plane_normal.x float t = ((planePoint.x - ray.position.x) * planeNormal.x
+ (plane_point.y - ray.position.y) * plane_normal.y + (planePoint.y - ray.position.y) * planeNormal.y
+ (plane_point.z - ray.position.z) * plane_normal.z) + (planePoint.z - ray.position.z) * planeNormal.z)
/ denominator; / denominator;
if (t < 0) {
// Intersection point is behind the ray's starting point, no collision // Intersection point is behind the ray's starting point, no collision
return collision; if (t < 0) return collision;
}
// Calculate the collision point // Calculate the collision point
collision.point.x = ray.position.x + t * ray.direction.x; collision.point.x = ray.position.x + t * ray.direction.x;
@ -238,188 +308,180 @@ static RayCollision get_ray_plane_collision(
return collision; return collision;
} }
static Handles get_sorted_handles(Handle h0, Handle h1, Handle h2) { static Handles getSortedHandled(Handle h0, Handle h1, Handle h2) {
if (h0.dist_to_cam < h1.dist_to_cam) swap(h0, h1); if (h0.distToCamera < h1.distToCamera) SWAP(h0, h1);
if (h1.dist_to_cam < h2.dist_to_cam) swap(h1, h2); if (h1.distToCamera < h2.distToCamera) SWAP(h1, h2);
if (h0.dist_to_cam < h1.dist_to_cam) swap(h0, h1); if (h0.distToCamera < h1.distToCamera) SWAP(h0, h1);
Handles handles = {.arr = {h0, h1, h2}}; Handles handles = {.arr = {h0, h1, h2}};
return handles; return handles;
} }
static HandleColors get_handle_colors(GizmoState hot_state) { static HandleColors getHandleColors(GizmoState hotState) {
bool is_hot = GIZMO_STATE == hot_state || GIZMO_STATE == hot_state + 4; bool isHot = gizmoState == hotState || gizmoState == hotState + 4;
Color x = is_hot && GIZMO_CURRENT_AXIS.x == 1.0 ? WHITE : RED; Color x = isHot && gizmoCurrentAxis.x == 1.0f ? WHITE : RED;
Color y = is_hot && GIZMO_CURRENT_AXIS.y == 1.0 ? WHITE : GREEN; Color y = isHot && gizmoCurrentAxis.y == 1.0f ? WHITE : GREEN;
Color z = is_hot && GIZMO_CURRENT_AXIS.z == 1.0 ? WHITE : BLUE; Color z = isHot && gizmoCurrentAxis.z == 1.0f ? WHITE : BLUE;
HandleColors colors = {x, y, z}; HandleColors colors = {x, y, z};
return colors; return colors;
} }
static void draw_axis_handles( static void drawAxisHandles(
Camera3D camera, Camera3D camera,
Vector3 position, Vector3 position,
float gizmo_radius, float gizmoRadius,
Color color_x, Color colorX,
Color color_y, Color colorY,
Color color_z Color colorZ
) { ) {
float length = gizmo_radius * GIZMO_AXIS_HANDLE_LENGTH; float length = gizmoRadius * GIZMO_AXIS_HANDLE_LENGTH;
float tip_length = gizmo_radius * GIZMO_AXIS_HANDLE_TIP_LENGTH; float tipLength = gizmoRadius * GIZMO_AXIS_HANDLE_TIP_LENGTH;
float tip_radius = gizmo_radius * GIZMO_AXIS_HANDLE_TIP_RADIUS; float tipRadius = gizmoRadius * GIZMO_AXIS_HANDLE_TIP_RADIUS;
Vector3 px = Vector3Add(position, Vector3Scale(X_AXIS, length)); Vector3 px = Vector3Add(position, Vector3Scale(X_AXIS, length));
Vector3 py = Vector3Add(position, Vector3Scale(Y_AXIS, length)); Vector3 py = Vector3Add(position, Vector3Scale(Y_AXIS, length));
Vector3 pz = Vector3Add(position, Vector3Scale(Z_AXIS, length)); Vector3 pz = Vector3Add(position, Vector3Scale(Z_AXIS, length));
Handle hx = {px, X_AXIS, color_x, Vector3DistanceSqr(px, camera.position)}; Handle hx = {px, X_AXIS, colorX, Vector3DistanceSqr(px, camera.position)};
Handle hy = {py, Y_AXIS, color_y, Vector3DistanceSqr(py, camera.position)}; Handle hy = {py, Y_AXIS, colorY, Vector3DistanceSqr(py, camera.position)};
Handle hz = {pz, Z_AXIS, color_z, Vector3DistanceSqr(pz, camera.position)}; Handle hz = {pz, Z_AXIS, colorZ, Vector3DistanceSqr(pz, camera.position)};
Handles handles = get_sorted_handles(hx, hy, hz); Handles handles = getSortedHandled(hx, hy, hz);
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
Handle* h = &handles.arr[i]; Handle* h = &handles.arr[i];
Vector3 tip_end = Vector3Add( Vector3 tipEnd = Vector3Add(
h->position, Vector3Scale(h->axis, tip_length) h->position, Vector3Scale(h->axis, tipLength)
); );
DrawLine3D(position, h->position, h->color); DrawLine3D(position, h->position, h->color);
DrawCylinderEx(h->position, tip_end, tip_radius, 0.0, 16, h->color); DrawCylinderEx(h->position, tipEnd, tipRadius, 0.0f, 16, h->color);
} }
} }
static void draw_plane_handles( static void drawPlaneHandles(
Camera3D camera, Camera3D camera,
Vector3 position, Vector3 position,
float gizmo_radius, float gizmoRadius,
Color color_x, Color colorX,
Color color_y, Color colorY,
Color color_z Color colorZ
) { ) {
float offset = gizmo_radius * GIZMO_PLANE_HANDLE_OFFSET; float offset = gizmoRadius * GIZMO_PLANE_HANDLE_OFFSET;
float size = gizmo_radius * GIZMO_PLANE_HANDLE_SIZE; float size = gizmoRadius * GIZMO_PLANE_HANDLE_SIZE;
Vector3 px = Vector3Add(position, (Vector3){0.0, offset, offset}); Vector3 px = Vector3Add(position, (Vector3){0.0f, offset, offset});
Vector3 py = Vector3Add(position, (Vector3){offset, 0.0, offset}); Vector3 py = Vector3Add(position, (Vector3){offset, 0.0f, offset});
Vector3 pz = Vector3Add(position, (Vector3){offset, offset, 0.0}); Vector3 pz = Vector3Add(position, (Vector3){offset, offset, 0.0f});
Handle hx = {px, Z_AXIS, color_x, Vector3DistanceSqr(px, camera.position)}; Handle hx = {px, Z_AXIS, colorX, Vector3DistanceSqr(px, camera.position)};
Handle hy = {py, Y_AXIS, color_y, Vector3DistanceSqr(py, camera.position)}; Handle hy = {py, Y_AXIS, colorY, Vector3DistanceSqr(py, camera.position)};
Handle hz = {pz, X_AXIS, color_z, Vector3DistanceSqr(pz, camera.position)}; Handle hz = {pz, X_AXIS, colorZ, Vector3DistanceSqr(pz, camera.position)};
Handles handles = get_sorted_handles(hx, hy, hz); Handles handles = getSortedHandled(hx, hy, hz);
rlDisableBackfaceCulling(); rlDisableBackfaceCulling();
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
Handle* h = &handles.arr[i]; Handle* h = &handles.arr[i];
rlPushMatrix(); rlPushMatrix();
{
rlTranslatef(h->position.x, h->position.y, h->position.z); rlTranslatef(h->position.x, h->position.y, h->position.z);
rlRotatef(90.0, h->axis.x, h->axis.y, h->axis.z); rlRotatef(90.0f, h->axis.x, h->axis.y, h->axis.z);
DrawPlane( DrawPlane(
Vector3Zero(), Vector2Scale(Vector2One(), size), h->color Vector3Zero(), Vector2Scale(Vector2One(), size), h->color
); );
}
rlPopMatrix(); rlPopMatrix();
} }
} }
static void draw_rot_handles( static void drawRotHandles(
Camera3D camera, Camera3D camera,
Vector3 position, Vector3 position,
float gizmo_radius, float gizmoRadius,
Color color_x, Color colorX,
Color color_y, Color colorY,
Color color_z Color colorZ
) { ) {
BeginShaderMode(SHADER_ROT_HANDLE_COLOR); BeginShaderMode(shaderRotHandleColor);
{
SetShaderValue( SetShaderValue(
SHADER_ROT_HANDLE_COLOR, shaderRotHandleColor,
SHADER_ROT_HANDLE_CAMERA_POS_LOC, ShaderRotHandleCameraPosLoc,
&camera.position, &camera.position,
SHADER_UNIFORM_VEC3 SHADER_UNIFORM_VEC3
); );
SetShaderValue( SetShaderValue(
SHADER_ROT_HANDLE_COLOR, shaderRotHandleColor,
SHADER_ROT_HANDLE_GIZMO_POS_LOC, ShaderRotHandleGizmoPosLoc,
&position, &position,
SHADER_UNIFORM_VEC3 SHADER_UNIFORM_VEC3
); );
DrawCircle3D(position, gizmo_radius, Y_AXIS, 90.0, color_x); DrawCircle3D(position, gizmoRadius, Y_AXIS, 90.0f, colorX);
DrawCircle3D(position, gizmo_radius, X_AXIS, 90.0, color_y); DrawCircle3D(position, gizmoRadius, X_AXIS, 90.0f, colorY);
DrawCircle3D(position, gizmo_radius, X_AXIS, 0.0, color_z); DrawCircle3D(position, gizmoRadius, X_AXIS, 0.0f, colorZ);
}
EndShaderMode(); EndShaderMode();
} }
static void draw_gizmo( static void drawGizmo(
Camera3D camera, Camera3D camera,
Vector3 position, Vector3 position,
Color rot_handle_color_x, Color rotHandleColorX,
Color rot_handle_color_y, Color rotHandleColorY,
Color rot_handle_color_z, Color rotHandleColorZ,
Color axis_handle_color_x, Color axisHandleColorX,
Color axis_handle_color_y, Color axisHandleColorY,
Color axis_handle_color_z, Color axisHandleColorZ,
Color plane_handle_color_x, Color planeHandleColorX,
Color plane_handle_color_y, Color planeHandleColorY,
Color plane_handle_color_z Color planeHandleColorZ
) { ) {
float radius = GIZMO_SIZE * Vector3Distance(camera.position, position); float radius = GIZMO_SIZE * Vector3Distance(camera.position, position);
// Draw gizmo's handle elements // Draw gizmo's handle elements
BeginMode3D(camera); BeginMode3D(camera);
{
rlSetLineWidth(GIZMO_HANDLE_DRAW_THICKNESS); rlSetLineWidth(GIZMO_HANDLE_DRAW_THICKNESS);
rlDisableDepthTest(); rlDisableDepthTest();
draw_plane_handles( drawPlaneHandles(
camera, camera,
position, position,
radius, radius,
plane_handle_color_x, planeHandleColorX,
plane_handle_color_y, planeHandleColorY,
plane_handle_color_z planeHandleColorZ
); );
draw_rot_handles( drawRotHandles(
camera, camera,
position, position,
radius, radius,
rot_handle_color_x, rotHandleColorX,
rot_handle_color_y, rotHandleColorY,
rot_handle_color_z rotHandleColorZ
); );
draw_axis_handles( drawAxisHandles(
camera, camera,
position, position,
radius, radius,
axis_handle_color_x, axisHandleColorX,
axis_handle_color_y, axisHandleColorY,
axis_handle_color_z axisHandleColorZ
); );
}
EndMode3D(); EndMode3D();
// Draw long white line which represents current active axis // Draw long white line which represents current active axis
if (GIZMO_STATE == GIZMO_ACTIVE_ROT || GIZMO_STATE == GIZMO_ACTIVE_AXIS) { if (gizmoState == GIZMO_ACTIVE_ROT || gizmoState == GIZMO_ACTIVE_AXIS) {
BeginMode3D(camera); BeginMode3D(camera);
{
rlSetLineWidth(GIZMO_ACTIVE_AXIS_DRAW_THICKNESS); rlSetLineWidth(GIZMO_ACTIVE_AXIS_DRAW_THICKNESS);
Vector3 half_axis_line = Vector3Scale(GIZMO_CURRENT_AXIS, 1000.0); Vector3 halfAxisLine = Vector3Scale(gizmoCurrentAxis, 1000.0f);
DrawLine3D( DrawLine3D(
Vector3Subtract(position, half_axis_line), Vector3Subtract(position, halfAxisLine),
Vector3Add(position, half_axis_line), Vector3Add(position, halfAxisLine),
WHITE WHITE
); );
}
EndMode3D(); EndMode3D();
} }
// Draw white line from the gizmo's center to the mouse cursor when rotating // Draw white line from the gizmo's center to the mouse cursor when rotating
if (GIZMO_STATE == GIZMO_ACTIVE_ROT) { if (gizmoState == GIZMO_ACTIVE_ROT) {
rlSetLineWidth(GIZMO_ACTIVE_AXIS_DRAW_THICKNESS); rlSetLineWidth(GIZMO_ACTIVE_AXIS_DRAW_THICKNESS);
DrawLineV( DrawLineV(
GetWorldToScreen(position, camera), GetMousePosition(), WHITE GetWorldToScreen(position, camera), GetMousePosition(), WHITE
@ -427,26 +489,26 @@ static void draw_gizmo(
} }
} }
static unsigned char get_gizmo_mask_pixel(Camera3D camera, Vector3 position) { static unsigned char getGizmoMaskPixel(Camera3D camera, Vector3 position) {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Draw gizmo into a separate framebuffer for the mouse pixel-picking // Draw gizmo into a separate framebuffer for the mouse pixel-picking
rlEnableFramebuffer(MASK_FRAMEBUFFER); rlEnableFramebuffer(maskFramebuffer);
rlViewport(0, 0, MASK_FRAMEBUFFER_WIDTH, MASK_FRAMEBUFFER_HEIGHT); rlViewport(0, 0, MASK_FRAMEBUFFER_WIDTH, MASK_FRAMEBUFFER_HEIGHT);
rlClearScreenBuffers(); rlClearScreenBuffers();
rlDisableColorBlend(); rlDisableColorBlend();
draw_gizmo( drawGizmo(
camera, camera,
position, position,
id_to_red_color(ROT_HANDLE_X), ID_TO_RED_COLOR(ROT_HANDLE_X),
id_to_red_color(ROT_HANDLE_Y), ID_TO_RED_COLOR(ROT_HANDLE_Y),
id_to_red_color(ROT_HANDLE_Z), ID_TO_RED_COLOR(ROT_HANDLE_Z),
id_to_red_color(AXIS_HANDLE_X), ID_TO_RED_COLOR(AXIS_HANDLE_X),
id_to_red_color(AXIS_HANDLE_Y), ID_TO_RED_COLOR(AXIS_HANDLE_Y),
id_to_red_color(AXIS_HANDLE_Z), ID_TO_RED_COLOR(AXIS_HANDLE_Z),
id_to_red_color(PLANE_HANDLE_X), ID_TO_RED_COLOR(PLANE_HANDLE_X),
id_to_red_color(PLANE_HANDLE_Y), ID_TO_RED_COLOR(PLANE_HANDLE_Y),
id_to_red_color(PLANE_HANDLE_Z) ID_TO_RED_COLOR(PLANE_HANDLE_Z)
); );
rlDisableFramebuffer(); rlDisableFramebuffer();
@ -455,38 +517,38 @@ static unsigned char get_gizmo_mask_pixel(Camera3D camera, Vector3 position) {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Pick the pixel under the mouse cursor // Pick the pixel under the mouse cursor
Vector2 mouse_position = GetMousePosition(); Vector2 mousePosition = GetMousePosition();
unsigned char* pixels = (unsigned char*)rlReadTexturePixels( unsigned char* pixels = (unsigned char*)rlReadTexturePixels(
MASK_TEXTURE, maskTexture,
MASK_FRAMEBUFFER_WIDTH, MASK_FRAMEBUFFER_WIDTH,
MASK_FRAMEBUFFER_HEIGHT, MASK_FRAMEBUFFER_HEIGHT,
RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8
); );
float x_ratio = Clamp(mouse_position.x / (float)GetScreenWidth(), 0.0, 1.0); float xFract = Clamp(mousePosition.x / (float)GetScreenWidth(), 0.0, 1.0);
float y_ratio = Clamp( float yFract = Clamp(
1.0 - (mouse_position.y / (float)GetScreenHeight()), 0.0, 1.0 1.0 - (mousePosition.y / (float)GetScreenHeight()), 0.0, 1.0
); );
int x = (int)(MASK_FRAMEBUFFER_WIDTH * x_ratio); int x = (int)(MASK_FRAMEBUFFER_WIDTH * xFract);
int y = (int)(MASK_FRAMEBUFFER_HEIGHT * y_ratio); int y = (int)(MASK_FRAMEBUFFER_HEIGHT * yFract);
int idx = 4 * (y * MASK_FRAMEBUFFER_WIDTH + x); int idx = 4 * (y * MASK_FRAMEBUFFER_WIDTH + x);
unsigned char mask_val = pixels[idx]; unsigned char maskVal = pixels[idx];
free(pixels); free(pixels);
return mask_val; return maskVal;
} }
Matrix update_gizmo_rot(Camera3D camera, Vector3 position) { static Matrix updateGizmoRot(Camera3D camera, Vector3 position) {
if (!check_if_mouse_moved()) return MatrixIdentity(); if (!checkIfMouseMoved()) return MatrixIdentity();
Vector2 rot_center = GetWorldToScreen(position, camera); Vector2 posOnScreen = GetWorldToScreen(position, camera);
Vector2 p1 = Vector2Subtract(GetMousePosition(), rot_center); Vector2 p1 = Vector2Subtract(GetMousePosition(), posOnScreen);
Vector2 p0 = Vector2Subtract(p1, GetMouseDelta()); Vector2 p0 = Vector2Subtract(p1, GetMouseDelta());
float angle = vector2_get_angle(p1, p0); float angle = getAngleBetweenTwoVector2(p1, p0);
// If we look at gizmo from behind, we should flip the rotation // If we look at the gizmo from behind, we should flip the rotation
if (Vector3DotProduct(GIZMO_CURRENT_AXIS, position) if (Vector3DotProduct(gizmoCurrentAxis, position)
> Vector3DotProduct(GIZMO_CURRENT_AXIS, camera.position)) { > Vector3DotProduct(gizmoCurrentAxis, camera.position)) {
angle *= -1; angle *= -1;
} }
@ -495,7 +557,7 @@ Matrix update_gizmo_rot(Camera3D camera, Vector3 position) {
Matrix transform = MatrixMultiply( Matrix transform = MatrixMultiply(
MatrixMultiply( MatrixMultiply(
MatrixTranslate(-position.x, -position.y, -position.z), MatrixTranslate(-position.x, -position.y, -position.z),
MatrixRotate(GIZMO_CURRENT_AXIS, angle) MatrixRotate(gizmoCurrentAxis, angle)
), ),
MatrixTranslate(position.x, position.y, position.z) MatrixTranslate(position.x, position.y, position.z)
); );
@ -503,92 +565,90 @@ Matrix update_gizmo_rot(Camera3D camera, Vector3 position) {
return transform; return transform;
} }
Matrix update_gizmo_axis(Camera3D camera, Vector3 position) { static Matrix updateGizmoAxis(Camera3D camera, Vector3 position) {
if (!check_if_mouse_moved()) return MatrixIdentity(); if (!checkIfMouseMoved()) return MatrixIdentity();
Vector2 p = Vector2Add(GetWorldToScreen(position, camera), GetMouseDelta()); Vector2 p = Vector2Add(GetWorldToScreen(position, camera), GetMouseDelta());
Ray r = GetMouseRay(p, camera); Ray r = GetMouseRay(p, camera);
Vector3 isect_p = Vector3Zero(); Vector3 interesctionPoint = Vector3Zero();
bool is_isect = get_two_vecs_nearest_point( bool isIntersected = getTwoLinesNearestPoint(
&isect_p, &interesctionPoint,
camera.position, camera.position,
Vector3Add(camera.position, r.direction), Vector3Add(camera.position, r.direction),
position, position,
Vector3Add(position, GIZMO_CURRENT_AXIS) Vector3Add(position, gizmoCurrentAxis)
); );
if (!is_isect) if (!isIntersected) return MatrixIdentity();
{
return MatrixIdentity();
}
Vector3 offset = Vector3Subtract(isect_p, position); Vector3 offset = Vector3Subtract(interesctionPoint, position);
offset = Vector3Multiply(offset, GIZMO_CURRENT_AXIS); offset = Vector3Multiply(offset, gizmoCurrentAxis);
Matrix transform = MatrixTranslate(offset.x, offset.y, offset.z); Matrix transform = MatrixTranslate(offset.x, offset.y, offset.z);
return transform; return transform;
} }
Matrix update_gizmo_plane(Camera3D camera, Vector3 position) { static Matrix updateGizmoPlane(Camera3D camera, Vector3 position) {
if (!check_if_mouse_moved()) return MatrixIdentity(); if (!checkIfMouseMoved()) return MatrixIdentity();
Vector2 p = Vector2Add(GetWorldToScreen(position, camera), GetMouseDelta()); Vector2 p = Vector2Add(GetWorldToScreen(position, camera), GetMouseDelta());
Ray r = GetMouseRay(p, camera); Ray r = GetMouseRay(p, camera);
RayCollision c = get_ray_plane_collision(r, position, GIZMO_CURRENT_AXIS); RayCollision c = getRayPlaneCollision(r, position, gizmoCurrentAxis);
Vector3 offset = Vector3Subtract(c.point, position); Vector3 offset = Vector3Subtract(c.point, position);
Matrix transform = MatrixTranslate(offset.x, offset.y, offset.z); Matrix transform = MatrixTranslate(offset.x, offset.y, offset.z);
return transform; return transform;
} }
Matrix update_gizmo(Camera3D camera, Vector3 position, unsigned char mask_val) { static Matrix updateGizmo(Camera3D camera, Vector3 position, unsigned char maskVal) {
bool is_lmb_down = IsMouseButtonDown(0); bool isLMBDown = IsMouseButtonDown(0);
if (!is_lmb_down) GIZMO_STATE = GIZMO_COLD; if (!isLMBDown) gizmoState = GIZMO_COLD;
if (GIZMO_STATE < GIZMO_ACTIVE) { if (gizmoState < GIZMO_ACTIVE) {
if (mask_val < HANDLE_Y) GIZMO_CURRENT_AXIS = X_AXIS; if (maskVal < HANDLE_Y) gizmoCurrentAxis = X_AXIS;
else if (mask_val < HANDLE_Z) GIZMO_CURRENT_AXIS = Y_AXIS; else if (maskVal < HANDLE_Z) gizmoCurrentAxis = Y_AXIS;
else GIZMO_CURRENT_AXIS = Z_AXIS; else gizmoCurrentAxis = Z_AXIS;
if (mask_val % 4 == 1) if (maskVal % 4 == 1)
GIZMO_STATE = is_lmb_down ? GIZMO_ACTIVE_ROT : GIZMO_HOT_ROT; gizmoState = isLMBDown ? GIZMO_ACTIVE_ROT : GIZMO_HOT_ROT;
else if (mask_val % 4 == 2) else if (maskVal % 4 == 2)
GIZMO_STATE = is_lmb_down ? GIZMO_ACTIVE_AXIS : GIZMO_HOT_AXIS; gizmoState = isLMBDown ? GIZMO_ACTIVE_AXIS : GIZMO_HOT_AXIS;
else if (mask_val % 4 == 3) else if (maskVal % 4 == 3)
GIZMO_STATE = is_lmb_down ? GIZMO_ACTIVE_PLANE : GIZMO_HOT_PLANE; gizmoState = isLMBDown ? GIZMO_ACTIVE_PLANE : GIZMO_HOT_PLANE;
} }
switch (GIZMO_STATE) { switch (gizmoState) {
case GIZMO_ACTIVE_ROT: return update_gizmo_rot(camera, position); case GIZMO_ACTIVE_ROT: return updateGizmoRot(camera, position);
case GIZMO_ACTIVE_AXIS: return update_gizmo_axis(camera, position); case GIZMO_ACTIVE_AXIS: return updateGizmoAxis(camera, position);
case GIZMO_ACTIVE_PLANE: return update_gizmo_plane(camera, position); case GIZMO_ACTIVE_PLANE: return updateGizmoPlane(camera, position);
default: return MatrixIdentity(); default: return MatrixIdentity();
} }
} }
void LoadGizmo() { void loadGizmo() {
if (IS_GIZMO_LOADED) return; if (isGizmoLoaded) return;
SHADER_ROT_HANDLE_COLOR = LoadShaderFromMemory( shaderRotHandleColor = LoadShaderFromMemory(
SHADER_COLOR_VERT, SHADER_ROT_HANDLE_COLOR_FRAG SHADER_COLOR_VERT, shaderRotHandleColor_FRAG
); );
SHADER_ROT_HANDLE_CAMERA_POS_LOC = GetShaderLocation( ShaderRotHandleCameraPosLoc = GetShaderLocation(
SHADER_ROT_HANDLE_COLOR, "cameraPosition" shaderRotHandleColor, "cameraPosition"
); );
SHADER_ROT_HANDLE_GIZMO_POS_LOC = GetShaderLocation( ShaderRotHandleGizmoPosLoc = GetShaderLocation(
SHADER_ROT_HANDLE_COLOR, "gizmoPosition" shaderRotHandleColor, "gizmoPosition"
); );
MASK_FRAMEBUFFER = rlLoadFramebuffer( maskFramebuffer = rlLoadFramebuffer(
MASK_FRAMEBUFFER_WIDTH, MASK_FRAMEBUFFER_HEIGHT MASK_FRAMEBUFFER_WIDTH, MASK_FRAMEBUFFER_HEIGHT
); );
if (!MASK_FRAMEBUFFER) { if (!maskFramebuffer) {
TraceLog(LOG_ERROR, "Failed to create gizmo's mask framebuffer"); TraceLog(LOG_ERROR, "Failed to create gizmo's mask framebuffer");
exit(1); exit(1);
} }
rlEnableFramebuffer(MASK_FRAMEBUFFER); rlEnableFramebuffer(maskFramebuffer);
MASK_TEXTURE = rlLoadTexture( maskTexture = rlLoadTexture(
NULL, NULL,
MASK_FRAMEBUFFER_WIDTH, MASK_FRAMEBUFFER_WIDTH,
MASK_FRAMEBUFFER_HEIGHT, MASK_FRAMEBUFFER_HEIGHT,
@ -597,56 +657,56 @@ void LoadGizmo() {
); );
rlActiveDrawBuffers(1); rlActiveDrawBuffers(1);
rlFramebufferAttach( rlFramebufferAttach(
MASK_FRAMEBUFFER, maskFramebuffer,
MASK_TEXTURE, maskTexture,
RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_COLOR_CHANNEL0,
RL_ATTACHMENT_TEXTURE2D, RL_ATTACHMENT_TEXTURE2D,
0 0
); );
if (!rlFramebufferComplete(MASK_FRAMEBUFFER)) { if (!rlFramebufferComplete(maskFramebuffer)) {
TraceLog(LOG_ERROR, "Gizmo's framebuffer is not complete"); TraceLog(LOG_ERROR, "Gizmo's framebuffer is not complete");
exit(1); exit(1);
} }
IS_GIZMO_LOADED = true; isGizmoLoaded = true;
} }
void UnloadGizmo() { void unloadGizmo() {
if (!IS_GIZMO_LOADED) return; if (!isGizmoLoaded) return;
UnloadShader(SHADER_ROT_HANDLE_COLOR); UnloadShader(shaderRotHandleColor);
rlUnloadFramebuffer(MASK_FRAMEBUFFER); rlUnloadFramebuffer(maskFramebuffer);
rlUnloadTexture(MASK_TEXTURE); rlUnloadTexture(maskTexture);
IS_GIZMO_LOADED = false; isGizmoLoaded = false;
} }
Matrix UpdateGizmo(Camera3D camera, Vector3 position) { Matrix updateAndDrawGizmo(Camera3D camera, Vector3 position) {
if (!IS_GIZMO_LOADED) { if (!isGizmoLoaded) {
TraceLog(LOG_ERROR, "Gizmo must be loaded before the update"); TraceLog(LOG_ERROR, "Gizmo must be loaded before the update");
exit(1); exit(1);
} }
unsigned char mask_val = get_gizmo_mask_pixel(camera, position); unsigned char maskVal = getGizmoMaskPixel(camera, position);
Matrix transform = update_gizmo(camera, position, mask_val); Matrix transform = updateGizmo(camera, position, maskVal);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Draw gizmo // Draw gizmo
HandleColors rot_handle_colors = get_handle_colors(GIZMO_HOT_ROT); HandleColors rotHandleColors = getHandleColors(GIZMO_HOT_ROT);
HandleColors axis_handle_colors = get_handle_colors(GIZMO_HOT_AXIS); HandleColors axisHandleColors = getHandleColors(GIZMO_HOT_AXIS);
HandleColors plane_handle_colors = get_handle_colors(GIZMO_HOT_PLANE); HandleColors planeHandleColors = getHandleColors(GIZMO_HOT_PLANE);
draw_gizmo( drawGizmo(
camera, camera,
position, position,
rot_handle_colors.x, rotHandleColors.x,
rot_handle_colors.y, rotHandleColors.y,
rot_handle_colors.z, rotHandleColors.z,
axis_handle_colors.x, axisHandleColors.x,
axis_handle_colors.y, axisHandleColors.y,
axis_handle_colors.z, axisHandleColors.z,
plane_handle_colors.x, planeHandleColors.x,
plane_handle_colors.y, planeHandleColors.y,
plane_handle_colors.z planeHandleColors.z
); );
return transform; return transform;