add orthographic toggle and mesh cycling to prepare for branch to core_3d_camera_view simplification
This commit is contained in:
parent
44226c995a
commit
e552a83ee9
|
|
@ -21,7 +21,7 @@
|
|||
*
|
||||
********************************************************************************************/
|
||||
// TODO list:
|
||||
// 1. add proper clipping to the target meshes to show intuition there (e.g. move mesh out of clip planes or allow moving the main camera's target away from the meshes)
|
||||
// 1. finish proper clipping toggle with some sort of visibility mask to geometry outside clip volume (also enable moving mesh out of clip planes more clear/allow moving the main camera's target away from the meshes)
|
||||
// 2. improve didactic annotations (ideally with spatial labeling rather than simple flat screen overlay)
|
||||
// 3. improve code didactic, code should read in order of fixed function staging... difficult but long term goal...
|
||||
// 4. add scripted toggling/navigation of ordered fixed function staging visualization (a "play button"-like thing)
|
||||
|
|
@ -53,15 +53,19 @@ typedef unsigned short Triangle[3];
|
|||
enum Flags
|
||||
{
|
||||
FLAG_NDC = 1u<<0,
|
||||
FLAG_REFLECT_Y = 1u<<1,
|
||||
FLAG_ASPECT = 1u<<2,
|
||||
FLAG_REFLECT_Y = 1u<<1, FLAG_ASPECT = 1u<<2,
|
||||
FLAG_PERSPECTIVE_CORRECT = 1u<<3,
|
||||
FLAG_PAUSE = 1u<<4,
|
||||
FLAG_COLOR_MODE = 1u<<5,
|
||||
FLAG_TEXTURE_MODE = 1u<<6
|
||||
FLAG_COLOR_MODE = 1u<<5, FLAG_TEXTURE_MODE = 1u<<6,
|
||||
FLAG_JUGEMU = 1u<<7,
|
||||
FLAG_ORTHO = 1u<<8,
|
||||
FLAG_CLIP = 1u<<9,
|
||||
GEN_CUBE = 1u<<10, LOAD_CUBE = 1u<<11,
|
||||
GEN_SPHERE = 1u<<12, LOAD_SPHERE = 1u<<13,
|
||||
GEN_KNOT = 1u<<14
|
||||
};
|
||||
|
||||
static unsigned int gflags = FLAG_ASPECT | FLAG_COLOR_MODE;
|
||||
static unsigned int gflags = FLAG_ASPECT | FLAG_COLOR_MODE | FLAG_JUGEMU | GEN_CUBE;
|
||||
|
||||
#define NDC_SPACE() ((gflags & FLAG_NDC) != 0)
|
||||
#define REFLECT_Y() ((gflags & FLAG_REFLECT_Y) != 0)
|
||||
|
|
@ -70,11 +74,24 @@ static unsigned int gflags = FLAG_ASPECT | FLAG_COLOR_MODE;
|
|||
#define PAUSED() ((gflags & FLAG_PAUSE) != 0)
|
||||
#define COLOR_MODE() ((gflags & FLAG_COLOR_MODE) != 0)
|
||||
#define TEXTURE_MODE() ((gflags & FLAG_TEXTURE_MODE) != 0)
|
||||
#define JUGEMU_MODE() ((gflags & FLAG_JUGEMU) != 0)
|
||||
#define ORTHO_MODE() ((gflags & FLAG_ORTHO) != 0)
|
||||
#define CLIP_MODE() ((gflags & FLAG_CLIP) != 0)
|
||||
#define TOGGLE(K, F) do { if (IsKeyPressed(K)) { gflags ^= (F); } } while (0)
|
||||
|
||||
static unsigned int targetMesh = 0;
|
||||
#define NUM_MODELS 5
|
||||
#define TARGET_GEN_CUBE() ((gflags & GEN_CUBE) != 0)
|
||||
#define TARGET_LOAD_CUBE() ((gflags & LOAD_CUBE) != 0)
|
||||
#define TARGET_GEN_SPHERE() ((gflags & GEN_SPHERE) != 0)
|
||||
#define TARGET_LOAD_SPHERE() ((gflags & LOAD_SPHERE) != 0)
|
||||
#define TARGET_GEN_KNOT() ((gflags & GEN_KNOT) != 0)
|
||||
#define CYCLE_MESH(K, I, F) do { if (IsKeyPressed(K)) { targetMesh = (I); gflags = (gflags & ~(GEN_CUBE|LOAD_CUBE|GEN_SPHERE|LOAD_SPHERE|GEN_KNOT)) | (F); } } while (0)
|
||||
|
||||
static int fontSize = 20;
|
||||
static float angularVelocity = 1.25f;
|
||||
static float fovy = 60.0f;
|
||||
static float fovyPerspective = 60.0f;
|
||||
static float nearPlaneHeightOrthographic = 1.0f;
|
||||
static float blendScalar = 5.0f;
|
||||
static Vector3 yAxis = { 0.0f, 1.0f, 0.0f };
|
||||
static Vector3 modelPos = { 0.0f, 0.0f, 0.0f };
|
||||
|
|
@ -90,7 +107,7 @@ static void DrawModelWiresAndPoints(Model *model, float rotation);
|
|||
static void DrawNearPlanePoints(Camera3D *main, float aspect, float near, Model *nearPlanePointsModel, Mesh *mesh, float rotation);
|
||||
|
||||
static void UpdateSpatialFrame(Camera3D *main, float aspect, float near, float far, Mesh *spatialFrame);
|
||||
static void DrawSpatialFrame(Mesh spatialFrame);
|
||||
static void DrawSpatialFrame(Mesh *spatialFrame);
|
||||
|
||||
static void PerspectiveIncorrectCapture(Camera3D *main, float aspect, float near, Mesh *mesh, Texture2D meshTexture, float rotation);
|
||||
static void PerspectiveCorrectCapture(Camera3D *main, Model *model, Texture2D meshTexture, Texture2D *perspectiveCorrectTexture, float rotation);
|
||||
|
|
@ -104,6 +121,7 @@ static Vector3 Intersect(Camera3D *main, float near, Vector3 worldCoord);
|
|||
static float SpaceBlendFactor(float dt);
|
||||
static float AspectBlendFactor(float dt);
|
||||
static float ReflectBlendFactor(float dt);
|
||||
static float OrthoBlendFactor(float dt);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
|
|
@ -116,64 +134,87 @@ int main(void)
|
|||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - fixed function didactic");
|
||||
|
||||
float near = 1.0f;
|
||||
float far = 3.0f;
|
||||
float aspect = (float)GetScreenWidth()/(float)GetScreenHeight();
|
||||
nearPlaneHeightOrthographic = 2.0f*near*tanf(DEG2RAD*fovyPerspective*0.5f);
|
||||
float meshRotation = 0.0f;
|
||||
|
||||
Camera3D main = { 0 };
|
||||
main.position = mainPos;
|
||||
main.target = modelPos;
|
||||
main.up = yAxis;
|
||||
main.fovy = fovy;
|
||||
main.projection = CAMERA_PERSPECTIVE;
|
||||
main.projection = (ORTHO_MODE())? CAMERA_ORTHOGRAPHIC : CAMERA_PERSPECTIVE;
|
||||
main.fovy = (ORTHO_MODE())? nearPlaneHeightOrthographic: fovyPerspective;
|
||||
|
||||
Camera3D jugemu = (Camera3D){ 0 };
|
||||
jugemu.position = jugemuPosIso;
|
||||
jugemu.target = modelPos;
|
||||
jugemu.up = yAxis;
|
||||
jugemu.fovy = fovy;
|
||||
jugemu.fovy = fovyPerspective;
|
||||
jugemu.projection = CAMERA_PERSPECTIVE;
|
||||
|
||||
// Model worldModel = LoadModelFromMesh(GenMeshCube(1.0f, 1.0f, 1.0f));
|
||||
// Image textureImage = GenImageChecked(4, 4, 1, 1, BLACK, WHITE);
|
||||
Model worldModels[NUM_MODELS] = { 0 };
|
||||
Model ndcModels[NUM_MODELS] = { 0 };
|
||||
Model nearPlanePointsModels[NUM_MODELS] = { 0 };
|
||||
Texture2D meshTextures[NUM_MODELS] = { 0 };
|
||||
int textureConfig[NUM_MODELS] = { 4, 4, 16, 16, 32 };
|
||||
|
||||
// Model worldModel = LoadModelFromMesh(GenMeshSphere(0.5f, 8, 8));
|
||||
// Image textureImage = GenImageChecked(16, 16, 1, 1, BLACK, WHITE);
|
||||
|
||||
// Model worldModel = LoadModelFromMesh(GenMeshKnot(1.0f, 1.0f, 8, 64));
|
||||
Model worldModel = LoadModelFromMesh(GenMeshKnot(1.0f, 1.0f, 16, 128));
|
||||
Image textureImage = GenImageChecked(32, 32, 1, 1, BLACK, WHITE);
|
||||
|
||||
Texture2D meshTexture = LoadTextureFromImage(textureImage);
|
||||
UnloadImage(textureImage);
|
||||
|
||||
if (!worldModel.meshes[0].indices)
|
||||
for (int i = 0; i < NUM_MODELS; i++)
|
||||
{
|
||||
worldModel.meshes[0].indices = RL_CALLOC(worldModel.meshes[0].vertexCount, sizeof(unsigned short));
|
||||
for (int i = 0; i < worldModel.meshes[0].vertexCount; i++) worldModel.meshes[0].indices[i] = (unsigned short)i;
|
||||
worldModel.meshes[0].triangleCount = worldModel.meshes[0].vertexCount/3;
|
||||
if (i == 0) worldModels[0] = LoadModelFromMesh(GenMeshCube(1.0f, 1.0f, 1.0f));
|
||||
if (i == 1) worldModels[1] = LoadModel("resources/models/unit_cube.obj");
|
||||
if (i == 2) worldModels[2] = LoadModelFromMesh(GenMeshSphere(0.5f, 8, 8));
|
||||
if (i == 3) worldModels[3] = LoadModel("resources/models/unit_sphere.obj");
|
||||
if (i == 4) worldModels[4] = LoadModelFromMesh(GenMeshKnot(1.0f, 1.0f, 16, 128));
|
||||
|
||||
Mesh *worldMesh = &worldModels[i].meshes[0];
|
||||
|
||||
if (!worldMesh->indices)
|
||||
{
|
||||
worldMesh->indices = RL_CALLOC(worldMesh->vertexCount, sizeof(unsigned short));
|
||||
for (int j = 0; j < worldMesh->vertexCount; j++) worldMesh->indices[j] = (unsigned short)j;
|
||||
worldMesh->triangleCount = worldMesh->vertexCount/3;
|
||||
}
|
||||
FillVertexColors(&worldModel.meshes[0]);
|
||||
if (!worldMesh->texcoords)
|
||||
{
|
||||
worldMesh->texcoords = (float *)MemAlloc(sizeof(float)*worldMesh->vertexCount*2);
|
||||
// Demonstrate planar mapping ("reasonable" default): https://en.wikipedia.org/wiki/Planar_projection.
|
||||
BoundingBox bounds = GetMeshBoundingBox(*worldMesh);
|
||||
Vector3 extents = Vector3Subtract(bounds.max, bounds.min);
|
||||
for (int j = 0; j < worldMesh->vertexCount; j++)
|
||||
{
|
||||
float x = ((Vector3 *)worldMesh->vertices)[j].x;
|
||||
float y = ((Vector3 *)worldMesh->vertices)[j].y;
|
||||
((Vector2 *)worldMesh->texcoords)[j].x = (x - bounds.min.x)/extents.x;
|
||||
((Vector2 *)worldMesh->texcoords)[j].y = (y - bounds.min.y)/extents.y;
|
||||
}
|
||||
}
|
||||
FillVertexColors(worldMesh);
|
||||
|
||||
Image textureImage = GenImageChecked(textureConfig[i], textureConfig[i], 1, 1, BLACK, WHITE);
|
||||
meshTextures[i] = LoadTextureFromImage(textureImage);
|
||||
UnloadImage(textureImage);
|
||||
worldModels[i].materials[0].maps[MATERIAL_MAP_ALBEDO].texture = meshTextures[i];
|
||||
|
||||
Mesh ndcMesh = (Mesh){ 0 };
|
||||
ndcMesh.vertexCount = worldModel.meshes[0].vertexCount;
|
||||
ndcMesh.triangleCount = worldModel.meshes[0].triangleCount;
|
||||
ndcMesh.vertexCount = worldMesh->vertexCount;
|
||||
ndcMesh.triangleCount = worldMesh->triangleCount;
|
||||
ndcMesh.vertices = RL_CALLOC(ndcMesh.vertexCount, sizeof(Vector3));
|
||||
ndcMesh.texcoords = RL_CALLOC(ndcMesh.vertexCount, sizeof(Vector2));
|
||||
ndcMesh.indices = RL_CALLOC(ndcMesh.triangleCount, sizeof(Triangle));
|
||||
ndcMesh.colors = RL_CALLOC(ndcMesh.vertexCount, sizeof(Color));
|
||||
memcpy(ndcMesh.colors, worldModel.meshes[0].colors, ndcMesh.vertexCount*sizeof(Color));
|
||||
memcpy(ndcMesh.texcoords, worldModel.meshes[0].texcoords, ndcMesh.vertexCount*sizeof(Vector2));
|
||||
memcpy(ndcMesh.indices, worldModel.meshes[0].indices, ndcMesh.triangleCount*sizeof(Triangle));
|
||||
Model ndcModel = LoadModelFromMesh(ndcMesh);
|
||||
memcpy(ndcMesh.colors, worldMesh->colors, ndcMesh.vertexCount*sizeof(Color));
|
||||
memcpy(ndcMesh.texcoords, worldMesh->texcoords, ndcMesh.vertexCount*sizeof(Vector2));
|
||||
memcpy(ndcMesh.indices, worldMesh->indices, ndcMesh.triangleCount*sizeof(Triangle));
|
||||
ndcModels[i] = LoadModelFromMesh(ndcMesh);
|
||||
ndcModels[i].materials[0].maps[MATERIAL_MAP_ALBEDO].texture = meshTextures[i];
|
||||
|
||||
Mesh nearPlanePoints = (Mesh){ 0 };
|
||||
nearPlanePoints.vertexCount = worldModel.meshes[0].triangleCount*3;
|
||||
nearPlanePoints.vertexCount = worldMesh->triangleCount*3;
|
||||
nearPlanePoints.vertices = RL_CALLOC(nearPlanePoints.vertexCount, sizeof(Vector3));
|
||||
Model nearPlanePointsModel = LoadModelFromMesh(nearPlanePoints);
|
||||
|
||||
worldModel.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = meshTexture;
|
||||
ndcModel.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = meshTexture;
|
||||
nearPlanePointsModels[i] = LoadModelFromMesh(nearPlanePoints);
|
||||
}
|
||||
|
||||
Texture2D perspectiveCorrectTexture = (Texture2D){ 0 };
|
||||
Mesh spatialFrame = GenMeshCube(1.0f, 1.0f, 1.0f);
|
||||
|
|
@ -189,8 +230,6 @@ int main(void)
|
|||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
float far = 3.0f;
|
||||
float near = 1.0f;
|
||||
aspect = (float)GetScreenWidth()/(float)GetScreenHeight();
|
||||
TOGGLE(KEY_N, FLAG_NDC);
|
||||
if (NDC_SPACE()) TOGGLE(KEY_F, FLAG_REFLECT_Y);
|
||||
|
|
@ -199,32 +238,42 @@ int main(void)
|
|||
TOGGLE(KEY_SPACE, FLAG_PAUSE);
|
||||
TOGGLE(KEY_C, FLAG_COLOR_MODE);
|
||||
TOGGLE(KEY_T, FLAG_TEXTURE_MODE);
|
||||
TOGGLE(KEY_J, FLAG_JUGEMU);
|
||||
TOGGLE(KEY_O, FLAG_ORTHO);
|
||||
TOGGLE(KEY_X, FLAG_CLIP);
|
||||
CYCLE_MESH(KEY_ONE, 0, GEN_CUBE);
|
||||
CYCLE_MESH(KEY_TWO, 1, LOAD_CUBE);
|
||||
CYCLE_MESH(KEY_THREE, 2, GEN_SPHERE);
|
||||
CYCLE_MESH(KEY_FOUR, 3, LOAD_SPHERE);
|
||||
CYCLE_MESH(KEY_FIVE, 4, GEN_KNOT);
|
||||
|
||||
float sBlend = SpaceBlendFactor(GetFrameTime());
|
||||
AspectBlendFactor(GetFrameTime());
|
||||
ReflectBlendFactor(GetFrameTime());
|
||||
OrthoBlendFactor(GetFrameTime());
|
||||
|
||||
if (!PAUSED()) meshRotation -= angularVelocity*GetFrameTime();
|
||||
|
||||
OrbitSpace(&jugemu, GetFrameTime());
|
||||
main.projection = (ORTHO_MODE())? CAMERA_ORTHOGRAPHIC : CAMERA_PERSPECTIVE;
|
||||
main.fovy = (ORTHO_MODE())? nearPlaneHeightOrthographic : fovyPerspective;
|
||||
WorldToNDCSpace(&main, aspect, near, far, &worldModels[targetMesh], &ndcModels[targetMesh], meshRotation);
|
||||
|
||||
WorldToNDCSpace(&main, aspect, near, far, &worldModel, &ndcModel, meshRotation);
|
||||
|
||||
for (int i = 0; i < ndcModel.meshes[0].vertexCount; i++)
|
||||
for (int i = 0; i < ndcModels[targetMesh].meshes[0].vertexCount; i++)
|
||||
{
|
||||
Vector3 *worldVertices = (Vector3 *)worldModel.meshes[0].vertices;
|
||||
Vector3 *ndcVertices = (Vector3 *)ndcModel.meshes[0].vertices;
|
||||
Vector3 *worldVertices = (Vector3 *)worldModels[targetMesh].meshes[0].vertices;
|
||||
Vector3 *ndcVertices = (Vector3 *)ndcModels[targetMesh].meshes[0].vertices;
|
||||
ndcVertices[i].x = Lerp(worldVertices[i].x, ndcVertices[i].x, sBlend);
|
||||
ndcVertices[i].y = Lerp(worldVertices[i].y, ndcVertices[i].y, sBlend);
|
||||
ndcVertices[i].z = Lerp(worldVertices[i].z, ndcVertices[i].z, sBlend);
|
||||
}
|
||||
|
||||
Model *displayModel = &ndcModel;
|
||||
Mesh *displayMesh = &ndcModel.meshes[0];
|
||||
Model *displayModel = &ndcModels[targetMesh];
|
||||
Mesh *displayMesh = &ndcModels[targetMesh].meshes[0];
|
||||
|
||||
if (PERSPECTIVE_CORRECT() && TEXTURE_MODE())
|
||||
{
|
||||
PerspectiveCorrectCapture(&main, displayModel, meshTexture, &perspectiveCorrectTexture, meshRotation);
|
||||
PerspectiveCorrectCapture(&main, displayModel, meshTextures[targetMesh], &perspectiveCorrectTexture, meshRotation);
|
||||
}
|
||||
|
||||
UpdateSpatialFrame(&main, aspect, near, far, &spatialFrame);
|
||||
|
|
@ -235,8 +284,7 @@ int main(void)
|
|||
BeginDrawing();
|
||||
|
||||
ClearBackground(BLACK);
|
||||
|
||||
BeginMode3D(jugemu);
|
||||
if (JUGEMU_MODE()) BeginMode3D(jugemu); else BeginMode3D(main);
|
||||
Vector3 depth, right, up;
|
||||
BasisVector(&main, &depth, &right, &up);
|
||||
|
||||
|
|
@ -244,26 +292,30 @@ int main(void)
|
|||
DrawLine3D(main.position, Vector3Add(main.position, up), LILAC);
|
||||
DrawLine3D(main.position, Vector3Add(main.position, depth), MARINER);
|
||||
|
||||
DrawSpatialFrame(spatialFrame);
|
||||
if (JUGEMU_MODE()) DrawSpatialFrame(&spatialFrame);
|
||||
|
||||
DrawModelFilled(displayModel, meshTexture, meshRotation);
|
||||
DrawModelFilled(displayModel, meshTextures[targetMesh], meshRotation);
|
||||
DrawModelWiresAndPoints(displayModel, meshRotation);
|
||||
|
||||
DrawNearPlanePoints(&main, aspect, near, &nearPlanePointsModel, displayMesh, meshRotation);
|
||||
if (JUGEMU_MODE()) DrawNearPlanePoints(&main, aspect, near, &nearPlanePointsModels[targetMesh], displayMesh, meshRotation);
|
||||
|
||||
if (PERSPECTIVE_CORRECT() && TEXTURE_MODE())
|
||||
{
|
||||
spatialFrameModel.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = perspectiveCorrectTexture;
|
||||
DrawModel(spatialFrameModel, modelPos, 1.0f, WHITE);
|
||||
if (JUGEMU_MODE()) DrawModel(spatialFrameModel, modelPos, 1.0f, WHITE);
|
||||
}
|
||||
else
|
||||
{
|
||||
PerspectiveIncorrectCapture(&main, aspect, near, displayMesh, meshTexture, meshRotation);
|
||||
if (JUGEMU_MODE()) PerspectiveIncorrectCapture(&main, aspect, near, displayMesh, meshTextures[targetMesh], meshRotation);
|
||||
}
|
||||
EndMode3D();
|
||||
|
||||
DrawText("ARROWS: MOVE | SPACEBAR: PAUSE", 12, 12, fontSize, NEON_CARROT);
|
||||
DrawText("W A : ZOOM", 12, 38, fontSize, NEON_CARROT);
|
||||
DrawText("[1-2]: CUBE [3-4]: SPHERE [5]: KNOT", 12, 12, fontSize, NEON_CARROT);
|
||||
DrawText("ARROWS: MOVE | SPACEBAR: PAUSE", 12, 38, fontSize, NEON_CARROT);
|
||||
DrawText("W A : ZOOM ", 12, 64, fontSize, NEON_CARROT);
|
||||
DrawText("CLIP [ X ]:", 12, 94, fontSize, SUNFLOWER);
|
||||
DrawText((CLIP_MODE())? "ON" : "OFF", 120, 94, fontSize, (CLIP_MODE())? BAHAMA_BLUE : ANAKIWA);
|
||||
DrawText((targetMesh == 0)? "GEN_CUBE" : (targetMesh == 1)? "LOAD_CUBE" : (targetMesh == 2)? "GEN_SPHERE" : (targetMesh == 3)? "LOAD_SPHERE" : "GEN_KNOT", 12, 205, fontSize, NEON_CARROT);
|
||||
DrawText("TEXTURE [ T ]:", 570, 12, fontSize, SUNFLOWER);
|
||||
DrawText((TEXTURE_MODE())? "ON" : "OFF", 740, 12, fontSize, (TEXTURE_MODE())? ANAKIWA : CHESTNUT_ROSE);
|
||||
DrawText("COLORS [ C ]:", 570, 38, fontSize, SUNFLOWER);
|
||||
|
|
@ -272,8 +324,10 @@ int main(void)
|
|||
DrawText((ASPECT_CORRECT())? "CORRECT" : "INCORRECT", 230, 392, fontSize, (ASPECT_CORRECT())? ANAKIWA : CHESTNUT_ROSE);
|
||||
DrawText("PERSPECTIVE [ P ]:", 12, 418, fontSize, SUNFLOWER);
|
||||
DrawText((PERSPECTIVE_CORRECT())? "CORRECT" : "INCORRECT", 230, 418, fontSize, (PERSPECTIVE_CORRECT())? ANAKIWA : CHESTNUT_ROSE);
|
||||
DrawText("SPACE [ N ]:", 530, 392, fontSize, SUNFLOWER);
|
||||
DrawText((NDC_SPACE())? "NDC" : "WORLD", 665, 392, fontSize, (NDC_SPACE())? BAHAMA_BLUE : ANAKIWA);
|
||||
DrawText("LENS [ O ]:", 510, 366, fontSize, SUNFLOWER);
|
||||
DrawText((ORTHO_MODE())? "ORTHOGRAPHIC" : "PERSPECTIVE", 630, 366, fontSize, (ORTHO_MODE())? BAHAMA_BLUE : ANAKIWA);
|
||||
DrawText("SPACE [ N ]:", 520, 392, fontSize, SUNFLOWER);
|
||||
DrawText((NDC_SPACE())? "NDC" : "WORLD", 655, 392, fontSize, (NDC_SPACE())? BAHAMA_BLUE : ANAKIWA);
|
||||
if (NDC_SPACE())
|
||||
{
|
||||
DrawText("REFLECT [ F ]:", 530, 418, fontSize, SUNFLOWER);
|
||||
|
|
@ -286,11 +340,14 @@ int main(void)
|
|||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadModel(worldModel);
|
||||
UnloadModel(ndcModel);
|
||||
UnloadModel(nearPlanePointsModel);
|
||||
for (int i = 0; i < NUM_MODELS; i++)
|
||||
{
|
||||
UnloadModel(worldModels[i]);
|
||||
UnloadModel(ndcModels[i]);
|
||||
UnloadModel(nearPlanePointsModels[i]);
|
||||
if (meshTextures[i].id) UnloadTexture(meshTextures[i]);
|
||||
}
|
||||
UnloadModel(spatialFrameModel);
|
||||
UnloadTexture(meshTexture);
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
|
@ -312,9 +369,9 @@ static void WorldToNDCSpace(Camera3D *main, float aspect, float near, float far,
|
|||
{
|
||||
Vector3 depth, right, up;
|
||||
BasisVector(main, &depth, &right, &up);
|
||||
float halfHNear = near*tanf(DEG2RAD*main->fovy*0.5f);
|
||||
float halfHNear = Lerp(near*tanf(DEG2RAD*fovyPerspective*0.5f), 0.5f*nearPlaneHeightOrthographic, OrthoBlendFactor(0.0f));
|
||||
float halfWNear = Lerp(halfHNear, halfHNear*aspect, AspectBlendFactor(0.0f));
|
||||
float halfDepthNDC = Lerp(halfHNear, 0.5f*(far - near), AspectBlendFactor(0.0f));
|
||||
float halfDepthNDC = Lerp(halfHNear, 0.5f*(far - near), Lerp(AspectBlendFactor(0.0f), 0.0f, OrthoBlendFactor(0.0f)));
|
||||
Vector3 centerNearPlane = Vector3Add(main->position, Vector3Scale(depth, near));
|
||||
Vector3 centerNDCCube = Vector3Add(centerNearPlane, Vector3Scale(depth, halfDepthNDC));
|
||||
|
||||
|
|
@ -326,7 +383,7 @@ static void WorldToNDCSpace(Camera3D *main, float aspect, float near, float far,
|
|||
Vector3 clipPlaneVector = Vector3Subtract(intersectionCoord, centerNearPlane);
|
||||
float xNDC = Vector3DotProduct(clipPlaneVector, right)/halfWNear;
|
||||
float yNDC = Vector3DotProduct(clipPlaneVector, up)/halfHNear;
|
||||
float zNDC = (far + near - 2.0f*far*near/signedDepth)/(far - near);
|
||||
float zNDC = Lerp((far + near - 2.0f*far*near/signedDepth)/(far - near), 2.0f*(signedDepth - near)/(far - near) - 1.0f, OrthoBlendFactor(0.0f));
|
||||
Vector3 scaledRight = Vector3Scale(right, xNDC*halfWNear);
|
||||
Vector3 scaledUp = Vector3Scale(up, yNDC*halfHNear);
|
||||
Vector3 scaledDepth = Vector3Scale(depth, zNDC*halfDepthNDC);
|
||||
|
|
@ -341,7 +398,6 @@ static void DrawModelFilled(Model *model, Texture2D texture, float rotation)
|
|||
if (!(COLOR_MODE() || TEXTURE_MODE())) return;
|
||||
Color *cacheColors = (Color *)model->meshes[0].colors;
|
||||
if (TEXTURE_MODE() && !COLOR_MODE()) model->meshes[0].colors = NULL;
|
||||
|
||||
model->materials[0].maps[MATERIAL_MAP_ALBEDO].texture.id = (TEXTURE_MODE())? texture.id : 0;
|
||||
DrawModelEx(*model, modelPos, yAxis, RAD2DEG*rotation, modelScale, WHITE);
|
||||
model->materials[0].maps[MATERIAL_MAP_ALBEDO].texture.id = 0;
|
||||
|
|
@ -353,9 +409,8 @@ static void DrawModelWiresAndPoints(Model *model, float rotation)
|
|||
{
|
||||
Color *cacheColors = (Color *)model->meshes[0].colors;
|
||||
unsigned int cacheID = model->materials[0].maps[MATERIAL_MAP_ALBEDO].texture.id;
|
||||
model->meshes[0].colors = NULL;
|
||||
if (!CLIP_MODE()) model->meshes[0].colors = NULL;
|
||||
model->materials[0].maps[MATERIAL_MAP_ALBEDO].texture.id = 0;
|
||||
|
||||
DrawModelWiresEx(*model, modelPos, yAxis, RAD2DEG*rotation, modelScale, MARINER);
|
||||
rlSetPointSize(4.0f);
|
||||
DrawModelPointsEx(*model, modelPos, yAxis, RAD2DEG*rotation, modelScale, LILAC);
|
||||
|
|
@ -368,11 +423,11 @@ static void UpdateSpatialFrame(Camera3D *main, float aspect, float near, float f
|
|||
{
|
||||
Vector3 depth, right, up;
|
||||
BasisVector(main, &depth, &right, &up);
|
||||
float halfHNear = near*tanf(DEG2RAD*main->fovy*0.5f);
|
||||
float halfHNear = Lerp(near*tanf(DEG2RAD*fovyPerspective*0.5f), 0.5f*nearPlaneHeightOrthographic, OrthoBlendFactor(0.0f));
|
||||
float halfWNear = Lerp(halfHNear, halfHNear*aspect, AspectBlendFactor(0.0f));
|
||||
float halfHFar = far*tanf(DEG2RAD*main->fovy*0.5f);
|
||||
float halfHFar = Lerp(far*tanf(DEG2RAD*fovyPerspective*0.5f), 0.5f*nearPlaneHeightOrthographic, OrthoBlendFactor(0.0f));
|
||||
float halfWFar = Lerp(halfHFar, halfHFar*aspect, AspectBlendFactor(0.0f));
|
||||
float halfDepthNdc = Lerp(halfHNear, 0.5f*(far - near), AspectBlendFactor(0.0f));
|
||||
float halfDepthNdc = Lerp(halfHNear, 0.5f*(far - near), Lerp(AspectBlendFactor(0.0f), 0.0f, OrthoBlendFactor(0.0f)));
|
||||
float halfDepth = Lerp(0.5f*(far - near), halfDepthNdc, SpaceBlendFactor(0.0f));
|
||||
float farHalfW = Lerp(halfWFar, halfWNear, SpaceBlendFactor(0.0f));
|
||||
float farHalfH = Lerp(halfHFar, halfHNear, SpaceBlendFactor(0.0f));
|
||||
|
|
@ -391,7 +446,7 @@ static void UpdateSpatialFrame(Camera3D *main, float aspect, float near, float f
|
|||
}
|
||||
}
|
||||
|
||||
static void DrawSpatialFrame(Mesh spatialFrame)
|
||||
static void DrawSpatialFrame(Mesh *spatialFrame)
|
||||
{
|
||||
static int frontFaces[4][2] = { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 } };
|
||||
static int backFaces[4][2] = { { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 4 } };
|
||||
|
|
@ -401,8 +456,8 @@ static void DrawSpatialFrame(Mesh spatialFrame)
|
|||
for (int i = 0; i < 3; i++)
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
Vector3 startPosition = ((Vector3 *)spatialFrame.vertices)[faces[i][j][0]];
|
||||
Vector3 endPosition = ((Vector3 *)spatialFrame.vertices)[faces[i][j][1]];
|
||||
Vector3 startPosition = ((Vector3 *)spatialFrame->vertices)[faces[i][j][0]];
|
||||
Vector3 endPosition = ((Vector3 *)spatialFrame->vertices)[faces[i][j][1]];
|
||||
DrawLine3D(startPosition, endPosition, (i == 0)? NEON_CARROT : (i == 1)? EGGPLANT : HOPBUSH);
|
||||
}
|
||||
}
|
||||
|
|
@ -552,12 +607,12 @@ static void OrbitSpace(Camera3D *jugemu, float dt)
|
|||
float azimuth = atan2f(jugemu->position.z, jugemu->position.x);
|
||||
float horizontalRadius = sqrtf(jugemu->position.x*jugemu->position.x + jugemu->position.z*jugemu->position.z);
|
||||
float elevation = atan2f(jugemu->position.y, horizontalRadius);
|
||||
if (IsKeyDown(KEY_LEFT)) azimuth += 1.5f*dt;
|
||||
if (IsKeyDown(KEY_RIGHT)) azimuth -= 1.5f*dt;
|
||||
if (IsKeyDown(KEY_LEFT)) azimuth += 1.0f*dt;
|
||||
if (IsKeyDown(KEY_RIGHT)) azimuth -= 1.0f*dt;
|
||||
if (IsKeyDown(KEY_UP)) elevation += 1.0f*dt;
|
||||
if (IsKeyDown(KEY_DOWN)) elevation -= 1.0f*dt;
|
||||
if (IsKeyDown(KEY_W)) radius -= 2.0f*dt;
|
||||
if (IsKeyDown(KEY_S)) radius += 2.0f*dt;
|
||||
if (IsKeyDown(KEY_W)) radius -= 1.0f*dt;
|
||||
if (IsKeyDown(KEY_S)) radius += 1.0f*dt;
|
||||
elevation = Clamp(elevation, -M_PI_2 + 0.1f, M_PI_2 - 0.1f);
|
||||
jugemu->position.x = Clamp(radius, 0.25f, 10.0f)*cosf(elevation)*cosf(azimuth);
|
||||
jugemu->position.y = Clamp(radius, 0.25f, 10.0f)*sinf(elevation);
|
||||
|
|
@ -614,9 +669,13 @@ static Vector3 Intersect(Camera3D *main, float near, Vector3 worldCoord)
|
|||
Vector3 viewDir = Vector3Normalize(Vector3Subtract(main->target, main->position));
|
||||
Vector3 mainCameraToPoint = Vector3Subtract(worldCoord, main->position);
|
||||
float depthAlongView = Vector3DotProduct(mainCameraToPoint, viewDir);
|
||||
if (depthAlongView <= 0.0f) return Vector3Add(main->position, Vector3Scale(viewDir, near));
|
||||
Vector3 centerNearPlane = Vector3Add(main->position, Vector3Scale(viewDir, near));
|
||||
if (depthAlongView <= 0.0f) return centerNearPlane;
|
||||
float scaleToNear = near/depthAlongView;
|
||||
return Vector3Add(main->position, Vector3Scale(mainCameraToPoint, scaleToNear));
|
||||
Vector3 resultPerspective = Vector3Add(main->position, Vector3Scale(mainCameraToPoint, scaleToNear));
|
||||
Vector3 resultOrtho = Vector3Add(worldCoord, Vector3Scale(viewDir, Vector3DotProduct(Vector3Subtract(centerNearPlane, worldCoord), viewDir)));
|
||||
Vector3 result = Vector3Lerp(resultPerspective,resultOrtho, OrthoBlendFactor(0.0f));
|
||||
return result;
|
||||
}
|
||||
|
||||
static float SpaceBlendFactor(float dt)
|
||||
|
|
@ -644,3 +703,10 @@ static float ReflectBlendFactor(float dt)
|
|||
}
|
||||
return blend;
|
||||
}
|
||||
|
||||
static float OrthoBlendFactor(float dt)
|
||||
{
|
||||
static float blend = 0.0f;
|
||||
if (dt > 0.0f) blend = Clamp(blend + ((ORTHO_MODE())? 1.0f : -1.0f)*blendScalar*dt, 0.0f, 1.0f);
|
||||
return blend;
|
||||
}
|
||||
22
examples/core/resources/models/unit_cube.obj
Normal file
22
examples/core/resources/models/unit_cube.obj
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
o unit_cube
|
||||
v -0.5 -0.5 -0.5
|
||||
v 0.5 -0.5 -0.5
|
||||
v 0.5 0.5 -0.5
|
||||
v -0.5 0.5 -0.5
|
||||
v -0.5 -0.5 0.5
|
||||
v 0.5 -0.5 0.5
|
||||
v 0.5 0.5 0.5
|
||||
v -0.5 0.5 0.5
|
||||
s off
|
||||
f 1 4 3
|
||||
f 1 3 2
|
||||
f 5 6 7
|
||||
f 5 7 8
|
||||
f 1 5 8
|
||||
f 1 8 4
|
||||
f 2 3 7
|
||||
f 2 7 6
|
||||
f 4 8 7
|
||||
f 4 7 3
|
||||
f 1 2 6
|
||||
f 1 6 5
|
||||
173
examples/core/resources/models/unit_sphere.obj
Normal file
173
examples/core/resources/models/unit_sphere.obj
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
o sphere_unit_minimal
|
||||
o sphere_unit_box_scaled
|
||||
v 0.0000 0.5000 0.0000
|
||||
v 0.1913 0.4619 0.0000
|
||||
v 0.1353 0.4619 0.1353
|
||||
v 0.0000 0.4619 0.1913
|
||||
v -0.1353 0.4619 0.1353
|
||||
v -0.1913 0.4619 0.0000
|
||||
v -0.1353 0.4619 -0.1353
|
||||
v -0.0000 0.4619 -0.1913
|
||||
v 0.1353 0.4619 -0.1353
|
||||
v 0.3536 0.3536 0.0000
|
||||
v 0.2500 0.3536 0.2500
|
||||
v 0.0000 0.3536 0.3536
|
||||
v -0.2500 0.3536 0.2500
|
||||
v -0.3536 0.3536 0.0000
|
||||
v -0.2500 0.3536 -0.2500
|
||||
v -0.0000 0.3536 -0.3536
|
||||
v 0.2500 0.3536 -0.2500
|
||||
v 0.4619 0.1913 0.0000
|
||||
v 0.3266 0.1913 0.3266
|
||||
v 0.0000 0.1913 0.4619
|
||||
v -0.3266 0.1913 0.3266
|
||||
v -0.4619 0.1913 0.0000
|
||||
v -0.3266 0.1913 -0.3266
|
||||
v -0.0000 0.1913 -0.4619
|
||||
v 0.3266 0.1913 -0.3266
|
||||
v 0.5000 0.0000 0.0000
|
||||
v 0.3536 0.0000 0.3536
|
||||
v 0.0000 0.0000 0.5000
|
||||
v -0.3536 0.0000 0.3536
|
||||
v -0.5000 0.0000 0.0000
|
||||
v -0.3536 0.0000 -0.3536
|
||||
v -0.0000 0.0000 -0.5000
|
||||
v 0.3536 0.0000 -0.3536
|
||||
v 0.4619 -0.1913 0.0000
|
||||
v 0.3266 -0.1913 0.3266
|
||||
v 0.0000 -0.1913 0.4619
|
||||
v -0.3266 -0.1913 0.3266
|
||||
v -0.4619 -0.1913 0.0000
|
||||
v -0.3266 -0.1913 -0.3266
|
||||
v -0.0000 -0.1913 -0.4619
|
||||
v 0.3266 -0.1913 -0.3266
|
||||
v 0.3536 -0.3536 0.0000
|
||||
v 0.2500 -0.3536 0.2500
|
||||
v 0.0000 -0.3536 0.3536
|
||||
v -0.2500 -0.3536 0.2500
|
||||
v -0.3536 -0.3536 0.0000
|
||||
v -0.2500 -0.3536 -0.2500
|
||||
v -0.0000 -0.3536 -0.3536
|
||||
v 0.2500 -0.3536 -0.2500
|
||||
v 0.1913 -0.4619 0.0000
|
||||
v 0.1353 -0.4619 0.1353
|
||||
v 0.0000 -0.4619 0.1913
|
||||
v -0.1353 -0.4619 0.1353
|
||||
v -0.1913 -0.4619 0.0000
|
||||
v -0.1353 -0.4619 -0.1353
|
||||
v -0.0000 -0.4619 -0.1913
|
||||
v 0.1353 -0.4619 -0.1353
|
||||
v 0.0000 -0.5000 0.0000
|
||||
s off
|
||||
f 1 3 2
|
||||
f 1 4 3
|
||||
f 1 5 4
|
||||
f 1 6 5
|
||||
f 1 7 6
|
||||
f 1 8 7
|
||||
f 1 9 8
|
||||
f 1 2 9
|
||||
f 2 3 10
|
||||
f 3 11 10
|
||||
f 3 4 11
|
||||
f 4 12 11
|
||||
f 4 5 12
|
||||
f 5 13 12
|
||||
f 5 6 13
|
||||
f 6 14 13
|
||||
f 6 7 14
|
||||
f 7 15 14
|
||||
f 7 8 15
|
||||
f 8 16 15
|
||||
f 8 9 16
|
||||
f 9 17 16
|
||||
f 9 2 17
|
||||
f 2 10 17
|
||||
f 10 11 18
|
||||
f 11 19 18
|
||||
f 11 12 19
|
||||
f 12 20 19
|
||||
f 12 13 20
|
||||
f 13 21 20
|
||||
f 13 14 21
|
||||
f 14 22 21
|
||||
f 14 15 22
|
||||
f 15 23 22
|
||||
f 15 16 23
|
||||
f 16 24 23
|
||||
f 16 17 24
|
||||
f 17 25 24
|
||||
f 17 10 25
|
||||
f 10 18 25
|
||||
f 18 19 26
|
||||
f 19 27 26
|
||||
f 19 20 27
|
||||
f 20 28 27
|
||||
f 20 21 28
|
||||
f 21 29 28
|
||||
f 21 22 29
|
||||
f 22 30 29
|
||||
f 22 23 30
|
||||
f 23 31 30
|
||||
f 23 24 31
|
||||
f 24 32 31
|
||||
f 24 25 32
|
||||
f 25 33 32
|
||||
f 25 18 33
|
||||
f 18 26 33
|
||||
f 26 27 34
|
||||
f 27 35 34
|
||||
f 27 28 35
|
||||
f 28 36 35
|
||||
f 28 29 36
|
||||
f 29 37 36
|
||||
f 29 30 37
|
||||
f 30 38 37
|
||||
f 30 31 38
|
||||
f 31 39 38
|
||||
f 31 32 39
|
||||
f 32 40 39
|
||||
f 32 33 40
|
||||
f 33 41 40
|
||||
f 33 26 41
|
||||
f 26 34 41
|
||||
f 34 35 42
|
||||
f 35 43 42
|
||||
f 35 36 43
|
||||
f 36 44 43
|
||||
f 36 37 44
|
||||
f 37 45 44
|
||||
f 37 38 45
|
||||
f 38 46 45
|
||||
f 38 39 46
|
||||
f 39 47 46
|
||||
f 39 40 47
|
||||
f 40 48 47
|
||||
f 40 41 48
|
||||
f 41 49 48
|
||||
f 41 34 49
|
||||
f 34 42 49
|
||||
f 42 43 50
|
||||
f 43 51 50
|
||||
f 43 44 51
|
||||
f 44 52 51
|
||||
f 44 45 52
|
||||
f 45 53 52
|
||||
f 45 46 53
|
||||
f 46 54 53
|
||||
f 46 47 54
|
||||
f 47 55 54
|
||||
f 47 48 55
|
||||
f 48 56 55
|
||||
f 48 49 56
|
||||
f 49 57 56
|
||||
f 49 42 57
|
||||
f 42 50 57
|
||||
f 58 50 51
|
||||
f 58 51 52
|
||||
f 58 52 53
|
||||
f 58 53 54
|
||||
f 58 54 55
|
||||
f 58 55 56
|
||||
f 58 56 57
|
||||
f 58 57 50
|
||||
Loading…
Reference in New Issue
Block a user