diff options
| author | jussi | 2023-05-10 21:21:40 +0300 |
|---|---|---|
| committer | jussi | 2023-05-10 21:21:40 +0300 |
| commit | b387742850a4d2d6b750f7cdc878ff00d7e4a5fb (patch) | |
| tree | 585ab2374c0c1821f85e0c1340ff44d6dd0fea5c /src/models.c | |
| parent | 1e58f551bbfb6a8ef4d83292685d7c3672385c8b (diff) | |
| download | reilua-enhanced-b387742850a4d2d6b750f7cdc878ff00d7e4a5fb.tar.gz reilua-enhanced-b387742850a4d2d6b750f7cdc878ff00d7e4a5fb.tar.bz2 reilua-enhanced-b387742850a4d2d6b750f7cdc878ff00d7e4a5fb.zip | |
DrawBillboardPro and rlglGetVersion.
Diffstat (limited to 'src/models.c')
| -rw-r--r-- | src/models.c | 136 |
1 files changed, 135 insertions, 1 deletions
diff --git a/src/models.c b/src/models.c index 3f69001..26e7e72 100644 --- a/src/models.c +++ b/src/models.c @@ -182,6 +182,102 @@ void UnloadModelKeepMeshes( Model model ) { TRACELOG(LOG_INFO, "MODEL: Unloaded model (but not meshes) from RAM and VRAM"); } +void DrawBillboardProNoRatio( Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint ) { + // NOTE: Billboard size will maintain source rectangle aspect ratio, size will represent billboard width + // Vector2 sizeRatio = { size.x*(float)source.width/source.height, size.y }; + Vector2 sizeRatio = { size.x, size.y }; + + Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up); + + Vector3 right = { matView.m0, matView.m4, matView.m8 }; + //Vector3 up = { matView.m1, matView.m5, matView.m9 }; + + Vector3 rightScaled = Vector3Scale(right, sizeRatio.x/2); + Vector3 upScaled = Vector3Scale(up, sizeRatio.y/2); + + Vector3 p1 = Vector3Add(rightScaled, upScaled); + Vector3 p2 = Vector3Subtract(rightScaled, upScaled); + + Vector3 topLeft = Vector3Scale(p2, -1); + Vector3 topRight = p1; + Vector3 bottomRight = p2; + Vector3 bottomLeft = Vector3Scale(p1, -1); + + if (rotation != 0.0f) + { + float sinRotation = sinf(rotation*DEG2RAD); + float cosRotation = cosf(rotation*DEG2RAD); + + // NOTE: (-1, 1) is the range where origin.x, origin.y is inside the texture + float rotateAboutX = sizeRatio.x*origin.x/2; + float rotateAboutY = sizeRatio.y*origin.y/2; + + float xtvalue, ytvalue; + float rotatedX, rotatedY; + + xtvalue = Vector3DotProduct(right, topLeft) - rotateAboutX; // Project points to x and y coordinates on the billboard plane + ytvalue = Vector3DotProduct(up, topLeft) - rotateAboutY; + rotatedX = xtvalue*cosRotation - ytvalue*sinRotation + rotateAboutX; // Rotate about the point origin + rotatedY = xtvalue*sinRotation + ytvalue*cosRotation + rotateAboutY; + topLeft = Vector3Add(Vector3Scale(up, rotatedY), Vector3Scale(right, rotatedX)); // Translate back to cartesian coordinates + + xtvalue = Vector3DotProduct(right, topRight) - rotateAboutX; + ytvalue = Vector3DotProduct(up, topRight) - rotateAboutY; + rotatedX = xtvalue*cosRotation - ytvalue*sinRotation + rotateAboutX; + rotatedY = xtvalue*sinRotation + ytvalue*cosRotation + rotateAboutY; + topRight = Vector3Add(Vector3Scale(up, rotatedY), Vector3Scale(right, rotatedX)); + + xtvalue = Vector3DotProduct(right, bottomRight) - rotateAboutX; + ytvalue = Vector3DotProduct(up, bottomRight) - rotateAboutY; + rotatedX = xtvalue*cosRotation - ytvalue*sinRotation + rotateAboutX; + rotatedY = xtvalue*sinRotation + ytvalue*cosRotation + rotateAboutY; + bottomRight = Vector3Add(Vector3Scale(up, rotatedY), Vector3Scale(right, rotatedX)); + + xtvalue = Vector3DotProduct(right, bottomLeft)-rotateAboutX; + ytvalue = Vector3DotProduct(up, bottomLeft)-rotateAboutY; + rotatedX = xtvalue*cosRotation - ytvalue*sinRotation + rotateAboutX; + rotatedY = xtvalue*sinRotation + ytvalue*cosRotation + rotateAboutY; + bottomLeft = Vector3Add(Vector3Scale(up, rotatedY), Vector3Scale(right, rotatedX)); + } + + // Translate points to the draw center (position) + topLeft = Vector3Add(topLeft, position); + topRight = Vector3Add(topRight, position); + bottomRight = Vector3Add(bottomRight, position); + bottomLeft = Vector3Add(bottomLeft, position); + + rlSetTexture(texture.id); + + rlBegin(RL_QUADS); + rlColor4ub(tint.r, tint.g, tint.b, tint.a); + + // Bottom-left corner for texture and quad + rlTexCoord2f((float)source.x/texture.width, (float)source.y/texture.height); + rlVertex3f(topLeft.x, topLeft.y, topLeft.z); + + // Top-left corner for texture and quad + rlTexCoord2f((float)source.x/texture.width, (float)(source.y + source.height)/texture.height); + rlVertex3f(bottomLeft.x, bottomLeft.y, bottomLeft.z); + + // Top-right corner for texture and quad + rlTexCoord2f((float)(source.x + source.width)/texture.width, (float)(source.y + source.height)/texture.height); + rlVertex3f(bottomRight.x, bottomRight.y, bottomRight.z); + + // Bottom-right corner for texture and quad + rlTexCoord2f((float)(source.x + source.width)/texture.width, (float)source.y/texture.height); + rlVertex3f(topRight.x, topRight.y, topRight.z); + rlEnd(); + + rlSetTexture(0); +} + +void DrawBillboardRecNoRatio( Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint ) { + // NOTE: Billboard locked on axis-Y + Vector3 up = { 0.0f, 1.0f, 0.0f }; + + DrawBillboardProNoRatio(camera, texture, source, position, up, size, Vector2Zero(), 0.0f, tint); +} + /* ## Models - Basic */ @@ -2049,7 +2145,45 @@ int lmodelsDrawBillboardRec( lua_State *L ) { lua_pushboolean( L, false ); return 1; } - DrawBillboardRec( *state->camera3Ds[ cameraId ], *texturesGetSourceTexture( texId ), source, position, size, tint ); + // DrawBillboardRec( *state->camera3Ds[ cameraId ], *texturesGetSourceTexture( texId ), source, position, size, tint ); + DrawBillboardRecNoRatio( *state->camera3Ds[ cameraId ], *texturesGetSourceTexture( texId ), source, position, size, tint ); + lua_pushboolean( L, true ); + + return 1; +} + +/* +> success = RL.DrawBillboardPro( Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint ) + +Draw a billboard texture defined by source and rotation + +- Failure return false +- Success return true +*/ +int lmodelsDrawBillboardPro( lua_State *L ) { + if ( !lua_isnumber( L, 1 ) || !lua_isnumber( L, 2 ) || !lua_istable( L, 3 ) + || !lua_istable( L, 4 ) || !lua_istable( L, 5 ) || !lua_istable( L, 6 ) + || !lua_istable( L, 7 ) || !lua_isnumber( L, 8 ) || !lua_istable( L, 9 ) ) { + TraceLog( LOG_WARNING, "%s", "Bad call of function. RL.DrawBillboardPro( Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint )" ); + lua_pushboolean( L, false ); + return 1; + } + size_t cameraId = lua_tointeger( L, 1 ); + size_t texId = lua_tointeger( L, 2 ); + Rectangle source = uluaGetRectangleIndex( L, 3 ); + Vector3 position = uluaGetVector3Index( L, 4 ); + Vector3 up = uluaGetVector3Index( L, 5 ); + Vector2 size = uluaGetVector2Index( L, 6 ); + Vector2 origin = uluaGetVector2Index( L, 7 ); + float rotation = lua_tonumber( L, 8 ); + Color tint = uluaGetColorIndex( L, 9 ); + + if ( !validTexture( texId, TEXTURE_TYPE_ALL ) || !validCamera3D( cameraId ) ) { + lua_pushboolean( L, false ); + return 1; + } + // DrawBillboardPro( *state->camera3Ds[ cameraId ], *texturesGetSourceTexture( texId ), source, position, up, size, origin, rotation, tint ); + DrawBillboardProNoRatio( *state->camera3Ds[ cameraId ], *texturesGetSourceTexture( texId ), source, position, up, size, origin, rotation, tint ); lua_pushboolean( L, true ); return 1; |
