Added bounding box system, with camera support
This commit is contained in:
parent
48494f9e18
commit
3e42320c3f
4 changed files with 105 additions and 41 deletions
|
@ -5,6 +5,7 @@
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "scenery.h"
|
#include "scenery.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
#include "tools/boundingbox.h"
|
||||||
|
|
||||||
struct CameraDefinition
|
struct CameraDefinition
|
||||||
{
|
{
|
||||||
|
@ -361,58 +362,49 @@ Vector3 cameraUnproject(CameraDefinition* camera, Vector3 point)
|
||||||
renderPushQuad(&v1, &v2, &v3, &v4);
|
renderPushQuad(&v1, &v2, &v3, &v4);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
static inline void _updateBox(Vector3* point, double* xmin, double* xmax, double* ymin, double* ymax, double* zmax)
|
|
||||||
{
|
|
||||||
*xmin = (*xmin < point->x) ? *xmin : point->x;
|
|
||||||
*ymin = (*ymin < point->y) ? *ymin : point->y;
|
|
||||||
|
|
||||||
*xmax = (*xmax > point->x) ? *xmax : point->x;
|
|
||||||
*ymax = (*ymax > point->y) ? *ymax : point->y;
|
|
||||||
*zmax = (*zmax > point->z) ? *zmax : point->z;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cameraIsBoxInView(CameraDefinition* camera, Vector3 center, double xsize, double ysize, double zsize)
|
int cameraIsBoxInView(CameraDefinition* camera, Vector3 center, double xsize, double ysize, double zsize)
|
||||||
{
|
{
|
||||||
Vector3 projected;
|
BoundingBox box;
|
||||||
double xmin, xmax, ymin, ymax, zmax;
|
|
||||||
|
|
||||||
center.x -= xsize / 2.0;
|
boundingBoxReset(&box);
|
||||||
center.y -= ysize / 2.0;
|
|
||||||
center.z -= zsize / 2.0;
|
|
||||||
projected = cameraProject(camera, center);
|
|
||||||
xmin = xmax = projected.x;
|
|
||||||
ymin = ymax = projected.y;
|
|
||||||
zmax = projected.z;
|
|
||||||
|
|
||||||
center.x += xsize;
|
boundingBoxPushPoint(&box, v3Add(center, v3(-xsize, -ysize, -zsize)));
|
||||||
projected = cameraProject(camera, center);
|
boundingBoxPushPoint(&box, v3Add(center, v3(xsize, ysize, zsize)));
|
||||||
_updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax);
|
|
||||||
|
|
||||||
center.z += zsize;
|
return cameraIsUnprojectedBoxInView(camera, &box);
|
||||||
projected = cameraProject(camera, center);
|
}
|
||||||
_updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax);
|
|
||||||
|
|
||||||
center.x -= xsize;
|
int cameraIsUnprojectedBoxInView(CameraDefinition* camera, BoundingBox* box)
|
||||||
projected = cameraProject(camera, center);
|
{
|
||||||
_updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax);
|
BoundingBox projected;
|
||||||
|
|
||||||
center.y += ysize;
|
boundingBoxReset(&projected);
|
||||||
projected = cameraProject(camera, center);
|
|
||||||
_updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax);
|
|
||||||
|
|
||||||
center.x += xsize;
|
boundingBoxPushPoint(&projected, cameraProject(camera, v3(box->xmin, box->ymin, box->zmin)));
|
||||||
projected = cameraProject(camera, center);
|
boundingBoxPushPoint(&projected, cameraProject(camera, v3(box->xmax, box->ymin, box->zmin)));
|
||||||
_updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax);
|
boundingBoxPushPoint(&projected, cameraProject(camera, v3(box->xmin, box->ymax, box->zmin)));
|
||||||
|
boundingBoxPushPoint(&projected, cameraProject(camera, v3(box->xmax, box->ymax, box->zmin)));
|
||||||
|
boundingBoxPushPoint(&projected, cameraProject(camera, v3(box->xmin, box->ymin, box->zmax)));
|
||||||
|
boundingBoxPushPoint(&projected, cameraProject(camera, v3(box->xmax, box->ymin, box->zmax)));
|
||||||
|
boundingBoxPushPoint(&projected, cameraProject(camera, v3(box->xmin, box->ymax, box->zmax)));
|
||||||
|
boundingBoxPushPoint(&projected, cameraProject(camera, v3(box->xmax, box->ymax, box->zmax)));
|
||||||
|
|
||||||
center.z -= zsize;
|
return cameraIsProjectedBoxInView(camera, &projected);
|
||||||
projected = cameraProject(camera, center);
|
}
|
||||||
_updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax);
|
|
||||||
|
|
||||||
center.x -= xsize;
|
int cameraIsProjectedBoxInView(CameraDefinition* camera, BoundingBox* box)
|
||||||
projected = cameraProject(camera, center);
|
{
|
||||||
_updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax);
|
if (box->xmin <= camera->width && box->xmax >= 0.0 && box->ymin <= camera->height && box->ymax >= 0.0 && box->zmax >= camera->perspective.znear)
|
||||||
|
{
|
||||||
|
double dx = box->xmax - box->xmin;
|
||||||
|
double dy = box->ymax - box->ymin;
|
||||||
|
|
||||||
return xmin <= camera->width && xmax >= 0.0 && ymin <= camera->height && ymax >= 0.0 && zmax >= camera->perspective.znear;
|
return (int)ceil(dx) * (int)ceil(dy);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int cameraTransitionToAnother(CameraDefinition* current, CameraDefinition* wanted, double factor)
|
int cameraTransitionToAnother(CameraDefinition* current, CameraDefinition* wanted, double factor)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "tools/pack.h"
|
#include "tools/pack.h"
|
||||||
#include "tools/euclid.h"
|
#include "tools/euclid.h"
|
||||||
|
#include "tools/boundingbox.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
|
@ -57,6 +58,8 @@ Vector3 cameraProject(CameraDefinition* camera, Vector3 point);
|
||||||
Vector3 cameraUnproject(CameraDefinition* camera, Vector3 point);
|
Vector3 cameraUnproject(CameraDefinition* camera, Vector3 point);
|
||||||
/*void cameraPushOverlay(CameraDefinition* camera, Color col, f_RenderFragmentCallback callback);*/
|
/*void cameraPushOverlay(CameraDefinition* camera, Color col, f_RenderFragmentCallback callback);*/
|
||||||
int cameraIsBoxInView(CameraDefinition* camera, Vector3 center, double xsize, double ysize, double zsize);
|
int cameraIsBoxInView(CameraDefinition* camera, Vector3 center, double xsize, double ysize, double zsize);
|
||||||
|
int cameraIsUnprojectedBoxInView(CameraDefinition* camera, BoundingBox* box);
|
||||||
|
int cameraIsProjectedBoxInView(CameraDefinition* camera, BoundingBox* box);
|
||||||
|
|
||||||
int cameraTransitionToAnother(CameraDefinition* current, CameraDefinition* wanted, double factor);
|
int cameraTransitionToAnother(CameraDefinition* current, CameraDefinition* wanted, double factor);
|
||||||
|
|
||||||
|
|
41
src/rendering/tools/boundingbox.c
Normal file
41
src/rendering/tools/boundingbox.c
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#include "boundingbox.h"
|
||||||
|
|
||||||
|
void boundingBoxReset(BoundingBox* box)
|
||||||
|
{
|
||||||
|
box->empty = 1;
|
||||||
|
box->xmin = 10000000000.0;
|
||||||
|
box->xmax = -10000000000.0;
|
||||||
|
box->ymin = 10000000000.0;
|
||||||
|
box->ymax = -10000000000.0;
|
||||||
|
box->zmin = 10000000000.0;
|
||||||
|
box->zmax = -10000000000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void boundingBoxPushPoint(BoundingBox* box, Vector3 point)
|
||||||
|
{
|
||||||
|
box->empty = 0;
|
||||||
|
if (point.x < box->xmin)
|
||||||
|
{
|
||||||
|
box->xmin = point.x;
|
||||||
|
}
|
||||||
|
if (point.x > box->xmax)
|
||||||
|
{
|
||||||
|
box->xmax = point.x;
|
||||||
|
}
|
||||||
|
if (point.y < box->ymin)
|
||||||
|
{
|
||||||
|
box->ymin = point.y;
|
||||||
|
}
|
||||||
|
if (point.y > box->ymax)
|
||||||
|
{
|
||||||
|
box->ymax = point.y;
|
||||||
|
}
|
||||||
|
if (point.z < box->zmin)
|
||||||
|
{
|
||||||
|
box->zmin = point.z;
|
||||||
|
}
|
||||||
|
if (point.z > box->zmax)
|
||||||
|
{
|
||||||
|
box->zmax = point.z;
|
||||||
|
}
|
||||||
|
}
|
28
src/rendering/tools/boundingbox.h
Normal file
28
src/rendering/tools/boundingbox.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef _RENDERING_TOOLS_BOUNDINGBOX_H_
|
||||||
|
#define _RENDERING_TOOLS_BOUNDINGBOX_H_
|
||||||
|
|
||||||
|
#include "euclid.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int empty;
|
||||||
|
double xmin;
|
||||||
|
double xmax;
|
||||||
|
double ymin;
|
||||||
|
double ymax;
|
||||||
|
double zmin;
|
||||||
|
double zmax;
|
||||||
|
} BoundingBox;
|
||||||
|
|
||||||
|
void boundingBoxReset(BoundingBox* box);
|
||||||
|
void boundingBoxPushPoint(BoundingBox* box, Vector3 point);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue