123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- /*
- * 3D Engine
- * clipping.c:
- * Based on pikuma.com 3D software renderer in C
- * Copyright (c) 2021 986-Studio. All rights reserved.
- *
- * Created by Manoël Trapier on 11/03/2021.
- */
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #include <assert.h>
- #include <clipping.h>
- static plane_t frustum[TOTAL_PLANES];
- void initFrustumPlanes(double fov, double aspectRation, double zNear, double zFar)
- {
- frustum[LEFT_PLANE].point = vec3(0, 0, 0);
- frustum[LEFT_PLANE].normal = vec3( cos(fov) / 2, 0, sin(fov) / 2);
- frustum[RIGHT_PLANE].point = vec3(0, 0, 0);
- frustum[RIGHT_PLANE].normal = vec3( -cos(fov) / 2, 0, sin(fov) / 2);
- frustum[TOP_PLANE].point = vec3(0, 0, 0);
- frustum[TOP_PLANE].normal = vec3(0, -cos(fov) / 2, sin(fov) / 2);
- frustum[BOTTOM_PLANE].point = vec3(0, 0, 0);
- frustum[BOTTOM_PLANE].normal = vec3(0, cos(fov) / 2, sin(fov) / 2);
- frustum[NEAR_PLANE].point = vec3(0, 0, zNear);
- frustum[NEAR_PLANE].normal = vec3(0, 0, 1);
- frustum[FAR_PLANE].point = vec3(0, 0, zFar);
- frustum[FAR_PLANE].normal = vec3(0, 0, -1);
- }
- static void clipPolygonAgainstPlane(polygon_t *poly, faceenum_t plane)
- {
- int i;
- vec3_t planePoint = frustum[plane].point;
- vec3_t planeNormal = frustum[plane].normal;
- vec3_t *currentVertex;
- vec3_t *previousVertex;
- double currentDot, previousDot;
- vec3_t newVertices[MAX_NUM_POLYGON_VERTICES];
- int newVerticesCount = 0;
- previousVertex = &poly->vertices[poly->num_verticices - 1];
- for(i = 0; i < poly->num_verticices; i++)
- {
- currentVertex = &poly->vertices[i];
- currentDot = vec3Dot(vec3SubVectors(*currentVertex, planePoint), planeNormal);
- previousDot = vec3Dot(vec3SubVectors(*previousVertex, planePoint), planeNormal);
- if ((currentDot * previousDot) < 0.0)
- {
- double t;
- /* we crossed the plane */
- t = previousDot / (previousDot - currentDot);
- newVertices[newVerticesCount] = vec3SubVectors(*currentVertex, *previousVertex);
- vec3ScalarMult(newVertices[newVerticesCount], t);
- newVertices[newVerticesCount] = vec3AddVectors(*currentVertex, newVertices[newVerticesCount]);
- newVerticesCount++;
- }
- if (currentDot >= 0.0)
- {
- newVertices[newVerticesCount] = *currentVertex;
- newVerticesCount++;
- }
- /* Just to be sure, should never trigger */
- assert(newVerticesCount < MAX_NUM_POLYGON_VERTICES);
- previousVertex = currentVertex;
- }
- for(i = 0; i < newVerticesCount; i++)
- {
- poly->vertices[i] = newVertices[i];
- }
- poly->num_verticices = newVerticesCount;
- }
- void clipPolygon(polygon_t *poly)
- {
- clipPolygonAgainstPlane(poly, LEFT_PLANE);
- clipPolygonAgainstPlane(poly, TOP_PLANE);
- clipPolygonAgainstPlane(poly, RIGHT_PLANE);
- clipPolygonAgainstPlane(poly, BOTTOM_PLANE);
- clipPolygonAgainstPlane(poly, NEAR_PLANE);
- clipPolygonAgainstPlane(poly, FAR_PLANE);
- }
|