From 3cad094edd94f859540b16bbdafcf2cfb9d02016 Mon Sep 17 00:00:00 2001 From: Marc Palau Date: Mon, 2 Mar 2015 20:52:58 +0100 Subject: [PATCH] Changes integration (some WIP, view details) Corrected GetMouseWheelMove() Corrected camera system Reviewed cubicmap resolution (collision detection) Added QuaternionTransform() WIP: Raycast system (not working) WIP: Reviewing axis-angle rotations... --- src/core.c | 154 ++++++++++++++++++++++++++++++++++------- src/models.c | 172 +++++++++++++++++++++++++++++++-------------- src/raylib.h | 15 +++- src/raymath.c | 20 ++++-- src/raymath.h | 3 +- src/rlgl.c | 188 ++++++++++++++++++++++++++++++++++++++++++++++---- src/rlgl.h | 3 +- 7 files changed, 452 insertions(+), 103 deletions(-) diff --git a/src/core.c b/src/core.c index c61381fd..a2344395 100644 --- a/src/core.c +++ b/src/core.c @@ -106,7 +106,8 @@ // FREE_CAMERA #define FREE_CAMERA_MOUSE_SENSITIVITY 0.01 -#define FREE_CAMERA_DISTANCE_CLAMP 0.3 +#define FREE_CAMERA_DISTANCE_MIN_CLAMP 0.3 +#define FREE_CAMERA_DISTANCE_MAX_CLAMP 12 #define FREE_CAMERA_MIN_CLAMP 85 #define FREE_CAMERA_MAX_CLAMP -85 #define FREE_CAMERA_SMOOTH_ZOOM_SENSITIVITY 0.05 @@ -118,7 +119,7 @@ // FIRST_PERSON #define FIRST_PERSON_MOUSE_SENSITIVITY 0.003 #define FIRST_PERSON_FOCUS_DISTANCE 25 -#define FIRST_PERSON_MIN_CLAMP 5 +#define FIRST_PERSON_MIN_CLAMP 85 #define FIRST_PERSON_MAX_CLAMP -85 #define FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER 5.0 @@ -604,8 +605,8 @@ void Begin3dMode(Camera camera) if (cameraMode == CAMERA_CUSTOM) currentCamera = camera; else currentCamera = internalCamera; - Matrix matLookAt = MatrixLookAt(currentCamera.position, currentCamera.target, currentCamera.up); - rlMultMatrixf(GetMatrixVector(matLookAt)); // Multiply MODELVIEW matrix by view matrix (camera) + Matrix view = MatrixLookAt(currentCamera.position, currentCamera.target, currentCamera.up); + rlMultMatrixf(GetMatrixVector(view)); // Multiply MODELVIEW matrix by view matrix (camera) } // Ends 3D mode and returns to default 2D orthographic mode @@ -703,6 +704,60 @@ void ShowLogo(void) showLogo = true; } +Ray GetMouseRay(Vector2 mousePosition, Camera camera) +{ + Ray ray; + + Matrix proj = MatrixIdentity(); + Matrix view = MatrixLookAt(currentCamera.position, currentCamera.target, currentCamera.up); + + float aspect = (GLfloat)GetScreenWidth()/(GLfloat)GetScreenHeight(); + double top = 0.1f*tanf(45.0f*PI / 360.0f); + double right = top*aspect; + + proj = MatrixFrustum(-right, right, -top, top, 0.01f, 1000.0f); + MatrixTranspose(&proj); + + float realy = (float)GetScreenHeight() - mousePosition.y; + + float z; + // glReadPixels(mousePosition.x, mousePosition.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z); + //http://www.bfilipek.com/2012/06/select-mouse-opengl.html + + Vector3 nearPoint = { mousePosition.x, realy, 0.0f }; + Vector3 farPoint = { mousePosition.x, realy, 1.0f }; + + nearPoint = internalCamera.position; + farPoint = rlglUnproject(farPoint, proj, view); + + Vector3 direction = VectorSubtract(farPoint, nearPoint); + VectorNormalize(&direction); + + ray.position = nearPoint; + ray.direction = direction; + + // Test + Vector2 screenPos; + screenPos.x = (mousePosition.x / (float)GetScreenWidth() * 2.0) - 1.0f; + screenPos.y = (mousePosition.y / (float)GetScreenHeight() * 2.0) - 1.0f; + + direction = VectorSubtract(internalCamera.target, internalCamera.position); + + printf("/nScreenPos %f, %f", screenPos.x, screenPos.y); + + Matrix rotate; + rotate = MatrixIdentity(); + rotate = MatrixRotate(0, 45*DEG2RAD*screenPos.y, 0); + VectorTransform(&direction, rotate); + + VectorNormalize(&direction); + + ray.position = internalCamera.position; + ray.direction = direction; + + return ray; +} + void SetCameraMode(int mode) { if ((cameraMode == CAMERA_FIRST_PERSON) && (mode == CAMERA_FREE)) @@ -721,28 +776,30 @@ void SetCameraMode(int mode) } else if ((cameraMode == CAMERA_CUSTOM) && (mode == CAMERA_FREE)) { - cameraMode = CAMERA_THIRD_PERSON; - cameraTargetDistance = 5; - internalCamera.position = (Vector3){ -1, 1, -1 }; - internalCamera.target = (Vector3){ 3, 0, 3}; + cameraTargetDistance = 10; + cameraAngle.x = 45 * DEG2RAD; + cameraAngle.y = -40 * DEG2RAD; + internalCamera.target = (Vector3){ 0, 0, 0}; ProcessCamera(&internalCamera, &internalCamera.position); } else if ((cameraMode == CAMERA_CUSTOM) && (mode == CAMERA_ORBITAL)) { - cameraMode = CAMERA_THIRD_PERSON; - cameraTargetDistance = 5; - cameraAngle.x = 45 * DEG2RAD; - cameraAngle.y = -20 * DEG2RAD; + cameraTargetDistance = 10; + cameraAngle.x = 225 * DEG2RAD; + cameraAngle.y = -40 * DEG2RAD; + internalCamera.target = (Vector3){ 3, 0, 3}; ProcessCamera(&internalCamera, &internalCamera.position); } cameraMode = mode; } -void UpdateCamera(Vector3 *playerPosition) +Camera UpdateCamera(Vector3 *position) { // Calculate camera - if (cameraMode != CAMERA_CUSTOM) ProcessCamera(&internalCamera, playerPosition); + if (cameraMode != CAMERA_CUSTOM) ProcessCamera(&internalCamera, position); + + return internalCamera; } //---------------------------------------------------------------------------------- @@ -858,10 +915,6 @@ void SetMousePosition(Vector2 position) // Returns mouse wheel movement Y int GetMouseWheelMove(void) { - previousMouseWheelY = currentMouseWheelY; - - currentMouseWheelY = 0; - return previousMouseWheelY; } #endif @@ -1839,6 +1892,9 @@ static void PollInputEvents(void) // Register previous mouse states for (int i = 0; i < 3; i++) previousMouseState[i] = currentMouseState[i]; + previousMouseWheelY = currentMouseWheelY; + currentMouseWheelY = 0; + glfwPollEvents(); // Register keyboard/mouse events... and window events! #elif defined(PLATFORM_ANDROID) @@ -2337,12 +2393,13 @@ static void LogoAnimation(void) static void ProcessCamera(Camera *camera, Vector3 *playerPosition) { // Mouse movement detection - if (fullscreen) + if (cameraMode != CAMERA_FREE) { - if (GetMousePosition().x < 100) SetMousePosition((Vector2){ screenWidth - 100, GetMousePosition().y}); - else if (GetMousePosition().y < 100) SetMousePosition((Vector2){ GetMousePosition().x, screenHeight - 100}); - else if (GetMousePosition().x > screenWidth - 100) SetMousePosition((Vector2) { 100, GetMousePosition().y}); - else if (GetMousePosition().y > screenHeight - 100) SetMousePosition((Vector2){ GetMousePosition().x, 100}); + HideCursor(); + if (GetMousePosition().x < GetScreenHeight() / 3) SetMousePosition((Vector2){ screenWidth - GetScreenHeight() / 3, GetMousePosition().y}); + else if (GetMousePosition().y < GetScreenHeight() / 3) SetMousePosition((Vector2){ GetMousePosition().x, screenHeight - GetScreenHeight() / 3}); + else if (GetMousePosition().x > screenWidth - GetScreenHeight() / 3) SetMousePosition((Vector2) { GetScreenHeight() / 3, GetMousePosition().y}); + else if (GetMousePosition().y > screenHeight - GetScreenHeight() / 3) SetMousePosition((Vector2){ GetMousePosition().x, GetScreenHeight() / 3}); else { cameraMouseVariation.x = GetMousePosition().x - cameraMousePosition.x; @@ -2351,6 +2408,7 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition) } else { + ShowCursor(); cameraMouseVariation.x = GetMousePosition().x - cameraMousePosition.x; cameraMouseVariation.y = GetMousePosition().y - cameraMousePosition.y; } @@ -2366,11 +2424,55 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition) if (IsKeyPressed('O')) cameraMode = CAMERA_ORBITAL; // Camera zoom - cameraTargetDistance -= (GetMouseWheelMove() * CAMERA_SCROLL_SENSITIVITY); + if ((cameraTargetDistance < FREE_CAMERA_DISTANCE_MAX_CLAMP) && (GetMouseWheelMove() < 0)) + { + cameraTargetDistance -= (GetMouseWheelMove() * CAMERA_SCROLL_SENSITIVITY); + + if (cameraTargetDistance > FREE_CAMERA_DISTANCE_MAX_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_MAX_CLAMP; + } + // Camera looking down + else if ((camera->position.y > camera->target.y) && (cameraTargetDistance == FREE_CAMERA_DISTANCE_MAX_CLAMP) && (GetMouseWheelMove() < 0)) + { + camera->target.x += GetMouseWheelMove() * (camera->target.x - camera->position.x) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance; + camera->target.y += GetMouseWheelMove() * (camera->target.y - camera->position.y) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance; + camera->target.z += GetMouseWheelMove() * (camera->target.z - camera->position.z) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance; + } + else if ((camera->position.y > camera->target.y) && (camera->target.y >= 0)) + { + camera->target.x += GetMouseWheelMove() * (camera->target.x - camera->position.x) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance; + camera->target.y += GetMouseWheelMove() * (camera->target.y - camera->position.y) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance; + camera->target.z += GetMouseWheelMove() * (camera->target.z - camera->position.z) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance; + + if (camera->target.y < 0) camera->target.y = -0.001; + } + else if ((camera->position.y > camera->target.y) && (camera->target.y < 0) && (GetMouseWheelMove() > 0)) + { + cameraTargetDistance -= (GetMouseWheelMove() * CAMERA_SCROLL_SENSITIVITY); + if (cameraTargetDistance < FREE_CAMERA_DISTANCE_MIN_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_MIN_CLAMP; + } + // Camera looking up + else if ((camera->position.y < camera->target.y) && (cameraTargetDistance == FREE_CAMERA_DISTANCE_MAX_CLAMP) && (GetMouseWheelMove() < 0)) + { + camera->target.x += GetMouseWheelMove() * (camera->target.x - camera->position.x) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance; + camera->target.y += GetMouseWheelMove() * (camera->target.y - camera->position.y) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance; + camera->target.z += GetMouseWheelMove() * (camera->target.z - camera->position.z) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance; + } + else if ((camera->position.y < camera->target.y) && (camera->target.y <= 0)) + { + camera->target.x += GetMouseWheelMove() * (camera->target.x - camera->position.x) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance; + camera->target.y += GetMouseWheelMove() * (camera->target.y - camera->position.y) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance; + camera->target.z += GetMouseWheelMove() * (camera->target.z - camera->position.z) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance; + + if (camera->target.y > 0) camera->target.y = 0.001; + } + else if ((camera->position.y < camera->target.y) && (camera->target.y > 0) && (GetMouseWheelMove() > 0)) + { + cameraTargetDistance -= (GetMouseWheelMove() * CAMERA_SCROLL_SENSITIVITY); + if (cameraTargetDistance < FREE_CAMERA_DISTANCE_MIN_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_MIN_CLAMP; + } - // Camera distance clamp - if (cameraTargetDistance < FREE_CAMERA_DISTANCE_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_CLAMP; + // Inputs if (IsKeyDown(KEY_LEFT_ALT)) { if (IsKeyDown(KEY_LEFT_CONTROL)) diff --git a/src/models.c b/src/models.c index a8bfe37f..771d25a4 100644 --- a/src/models.c +++ b/src/models.c @@ -40,7 +40,7 @@ //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- -// Nop... +#define CUBIC_MAP_HALF_BLOCK_SIZE 0.5 //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -285,7 +285,6 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color rlPushMatrix(); rlTranslatef(centerPos.x, centerPos.y, centerPos.z); rlScalef(radius, radius, radius); - //rlRotatef(rotation, 0, 1, 0); rlBegin(RL_TRIANGLES); rlColor4ub(color.r, color.g, color.b, color.a); @@ -325,8 +324,7 @@ void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Col rlPushMatrix(); rlTranslatef(centerPos.x, centerPos.y, centerPos.z); rlScalef(radius, radius, radius); - //rlRotatef(rotation, 0, 1, 0); - + rlBegin(RL_LINES); rlColor4ub(color.r, color.g, color.b, color.a); @@ -548,6 +546,19 @@ void DrawPlaneEx(Vector3 centerPos, Vector2 size, Vector3 rotation, int slicesX, rlPopMatrix(); } +void DrawRay(Ray ray, Color color) +{ + float scale = 10000; + + rlBegin(RL_LINES); + rlColor4ub(color.r, color.g, color.b, color.a); + rlColor4ub(color.r, color.g, color.b, color.a); + + rlVertex3f(ray.position.x, ray.position.y, ray.position.z); + rlVertex3f(ray.position.x + ray.direction.x*scale, ray.position.y + ray.direction.y*scale, ray.position.z + ray.direction.z*scale); + rlEnd(); +} + // Draw a grid centered at (0, 0, 0) void DrawGrid(int slices, float spacing) { @@ -1216,26 +1227,28 @@ void SetModelTexture(Model *model, Texture2D texture) void DrawModel(Model model, Vector3 position, float scale, Color tint) { Vector3 vScale = { scale, scale, scale }; - Vector3 rotation = { 0, 0, 0 }; + float rotAngle = 0.0f; + Vector3 rotAxis = { 0, 0, 0 }; - rlglDrawModel(model, position, rotation, vScale, tint, false); + rlglDrawModel(model, position, rotAngle, rotAxis, vScale, tint, false); } // Draw a model with extended parameters -void DrawModelEx(Model model, Vector3 position, Vector3 rotation, Vector3 scale, Color tint) +void DrawModelEx(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color tint) { // NOTE: Rotation must be provided in degrees, it's converted to radians inside rlglDrawModel() - rlglDrawModel(model, position, rotation, scale, tint, false); + rlglDrawModel(model, position, rotationAngle, rotationAxis, scale, tint, false); } // Draw a model wires (with texture if set) void DrawModelWires(Model model, Vector3 position, float scale, Color color) { Vector3 vScale = { scale, scale, scale }; - Vector3 rotation = { 0, 0, 0 }; + float rotAngle = 0.0f; + Vector3 rotAxis = { 0, 0, 0 }; - rlglDrawModel(model, position, rotation, vScale, color, true); + rlglDrawModel(model, position, rotAngle, rotAxis, vScale, color, true); } // Draw a billboard @@ -1418,14 +1431,16 @@ bool CheckCollisionBoxSphere(Vector3 minBBox, Vector3 maxBBox, Vector3 centerSph // Detect and resolve cubicmap collisions // NOTE: player position (or camera) is modified inside this function -void ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition) +Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius) { // Detect the cell where the player is located + Vector3 impactDirection = { 0, 0, 0 }; + int locationCellX = 0; int locationCellY = 0; - locationCellX = floor(playerPosition->x + mapPosition.x + 0.5); - locationCellY = floor(playerPosition->z + mapPosition.z + 0.5); + locationCellX = floor(playerPosition->x + mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE); + locationCellY = floor(playerPosition->z + mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE); // Multiple Axis -------------------------------------------------------------------------------------------- @@ -1433,11 +1448,12 @@ void ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *play if ((cubicmap.pixels[locationCellY * cubicmap.width + (locationCellX - 1)].r != 0) && (cubicmap.pixels[(locationCellY - 1) * cubicmap.width + (locationCellX)].r != 0)) { - if (((playerPosition->x + 0.5f) - locationCellX < 0.3) && - ((playerPosition->z + 0.5f) - locationCellY < 0.3)) + if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) && + ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius)) { - playerPosition->x = locationCellX - 0.2; - playerPosition->z = locationCellY - 0.2; + playerPosition->x = locationCellX - (CUBIC_MAP_HALF_BLOCK_SIZE - radius); + playerPosition->z = locationCellY - (CUBIC_MAP_HALF_BLOCK_SIZE - radius); + impactDirection = (Vector3) { 1, 0, 1}; } } @@ -1445,11 +1461,12 @@ void ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *play if ((cubicmap.pixels[locationCellY * cubicmap.width + (locationCellX - 1)].r != 0) && (cubicmap.pixels[(locationCellY + 1) * cubicmap.width + (locationCellX)].r != 0)) { - if (((playerPosition->x + 0.5f) - locationCellX < 0.3) && - ((playerPosition->z + 0.5f) - locationCellY > 0.7)) + if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) && + ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius)) { - playerPosition->x = locationCellX - 0.2; - playerPosition->z = locationCellY + 0.2; + playerPosition->x = locationCellX - (CUBIC_MAP_HALF_BLOCK_SIZE - radius); + playerPosition->z = locationCellY + (CUBIC_MAP_HALF_BLOCK_SIZE - radius); + impactDirection = (Vector3) { 1, 0, 1}; } } @@ -1457,11 +1474,12 @@ void ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *play if ((cubicmap.pixels[locationCellY * cubicmap.width + (locationCellX + 1)].r != 0) && (cubicmap.pixels[(locationCellY - 1) * cubicmap.width + (locationCellX)].r != 0)) { - if (((playerPosition->x + 0.5f) - locationCellX > 0.7) && - ((playerPosition->z + 0.5f) - locationCellY < 0.3)) + if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) && + ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius)) { - playerPosition->x = locationCellX + 0.2; - playerPosition->z = locationCellY - 0.2; + playerPosition->x = locationCellX + (CUBIC_MAP_HALF_BLOCK_SIZE - radius); + playerPosition->z = locationCellY - (CUBIC_MAP_HALF_BLOCK_SIZE - radius); + impactDirection = (Vector3) { 1, 0, 1}; } } @@ -1469,11 +1487,12 @@ void ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *play if ((cubicmap.pixels[locationCellY * cubicmap.width + (locationCellX + 1)].r != 0) && (cubicmap.pixels[(locationCellY + 1) * cubicmap.width + (locationCellX)].r != 0)) { - if (((playerPosition->x + 0.5f) - locationCellX > 0.7) && - ((playerPosition->z + 0.5f) - locationCellY > 0.7)) + if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) && + ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius)) { - playerPosition->x = locationCellX + 0.2f; - playerPosition->z = locationCellY + 0.2f; + playerPosition->x = locationCellX + (CUBIC_MAP_HALF_BLOCK_SIZE - radius); + playerPosition->z = locationCellY + (CUBIC_MAP_HALF_BLOCK_SIZE - radius); + impactDirection = (Vector3) { 1, 0, 1}; } } @@ -1482,33 +1501,37 @@ void ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *play // Axis x- if (cubicmap.pixels[locationCellY * cubicmap.width + (locationCellX - 1)].r != 0) { - if ((playerPosition->x + 0.5f) - locationCellX < 0.3) + if ((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) { - playerPosition->x = locationCellX - 0.2; + playerPosition->x = locationCellX - (CUBIC_MAP_HALF_BLOCK_SIZE - radius); + impactDirection = (Vector3) { 1, 0, 0}; } } // Axis x+ if (cubicmap.pixels[locationCellY * cubicmap.width + (locationCellX + 1)].r != 0) { - if ((playerPosition->x + 0.5f) - locationCellX > 0.7) + if ((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) { - playerPosition->x = locationCellX + 0.2; + playerPosition->x = locationCellX + (CUBIC_MAP_HALF_BLOCK_SIZE - radius); + impactDirection = (Vector3) { 1, 0, 0}; } } // Axis y- if (cubicmap.pixels[(locationCellY - 1) * cubicmap.width + (locationCellX)].r != 0) { - if ((playerPosition->z + 0.5f) - locationCellY < 0.3) + if ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius) { - playerPosition->z = locationCellY - 0.2; + playerPosition->z = locationCellY - (CUBIC_MAP_HALF_BLOCK_SIZE - radius); + impactDirection = (Vector3) { 0, 0, 1}; } } // Axis y+ if (cubicmap.pixels[(locationCellY + 1) * cubicmap.width + (locationCellX)].r != 0) { - if ((playerPosition->z + 0.5f) - locationCellY > 0.7) + if ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius) { - playerPosition->z = locationCellY + 0.2; + playerPosition->z = locationCellY + (CUBIC_MAP_HALF_BLOCK_SIZE - radius); + impactDirection = (Vector3) { 0, 0, 1}; } } @@ -1519,11 +1542,18 @@ void ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *play (cubicmap.pixels[(locationCellY - 1) * cubicmap.width + (locationCellX)].r == 0) && (cubicmap.pixels[(locationCellY - 1) * cubicmap.width + (locationCellX - 1)].r != 0)) { - if (((playerPosition->x + 0.5f) - locationCellX < 0.3) && - ((playerPosition->z + 0.5f) - locationCellY < 0.3)) + if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) && + ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius)) { - if (((playerPosition->x + 0.5f) - locationCellX) > ((playerPosition->z + 0.5f) - locationCellY)) playerPosition->x = locationCellX - 0.2; - else playerPosition->z = locationCellY - 0.2; + if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX) > ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY)) playerPosition->x = locationCellX - (CUBIC_MAP_HALF_BLOCK_SIZE - radius); + else playerPosition->z = locationCellY - (CUBIC_MAP_HALF_BLOCK_SIZE - radius); + + // Return ricochet + if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius / 3) && + ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius / 3)) + { + impactDirection = (Vector3) { 1, 0, 1}; + } } } @@ -1532,11 +1562,18 @@ void ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *play (cubicmap.pixels[(locationCellY + 1) * cubicmap.width + (locationCellX)].r == 0) && (cubicmap.pixels[(locationCellY + 1) * cubicmap.width + (locationCellX - 1)].r != 0)) { - if (((playerPosition->x + 0.5f) - locationCellX < 0.3) && - ((playerPosition->z + 0.5f) - locationCellY > 0.7)) + if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) && + ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius)) { - if (((playerPosition->x + 0.5f) - locationCellX) > (1 - ((playerPosition->z + 0.5f) - locationCellY))) playerPosition->x = locationCellX - 0.2; - else playerPosition->z = locationCellY + 0.2; + if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX) > (1 - ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY))) playerPosition->x = locationCellX - (CUBIC_MAP_HALF_BLOCK_SIZE - radius); + else playerPosition->z = locationCellY + (CUBIC_MAP_HALF_BLOCK_SIZE - radius); + + // Return ricochet + if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius / 3) && + ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius / 3)) + { + impactDirection = (Vector3) { 1, 0, 1}; + } } } @@ -1545,11 +1582,18 @@ void ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *play (cubicmap.pixels[(locationCellY - 1) * cubicmap.width + (locationCellX)].r == 0) && (cubicmap.pixels[(locationCellY - 1) * cubicmap.width + (locationCellX + 1)].r != 0)) { - if (((playerPosition->x + 0.5f) - locationCellX > 0.7) && - ((playerPosition->z + 0.5f) - locationCellY < 0.3)) + if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) && + ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius)) { - if (((playerPosition->x + 0.5f) - locationCellX) < (1 - ((playerPosition->z + 0.5f) - locationCellY))) playerPosition->x = locationCellX + 0.2; - else playerPosition->z = locationCellY - 0.2; + if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX) < (1 - ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY))) playerPosition->x = locationCellX + (CUBIC_MAP_HALF_BLOCK_SIZE - radius); + else playerPosition->z = locationCellY - (CUBIC_MAP_HALF_BLOCK_SIZE - radius); + + // Return ricochet + if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius / 3) && + ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius / 3)) + { + impactDirection = (Vector3) { 1, 0, 1}; + } } } @@ -1558,13 +1602,35 @@ void ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *play (cubicmap.pixels[(locationCellY + 1) * cubicmap.width + (locationCellX)].r == 0) && (cubicmap.pixels[(locationCellY + 1) * cubicmap.width + (locationCellX + 1)].r != 0)) { - if (((playerPosition->x + 0.5f) - locationCellX > 0.7) && - ((playerPosition->z + 0.5f) - locationCellY > 0.7)) + if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) && + ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius)) { - if (((playerPosition->x + 0.5f) - locationCellX) < ((playerPosition->z + 0.5f) - locationCellY)) playerPosition->x = locationCellX + 0.2; - else playerPosition->z = locationCellY + 0.2; + if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX) < ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY)) playerPosition->x = locationCellX + (CUBIC_MAP_HALF_BLOCK_SIZE - radius); + else playerPosition->z = locationCellY + (CUBIC_MAP_HALF_BLOCK_SIZE - radius); + + // Return ricochet + if (((playerPosition->x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius / 3) && + ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius / 3)) + { + impactDirection = (Vector3) { 1, 0, 1}; + } } } + + // Floor collision + if (playerPosition->y <= radius) + { + playerPosition->y = radius + 0.01; + impactDirection = (Vector3) { impactDirection.x, 1, impactDirection.z}; + } + // Roof collision + else if (playerPosition->y >= 1.5 - radius) + { + playerPosition->y = (1.5 - radius) - 0.01; + impactDirection = (Vector3) { impactDirection.x, 1, impactDirection.z}; + } + + return impactDirection; } //---------------------------------------------------------------------------------- diff --git a/src/raylib.h b/src/raylib.h index 3b6f9320..c6c3e32a 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -294,6 +294,12 @@ typedef struct Model { //Matrix transform; } Model; +// Ray type (useful for raycast) +typedef struct Ray { + Vector3 position; + Vector3 direction; +} Ray; + // Sound source type typedef struct Sound { unsigned int source; @@ -355,7 +361,7 @@ int GetRandomValue(int min, int max); // Returns a random Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f void SetCameraMode(int mode); // Multiple camera modes available -void UpdateCamera(Vector3 *playerPosition); // Update camera with player position (when using internal camera) +Camera UpdateCamera(Vector3 *position); // Update camera with position (when using internal camera) void SetConfigFlags(char flags); // Enable some window configurations void ShowLogo(void); // Activates raylib logo at startup (can be done with flags) @@ -363,6 +369,8 @@ void ShowLogo(void); // Activates raylib void InitPostShader(void); // Initialize fullscreen postproduction shaders system void SetPostShader(unsigned int shader); // Set fullscreen postproduction shader +Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Gives the rayTrace from mouse position + //------------------------------------------------------------------------------------ // Input Handling Functions (Module: core) //------------------------------------------------------------------------------------ @@ -485,6 +493,7 @@ void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, fl void DrawQuad(Vector3 vertices[4], Vector2 textcoords[4], Vector3 normals[4], Color colors[4]); // Draw a quad void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color); // Draw a plane void DrawPlaneEx(Vector3 centerPos, Vector2 size, Vector3 rotation, int slicesX, int slicesZ, Color color); // Draw a plane with divisions +void DrawRay(Ray ray, Color color); void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0)) void DrawGizmo(Vector3 position); // Draw simple gizmo void DrawGizmoEx(Vector3 position, Vector3 rotation, float scale); // Draw gizmo with extended parameters @@ -502,7 +511,7 @@ void SetModelTexture(Model *model, Texture2D texture); void SetModelShader(Model *model, Shader shader); // Link a shader to a model (not available on OpenGL 1.1) void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) -void DrawModelEx(Model model, Vector3 position, Vector3 rotation, Vector3 scale, Color tint); // Draw a model with extended parameters +void DrawModelEx(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color tint); // Draw a model with extended parameters void DrawModelWires(Model model, Vector3 position, float scale, Color color); // Draw a model wires (with texture if set) void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture @@ -513,7 +522,7 @@ Shader LoadShader(char *vsFileName, char *fsFileName); bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); bool CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, Vector3 maxBBox2); bool CheckCollisionBoxSphere(Vector3 minBBox, Vector3 maxBBox, Vector3 centerSphere, float radiusSphere); -void ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition); +Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius); // Return the normal vector of the impacted surface //------------------------------------------------------------------------------------ // Audio Loading and Playing Functions (Module: audio) diff --git a/src/raymath.c b/src/raymath.c index df098c6a..8ad50312 100644 --- a/src/raymath.c +++ b/src/raymath.c @@ -346,8 +346,6 @@ void MatrixInvert(Matrix *mat) temp.m14 = (-a30*b03 + a31*b01 - a32*b00)*invDet; temp.m15 = (a20*b03 - a21*b01 + a22*b00)*invDet; - PrintMatrix(temp); - *mat = temp; } @@ -671,8 +669,8 @@ Matrix MatrixRotateY(float angle) { Matrix result = MatrixIdentity(); - float cosres = (float)cos(angle); - float sinres = (float)sin(angle); + float cosres = cosf(angle); + float sinres = sinf(angle); result.m0 = cosres; result.m2 = sinres; @@ -1097,4 +1095,18 @@ void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle) *outAxis = resAxis; *outAngle = resAngle; +} + +// Transform a quaternion given a transformation matrix +void QuaternionTransform(Quaternion *q, Matrix mat) +{ + float x = q->x; + float y = q->y; + float z = q->z; + float w = q->w; + + q->x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12*w; + q->y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13*w; + q->z = mat.m2*x + mat.m6*y + mat.m10*z + mat.m14*w; + q->w = mat.m3*x + mat.m7*y + mat.m11*z + mat.m15*w; } \ No newline at end of file diff --git a/src/raymath.h b/src/raymath.h index c8c1a26c..b3676ed9 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -91,7 +91,7 @@ void VectorNormalize(Vector3 *v); // Normalize provided ve float VectorDistance(Vector3 v1, Vector3 v2); // Calculate distance between two points Vector3 VectorLerp(Vector3 v1, Vector3 v2, float amount); // Calculate linear interpolation between two vectors Vector3 VectorReflect(Vector3 vector, Vector3 normal); // Calculate reflected vector to normal -void VectorTransform(Vector3 *v, Matrix mat); // Transforms a Vector3 with a given Matrix +void VectorTransform(Vector3 *v, Matrix mat); // Transforms a Vector3 by a given Matrix Vector3 VectorZero(void); // Return a Vector3 init to zero //------------------------------------------------------------------------------------ @@ -134,6 +134,7 @@ Quaternion QuaternionFromMatrix(Matrix matrix); // Returns a qua Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle); // Returns rotation quaternion for an angle around an axis Matrix QuaternionToMatrix(Quaternion q); // Calculates the matrix from the given quaternion void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle); // Returns the axis and the angle for a given quaternion +void QuaternionTransform(Quaternion *q, Matrix mat); // Transform a quaternion given a transformation matrix #ifdef __cplusplus } diff --git a/src/rlgl.c b/src/rlgl.c index 1664c5c2..7d947d66 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -303,26 +303,26 @@ void rlTranslatef(float x, float y, float z) void rlRotatef(float angleDeg, float x, float y, float z) { // TODO: Support rotation in multiple axes - Matrix rot = MatrixIdentity(); + Matrix rotation = MatrixIdentity(); // OPTION 1: It works... - if (x == 1) rot = MatrixRotateX(angleDeg*DEG2RAD); - else if (y == 1) rot = MatrixRotateY(angleDeg*DEG2RAD); - else if (z == 1) rot = MatrixRotateZ(angleDeg*DEG2RAD); + //if (x == 1) rot = MatrixRotateX(angleDeg*DEG2RAD); + //else if (y == 1) rot = MatrixRotateY(angleDeg*DEG2RAD); + //else if (z == 1) rot = MatrixRotateZ(angleDeg*DEG2RAD); // OPTION 2: Requires review... - //Vector3 vec = (Vector3){ 0, 1, 0 }; - //VectorNormalize(&vec); - //rot = MatrixFromAxisAngle(vec, angleDeg*DEG2RAD); // Working? + Vector3 axis = (Vector3){ x, y, z }; + VectorNormalize(&axis); + rotation = MatrixRotateY(angleDeg*DEG2RAD); //MatrixFromAxisAngle(axis, angleDeg*DEG2RAD); // OPTION 3: TODO: Review, it doesn't work! //Vector3 vec = (Vector3){ x, y, z }; //VectorNormalize(&vec); //rot = MatrixRotate(angleDeg*vec.x, angleDeg*vec.x, angleDeg*vec.x); - MatrixTranspose(&rot); + MatrixTranspose(&rotation); - *currentMatrix = MatrixMultiply(*currentMatrix, rot); + *currentMatrix = MatrixMultiply(*currentMatrix, rotation); } // Multiply the current matrix by a scaling matrix @@ -1206,7 +1206,7 @@ void rlglDrawPostpro(unsigned int shaderId) #endif // Draw a 3d model -void rlglDrawModel(Model model, Vector3 position, Vector3 rotation, Vector3 scale, Color color, bool wires) +void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color color, bool wires) { #if defined (GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) // NOTE: glPolygonMode() not available on OpenGL ES @@ -1215,7 +1215,7 @@ void rlglDrawModel(Model model, Vector3 position, Vector3 rotation, Vector3 scal #if defined(GRAPHICS_API_OPENGL_11) glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, model.textureId); + glBindTexture(GL_TEXTURE_2D, model.texture.id); // NOTE: On OpenGL 1.1 we use Vertex Arrays to draw model glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex array @@ -1230,7 +1230,7 @@ void rlglDrawModel(Model model, Vector3 position, Vector3 rotation, Vector3 scal rlPushMatrix(); rlTranslatef(position.x, position.y, position.z); rlScalef(scale.x, scale.y, scale.z); - rlRotatef(rotation.y, 0, 1, 0); + rlRotatef(rotationAngle, rotationAxis.x, rotationAxis.y, rotationAxis.z); // TODO: If rotate in multiple axis, get rotation matrix and use rlMultMatrix() @@ -1250,7 +1250,7 @@ void rlglDrawModel(Model model, Vector3 position, Vector3 rotation, Vector3 scal #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) glUseProgram(model.shader.id); - VectorScale(&rotation, DEG2RAD); + Vector3 rotation = { 0.0f, 0.0f, 0.0f }; // Get transform matrix (rotation -> scale -> translation) Matrix transform = MatrixTransform(position, rotation, scale); // Object-space transformation @@ -1335,7 +1335,7 @@ void rlglInitGraphics(int offsetX, int offsetY, int width, int height) rlMatrixMode(RL_PROJECTION); // Switch to PROJECTION matrix rlLoadIdentity(); // Reset current matrix (PROJECTION) - rlOrtho(0, width - offsetX, height - offsetY, 0, 0, 1); // Config orthographic mode: top-left corner --> (0,0) + rlOrtho(0, width - offsetX, height - offsetY, 0, 0, 1); // Config orthographic mode: top-left corner --> (0,0) rlMatrixMode(RL_MODELVIEW); // Switch back to MODELVIEW matrix rlLoadIdentity(); // Reset current matrix (MODELVIEW) @@ -1355,6 +1355,165 @@ void rlglInitGraphics(int offsetX, int offsetY, int width, int height) TraceLog(INFO, "OpenGL Graphics initialized successfully"); } +// Get world coordinates from screen coordinates +Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view) +{ + //GLint viewport[4]; + //glGetIntegerv(GL_VIEWPORT, viewport); + + // Viewport data + int x = 0; + int y = 0; + int width = GetScreenWidth(); + int height = GetScreenHeight(); + float minDepth = 0.0f; + float maxDepth = 1.0f; +/* + Matrix modelviewprojection = MatrixMultiply(modelview, projection); + MatrixInvert(&modelviewprojection); + + Vector3 vector; + + vector.x = (((source.x - x) / ((float)width)) * 2.0f) - 1.0f; + vector.y = -((((source.y - y) / ((float)height)) * 2.0f) - 1.0f); + vector.z = (source.z - minDepth) / (maxDepth - minDepth); + + //float a = (((vector.x * matrix.M14) + (vector.y * matrix.M24)) + (vector.z * matrix.M34)) + matrix.M44; + //float a = (((vector.x * modelviewprojection.m3) + (vector.y * modelviewprojection.m7)) + (vector.z * modelviewprojection.m11)) + modelviewprojection.m15; + VectorTransform(&vector, modelviewprojection); + + //if (!MathUtil.IsOne(a)) vector = (vector / a); + //VectorScale(&vector, 1/a); + + return vector; +*/ +/* + Vector3 worldPoint; + + // Transformation matrices + Matrix modelviewprojection = MatrixIdentity(); + Quaternion quat; + + // Calculation for inverting a matrix, compute projection x modelview + modelviewprojection = MatrixMultiply(proj, view); + MatrixInvert(&modelviewprojection); + + // Transformation of normalized coordinates between -1 and 1 + quat.x = ((source.x - (float)x)/(float)width*2.0) - 1.0f; + quat.y = ((source.y - (float)y)/(float)height*2.0) - 1.0f; + quat.z = 2.0*source.z - 1.0; + quat.w = 1.0; + + // Objects coordinates + QuaternionTransform(&quat, modelviewprojection); + + //if (quat.w == 0.0) return 0; + + worldPoint.x = quat.x/quat.w; + worldPoint.y = quat.y/quat.w; + worldPoint.z = quat.z/quat.w; + + return worldPoint; + */ +/* + Quaternion quat; + Vector3 vec; + + quat.x = 2.0f * GetMousePosition().x / (float)width - 1; + quat.y = -(2.0f * GetMousePosition().y / (float)height - 1); + quat.z = 0; + quat.w = 1; + + Matrix invView; + MatrixInvert(&view); + Matrix invProj; + MatrixInvert(&proj); + + quat.x = invProj.m0 * quat.x + invProj.m4 * quat.y + invProj.m8 * quat.z + invProj.m12 * quat.w; + quat.y = invProj.m1 * quat.x + invProj.m5 * quat.y + invProj.m9 * quat.z + invProj.m13 * quat.w; + quat.z = invProj.m2 * quat.x + invProj.m6 * quat.y + invProj.m10 * quat.z + invProj.m14 * quat.w; + quat.w = invProj.m3 * quat.x + invProj.m7 * quat.y + invProj.m11 * quat.z + invProj.m15 * quat.w; + + quat.x = invView.m0 * quat.x + invView.m4 * quat.y + invView.m8 * quat.z + invView.m12 * quat.w; + quat.y = invView.m1 * quat.x + invView.m5 * quat.y + invView.m9 * quat.z + invView.m13 * quat.w; + quat.z = invView.m2 * quat.x + invView.m6 * quat.y + invView.m10 * quat.z + invView.m14 * quat.w; + quat.w = invView.m3 * quat.x + invView.m7 * quat.y + invView.m11 * quat.z + invView.m15 * quat.w; + + vec.x /= quat.w; + vec.y /= quat.w; + vec.z /= quat.w; + + return vec; + */ +/* + Vector3 worldPoint; + + // Transformation matrices + Matrix modelviewprojection; + Quaternion quat; + + // Calculation for inverting a matrix, compute projection x modelview + modelviewprojection = MatrixMultiply(view, proj); + + // Now compute the inverse of matrix A + MatrixInvert(&modelviewprojection); + + // Transformation of normalized coordinates between -1 and 1 + quat.x = ((source.x - (float)x)/(float)width*2.0) - 1.0f; + quat.y = ((source.y - (float)y)/(float)height*2.0) - 1.0f; + quat.z = 2.0*source.z - 1.0; + quat.w = 1.0; + + // Traspose quaternion and multiply + Quaternion result; + result.x = modelviewprojection.m0 * quad.x + modelviewprojection.m4 * quad.y + modelviewprojection.m8 * quad.z + modelviewprojection.m12 * quad.w; + result.y = modelviewprojection.m1 * quad.x + modelviewprojection.m5 * quad.y + modelviewprojection.m9 * quad.z + modelviewprojection.m13 * quad.w; + result.z = modelviewprojection.m2 * quad.x + modelviewprojection.m6 * quad.y + modelviewprojection.m10 * quad.z + modelviewprojection.m14 * quad.w; + result.w = modelviewprojection.m3 * quad.x + modelviewprojection.m7 * quad.y + modelviewprojection.m11 * quad.z + modelviewprojection.m15 * quad.w; + + // Invert + result.w = 1.0f / result.w; + + //if (quat.w == 0.0) return 0; + + worldPoint.x = quat.x * quat.w; + worldPoint.y = quat.y * quat.w; + worldPoint.z = quat.z * quat.w; + + return worldPoint; + */ +/* + // Needed Vectors + Vector3 normalDeviceCoordinates; + Quaternion rayClip; + Quaternion rayEye; + Vector3 rayWorld; + + // Getting normal device coordinates + float x = (2.0 * mousePosition.x) / GetScreenWidth() - 1.0; + float y = 1.0 - (2.0 * mousePosition.y) / GetScreenHeight(); + float z = 1.0; + normalDeviceCoordinates = (Vector3){ x, y, z }; + + // Getting clip vector + rayClip = (Quaternion){ normalDeviceCoordinates.x, normalDeviceCoordinates.y, -1, 1 }; + + Matrix invProjection = projection; + MatrixInvert(&invProjection); + + rayEye = MatrixQuaternionMultiply(invProjection, rayClip); + rayEye = (Quaternion){ rayEye.x, rayEye.y, -1, 0 }; + + Matrix invModelview = modelview; + MatrixInvert(&invModelview); + + rayWorld = MatrixVector3Multiply(invModelview, (Vector3){rayEye.x, rayEye.y, rayEye.z} ); + VectorNormalize(&rayWorld); + + return rayWorld; +*/ +} + // Convert image data to OpenGL texture (returns OpenGL valid Id) unsigned int rlglLoadTexture(unsigned char *data, int width, int height, int colorMode, bool genMipmaps) { @@ -2352,7 +2511,6 @@ static pixel *GenNextMipmap(pixel *srcData, int srcWidth, int srcHeight) return mipmap; } - #endif #if defined(RLGL_STANDALONE) diff --git a/src/rlgl.h b/src/rlgl.h index ff2bcd4e..e277b250 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -192,6 +192,7 @@ void rlglClose(void); // De-init rlgl void rlglDraw(void); // Draw VAO/VBO void rlglDrawPostpro(unsigned int shaderId); // Draw with postpro shader void rlglInitGraphics(int offsetX, int offsetY, int width, int height); // Initialize Graphics (OpenGL stuff) +Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view); // Get world coordinates from screen coordinates unsigned int rlglLoadTexture(unsigned char *data, int width, int height, int colorMode, bool genMipmaps); // Load in GPU OpenGL texture unsigned int rlglLoadCompressedTexture(unsigned char *data, int width, int height, int mipmapCount, int format); @@ -200,7 +201,7 @@ unsigned int rlglLoadShader(char *vShaderStr, char *fShaderStr); // Load a shade #endif Model rlglLoadModel(VertexData mesh); // Upload vertex data into GPU and provided VAO/VBO ids -void rlglDrawModel(Model model, Vector3 position, Vector3 rotation, Vector3 scale, Color color, bool wires); +void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color color, bool wires); byte *rlglReadScreenPixels(int width, int height); // Read screen pixel data (color buffer)