Simplified MatrixMultiply() function
This commit is contained in:
parent
1ce010c7d4
commit
7f2e67e924
109
src/core.c
109
src/core.c
@ -122,8 +122,8 @@ static int ident, events;
|
||||
static bool windowReady = false; // Used to detect display initialization
|
||||
static bool appEnabled = true; // Used to detec if app is active
|
||||
static bool contextRebindRequired = false; // Used to know context rebind required
|
||||
static int previousButtonState[512] = { 1 }; // Required to check if button pressed/released once
|
||||
static int currentButtonState[512] = { 1 }; // Required to check if button pressed/released once
|
||||
static int previousButtonState[128] = { 1 }; // Required to check if button pressed/released once
|
||||
static int currentButtonState[128] = { 1 }; // Required to check if button pressed/released once
|
||||
#elif defined(PLATFORM_RPI)
|
||||
static EGL_DISPMANX_WINDOW_T nativeWindow; // Native window (graphic device)
|
||||
|
||||
@ -272,7 +272,7 @@ static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent
|
||||
// Initialize Window and Graphics Context (OpenGL)
|
||||
void InitWindow(int width, int height, const char *title)
|
||||
{
|
||||
TraceLog(INFO, "Initializing raylib (v1.3.0)");
|
||||
TraceLog(INFO, "Initializing raylib (v1.4.0)");
|
||||
|
||||
// Store window title (could be useful...)
|
||||
windowTitle = title;
|
||||
@ -324,7 +324,7 @@ void InitWindow(int width, int height, const char *title)
|
||||
// Android activity initialization
|
||||
void InitWindow(int width, int height, struct android_app *state)
|
||||
{
|
||||
TraceLog(INFO, "Initializing raylib (v1.3.0)");
|
||||
TraceLog(INFO, "Initializing raylib (v1.4.0)");
|
||||
|
||||
app_dummy();
|
||||
|
||||
@ -368,7 +368,7 @@ void InitWindow(int width, int height, struct android_app *state)
|
||||
TraceLog(INFO, "Android app initialized successfully");
|
||||
|
||||
// Init button states values (default up)
|
||||
for(int i = 0; i < 512; i++)
|
||||
for(int i = 0; i < 128; i++)
|
||||
{
|
||||
currentButtonState[i] = 1;
|
||||
previousButtonState[i] = 1;
|
||||
@ -587,8 +587,8 @@ void Begin3dMode(Camera camera)
|
||||
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
|
||||
|
||||
// Setup Camera view
|
||||
Matrix view = MatrixLookAt(camera.position, camera.target, camera.up);
|
||||
rlMultMatrixf(GetMatrixVector(view)); // Multiply MODELVIEW matrix by view matrix (camera)
|
||||
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
|
||||
rlMultMatrixf(GetMatrixVector(matView)); // Multiply MODELVIEW matrix by view matrix (camera)
|
||||
}
|
||||
|
||||
// Ends 3D mode and returns to default 2D orthographic mode
|
||||
@ -778,42 +778,78 @@ int StorageLoadValue(int position)
|
||||
return value;
|
||||
}
|
||||
|
||||
// TODO: Gives the ray trace from mouse position
|
||||
// Gives the ray trace from mouse position
|
||||
// TODO: DOESN'T WORK! :(
|
||||
//http://www.songho.ca/opengl/gl_transform.html
|
||||
//http://www.songho.ca/opengl/gl_matrix.html
|
||||
//http://www.sjbaker.org/steve/omniv/matrices_can_be_your_friends.html
|
||||
//https://www.opengl.org/archives/resources/faq/technical/transformations.htm
|
||||
Ray GetMouseRay(Vector2 mousePosition, Camera camera)
|
||||
{
|
||||
Ray ray;
|
||||
|
||||
Matrix matProj = MatrixIdentity();
|
||||
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
|
||||
|
||||
// Calculate projection matrix for the camera
|
||||
|
||||
// Calculate projection matrix
|
||||
float aspect = (float)GetScreenWidth()/(float)GetScreenHeight();
|
||||
double top = 0.1f*tanf(45.0f*PI/360.0f);
|
||||
double right = top*aspect;
|
||||
|
||||
// NOTE: zNear and zFar values are important for depth
|
||||
matProj = MatrixFrustum(-right, right, -top, top, 0.01f, 1000.0f);
|
||||
MatrixTranspose(&matProj);
|
||||
Matrix matProjection = MatrixFrustum(-right, right, -top, top, 0.01f, 1000.0f);
|
||||
|
||||
// Calculate view matrix (camera)
|
||||
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
|
||||
|
||||
// Tutorial used: http://antongerdelan.net/opengl/raycasting.html
|
||||
|
||||
// Step 0: We got mouse coordinates in viewport-space [0:screenWidth, 0:screenHeight]
|
||||
// NOTE: That that 0 is at the top of the screen here, so the y-axis direction is opposed to that in other coordinate systems
|
||||
|
||||
// Step 1: 3d Normalised Device Coordinates [-1:1, -1:1, -1:1]
|
||||
// Transform mousePosition into 3d normalised device coordinates.
|
||||
// We have an x and y already, so we scale their range, and reverse the direction of y.
|
||||
float x = (2.0f*mousePosition.x)/(float)screenWidth - 1.0f;
|
||||
float y = 1.0f - (2.0f*mousePosition.x)/(float)screenHeight;
|
||||
float z = 1.0f;
|
||||
Vector3 rayDevice = { x, y, z };
|
||||
|
||||
// Step 2: 4d Homogeneous Clip Coordinates [-1:1, -1:1, -1:1, -1:1]
|
||||
// We want our ray's z to point forwards - this is usually the negative z direction in OpenGL style.
|
||||
// We can add a w, just so that we have a 4d vector.
|
||||
//vec4 ray_clip = vec4 (ray_nds.xy, -1.0, 1.0);
|
||||
Quaternion rayClip = { rayDevice.x, rayDevice.y , -1.0f, 1.0f };
|
||||
|
||||
// Step 3: 4d Eye (Camera) Coordinates [-x:x, -y:y, -z:z, -w:w]
|
||||
// To get into clip space from eye space we multiply the vector by a projection matrix.
|
||||
// We can go backwards by multiplying by the inverse of this matrix.
|
||||
//vec4 ray_eye = MatrixInverse(matProjection) * ray_clip;
|
||||
Quaternion rayEye = rayClip;
|
||||
MatrixInvert(&matProjection);
|
||||
QuaternionTransform(&rayEye, matProjection);
|
||||
|
||||
// We only needed to un-project the x,y part, so let's manually set the z,w part to mean "forwards, and not a point".
|
||||
//ray_eye = vec4(ray_eye.xy, -1.0, 0.0);
|
||||
rayEye.z = -1.0f;
|
||||
rayEye.w = 0.0f;
|
||||
|
||||
// Step 4: 4d World Coordinates [-x:x, -y:y, -z:z, -w:w]
|
||||
// Go back another step in the transformation pipeline. Remember that we manually specified a -1 for the z component,
|
||||
// which means that our ray isn't normalised. We should do this before we use it
|
||||
//Vector3 rayWorld = (MatrixInverse(matView) * ray_eye).xyz;
|
||||
MatrixInvert(&matView);
|
||||
QuaternionTransform(&rayEye, matView);
|
||||
Vector3 rayWorld = { rayEye.x, rayEye.y, rayEye.z };
|
||||
|
||||
// NOTE: Our screen origin is top-left instead of bottom-left: transform required!
|
||||
float invertedMouseY = (float)GetScreenHeight() - mousePosition.y;
|
||||
|
||||
// NOTE: Do I really need to get z value from depth buffer?
|
||||
//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, invertedMouseY, 0.0f };
|
||||
Vector3 farPoint = { mousePosition.x, invertedMouseY, 1.0f };
|
||||
|
||||
nearPoint = rlglUnproject(nearPoint, matProj, matView);
|
||||
farPoint = rlglUnproject(farPoint, matProj, matView); // TODO: it seems it doesn't work...
|
||||
|
||||
Vector3 direction = VectorSubtract(farPoint, nearPoint);
|
||||
VectorNormalize(&direction);
|
||||
|
||||
ray.position = nearPoint;
|
||||
ray.direction = direction;
|
||||
VectorNormalize(&rayWorld);
|
||||
|
||||
// Assuming our camera is looking directly along the -Z world axis,
|
||||
// we should get [0,0,-1] when the mouse is in the centre of the screen,
|
||||
// and less significant z values when the mouse moves around the screen.
|
||||
|
||||
ray.position = camera.position;
|
||||
ray.direction = rayWorld;
|
||||
|
||||
TraceLog(INFO, "ray.position -> (%f, %f, %f)", ray.position.x, ray.position.y, ray.position.z);
|
||||
TraceLog(INFO, "ray.direction -> (%f, %f, %f)", ray.direction.x, ray.direction.y, ray.direction.z);
|
||||
|
||||
return ray;
|
||||
}
|
||||
@ -1688,7 +1724,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
||||
//int32_t AKeyEvent_getMetaState(event);
|
||||
|
||||
// Save current button and its state
|
||||
currentButtonState[keycode] = AKeyEvent_getAction (event); // Down = 0, Up = 1
|
||||
currentButtonState[keycode] = AKeyEvent_getAction(event); // Down = 0, Up = 1
|
||||
|
||||
if (keycode == AKEYCODE_POWER)
|
||||
{
|
||||
@ -1826,7 +1862,6 @@ static void PollInputEvents(void)
|
||||
|
||||
// TODO: Remove this requirement...
|
||||
UpdateGestures();
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
@ -1856,7 +1891,7 @@ static void PollInputEvents(void)
|
||||
#elif defined(PLATFORM_ANDROID)
|
||||
|
||||
// Register previous keys states
|
||||
for (int i = 0; i < 512; i++) previousButtonState[i] = currentButtonState[i];
|
||||
for (int i = 0; i < 128; i++) previousButtonState[i] = currentButtonState[i];
|
||||
|
||||
// Poll Events (registered events)
|
||||
// NOTE: Activity is paused if not enabled (appEnabled)
|
||||
|
@ -226,6 +226,8 @@ Vector3 VectorZero(void)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Returns an OpenGL-ready vector (glMultMatrixf)
|
||||
// NOTE: Returned vector is row-major instead column-major as expected,
|
||||
// it means, returned vector is a transposed version of the matrix!
|
||||
float *GetMatrixVector(Matrix mat)
|
||||
{
|
||||
static float vector[16];
|
||||
@ -598,33 +600,22 @@ Matrix MatrixMultiply(Matrix left, Matrix right)
|
||||
{
|
||||
Matrix result;
|
||||
|
||||
// Cache the matrix values (speed optimization)
|
||||
float a00 = left.m0, a01 = left.m1, a02 = left.m2, a03 = left.m3;
|
||||
float a10 = left.m4, a11 = left.m5, a12 = left.m6, a13 = left.m7;
|
||||
float a20 = left.m8, a21 = left.m9, a22 = left.m10, a23 = left.m11;
|
||||
float a30 = left.m12, a31 = left.m13, a32 = left.m14, a33 = left.m15;
|
||||
|
||||
float b00 = right.m0, b01 = right.m1, b02 = right.m2, b03 = right.m3;
|
||||
float b10 = right.m4, b11 = right.m5, b12 = right.m6, b13 = right.m7;
|
||||
float b20 = right.m8, b21 = right.m9, b22 = right.m10, b23 = right.m11;
|
||||
float b30 = right.m12, b31 = right.m13, b32 = right.m14, b33 = right.m15;
|
||||
|
||||
result.m0 = b00*a00 + b01*a10 + b02*a20 + b03*a30;
|
||||
result.m1 = b00*a01 + b01*a11 + b02*a21 + b03*a31;
|
||||
result.m2 = b00*a02 + b01*a12 + b02*a22 + b03*a32;
|
||||
result.m3 = b00*a03 + b01*a13 + b02*a23 + b03*a33;
|
||||
result.m4 = b10*a00 + b11*a10 + b12*a20 + b13*a30;
|
||||
result.m5 = b10*a01 + b11*a11 + b12*a21 + b13*a31;
|
||||
result.m6 = b10*a02 + b11*a12 + b12*a22 + b13*a32;
|
||||
result.m7 = b10*a03 + b11*a13 + b12*a23 + b13*a33;
|
||||
result.m8 = b20*a00 + b21*a10 + b22*a20 + b23*a30;
|
||||
result.m9 = b20*a01 + b21*a11 + b22*a21 + b23*a31;
|
||||
result.m10 = b20*a02 + b21*a12 + b22*a22 + b23*a32;
|
||||
result.m11 = b20*a03 + b21*a13 + b22*a23 + b23*a33;
|
||||
result.m12 = b30*a00 + b31*a10 + b32*a20 + b33*a30;
|
||||
result.m13 = b30*a01 + b31*a11 + b32*a21 + b33*a31;
|
||||
result.m14 = b30*a02 + b31*a12 + b32*a22 + b33*a32;
|
||||
result.m15 = b30*a03 + b31*a13 + b32*a23 + b33*a33;
|
||||
result.m0 = right.m0*left.m0 + right.m1*left.m4 + right.m2*left.m8 + right.m3*left.m12;
|
||||
result.m1 = right.m0*left.m1 + right.m1*left.m5 + right.m2*left.m9 + right.m3*left.m13;
|
||||
result.m2 = right.m0*left.m2 + right.m1*left.m6 + right.m2*left.m10 + right.m3*left.m14;
|
||||
result.m3 = right.m0*left.m3 + right.m1*left.m7 + right.m2*left.m11 + right.m3*left.m15;
|
||||
result.m4 = right.m4*left.m0 + right.m5*left.m4 + right.m6*left.m8 + right.m7*left.m12;
|
||||
result.m5 = right.m4*left.m1 + right.m5*left.m5 + right.m6*left.m9 + right.m7*left.m13;
|
||||
result.m6 = right.m4*left.m2 + right.m5*left.m6 + right.m6*left.m10 + right.m7*left.m14;
|
||||
result.m7 = right.m4*left.m3 + right.m5*left.m7 + right.m6*left.m11 + right.m7*left.m15;
|
||||
result.m8 = right.m8*left.m0 + right.m9*left.m4 + right.m10*left.m8 + right.m11*left.m12;
|
||||
result.m9 = right.m8*left.m1 + right.m9*left.m5 + right.m10*left.m9 + right.m11*left.m13;
|
||||
result.m10 = right.m8*left.m2 + right.m9*left.m6 + right.m10*left.m10 + right.m11*left.m14;
|
||||
result.m11 = right.m8*left.m3 + right.m9*left.m7 + right.m10*left.m11 + right.m11*left.m15;
|
||||
result.m12 = right.m12*left.m0 + right.m13*left.m4 + right.m14*left.m8 + right.m15*left.m12;
|
||||
result.m13 = right.m12*left.m1 + right.m13*left.m5 + right.m14*left.m9 + right.m15*left.m13;
|
||||
result.m14 = right.m12*left.m2 + right.m13*left.m6 + right.m14*left.m10 + right.m15*left.m14;
|
||||
result.m15 = right.m12*left.m3 + right.m13*left.m7 + right.m14*left.m11 + right.m15*left.m15;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
42
src/rlgl.c
42
src/rlgl.c
@ -1500,28 +1500,34 @@ void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 r
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
glUseProgram(model.shader.id);
|
||||
|
||||
// Apply transformation provided in model.transform matrix
|
||||
// TODO: review if at this point the modelview matrix just contains view matrix values
|
||||
Matrix viewworld = modelview; // Store view matrix before applying model transformations
|
||||
Matrix modelviewworld = MatrixMultiply(model.transform, modelview); // World-space transformation
|
||||
|
||||
// Apply transformations provided in function
|
||||
|
||||
// At this point the modelview matrix just contains the view matrix (camera)
|
||||
// That's because Begin3dMode() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix()
|
||||
Matrix matView = modelview; // View matrix (camera)
|
||||
Matrix matProjection = projection; // Projection matrix (perspective)
|
||||
|
||||
// Calculate transformation matrix from function parameters
|
||||
// Get transform matrix (rotation -> scale -> translation)
|
||||
Matrix rotation = MatrixRotate(rotationAngle*DEG2RAD, rotationAxis);
|
||||
Matrix matRotation = MatrixRotate(rotationAngle*DEG2RAD, rotationAxis);
|
||||
Matrix matScale = MatrixScale(scale.x, scale.y, scale.z);
|
||||
Matrix translation = MatrixTranslate(position.x, position.y, position.z);
|
||||
Matrix matTranslation = MatrixTranslate(position.x, position.y, position.z);
|
||||
Matrix matTransform = MatrixMultiply(MatrixMultiply(matRotation, matScale), matTranslation);
|
||||
|
||||
// Combine model internal transformation matrix (model.transform) with matrix generated by function parameters (matTransform)
|
||||
Matrix matModel = MatrixMultiply(model.transform, matTransform); // Transform to world-space coordinates
|
||||
|
||||
// Calculate model-view matrix combining matModel and matView
|
||||
Matrix matModelView = MatrixMultiply(matModel, matView); // Transform to camera-space coordinates
|
||||
|
||||
Matrix transform = MatrixMultiply(MatrixMultiply(rotation, matScale), translation); // Object-space transformation matrix
|
||||
modelviewworld = MatrixMultiply(transform, modelview); // World-space transformation
|
||||
// Calculate model-view-projection matrix (MVP)
|
||||
//Matrix matMVP = MatrixMultiply(matModelView, matProjection); // Transform to screen-space coordinates
|
||||
|
||||
// Projection: Screen-space transformation
|
||||
|
||||
// NOTE: Drawing in OpenGL 3.3+, transform is passed to shader
|
||||
glUniformMatrix4fv(model.shader.projectionLoc, 1, false, GetMatrixVector(projection));
|
||||
glUniformMatrix4fv(model.shader.modelLoc, 1, false, GetMatrixVector(transform));
|
||||
glUniformMatrix4fv(model.shader.viewLoc, 1, false, GetMatrixVector(viewworld));
|
||||
glUniformMatrix4fv(model.shader.modelviewLoc, 1, false, GetMatrixVector(modelviewworld));
|
||||
// NOTE: Drawing in OpenGL 3.3+, matrices are passed to shader
|
||||
// TODO: Reduce number of matrices passed to shaders, use only matMVP
|
||||
glUniformMatrix4fv(model.shader.modelLoc, 1, false, GetMatrixVector(matModel));
|
||||
glUniformMatrix4fv(model.shader.viewLoc, 1, false, GetMatrixVector(matView));
|
||||
glUniformMatrix4fv(model.shader.projectionLoc, 1, false, GetMatrixVector(matProjection));
|
||||
glUniformMatrix4fv(model.shader.modelviewLoc, 1, false, GetMatrixVector(matModelView));
|
||||
|
||||
// Apply color tinting to model
|
||||
// NOTE: Just update one uniform on fragment shader
|
||||
|
Loading…
x
Reference in New Issue
Block a user