[scene] Add a camera object

It holds the data for a basic 3d camera (transform, fov, near and far
clip). Not used yet as there is much work to be done in cleaning up the
client code.
This commit is contained in:
Bill Currie 2022-02-25 10:41:50 +09:00
parent deff95f490
commit 5ad7c0fbd6
4 changed files with 125 additions and 0 deletions

View File

@ -140,6 +140,7 @@ include_qf_progs = \
include/QF/progs/pr_type_names.h
include_qf_scene = \
include/QF/scene/camera.h \
include/QF/scene/entity.h \
include/QF/scene/hierarchy.h \
include/QF/scene/transform.h \

57
include/QF/scene/camera.h Normal file
View File

@ -0,0 +1,57 @@
/*
camera.h
Scene camera data
Copyright (C) 2022 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2022/02/18
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifndef __QF_scene_camera_h
#define __QF_scene_camera_h
#include "QF/qtypes.h"
#include "QF/simd/mat4f.h"
/** \defgroup scene_camera Camera data
\ingroup scene
*/
///@{
typedef struct camera_s {
struct scene_s *scene; ///< owning scene
int32_t id; ///< id in scene
int32_t transform;
float field_of_view;
float aspect;
float near_clip;
float far_clip;
} camera_t;
void Camera_GetViewMatrix (const camera_t *camera, mat4f_t mat);
void Camera_GetProjectionMatrix (const camera_t *camera, mat4f_t mat);
///@}
#endif//__QF_scene_camera_h

View File

@ -8,6 +8,7 @@ libs_scene_libQFscene_la_LDFLAGS= $(lib_ldflags)
libs_scene_libQFscene_la_LIBADD= $(scene_deps)
libs_scene_libQFscene_la_DEPENDENCIES= $(scene_deps)
libs_scene_libQFscene_la_SOURCES= \
libs/scene/camera.c \
libs/scene/hierarchy.c \
libs/scene/scene.c \
libs/scene/transform.c

66
libs/scene/camera.c Normal file
View File

@ -0,0 +1,66 @@
/*
camera.c
Scene camera data
Copyright (C) 2022 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2022/02/18
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "QF/scene/camera.h"
#include "QF/scene/scene.h"
#include "QF/scene/transform.h"
#include "scn_internal.h"
void
Camera_GetViewMatrix (const camera_t *camera, mat4f_t view)
{
scene_resources_t *res = camera->scene->resources;
transform_t *transform = PR_RESGET (res->transforms, camera->transform);
vec4f_t rotation = Transform_GetWorldRotation (transform);
vec4f_t position = Transform_GetWorldPosition (transform);
mat4fquat (view, qconjf (rotation));
// qconjf negates xyz but leaves w alone, which is what we want for
// inverting the translation (essentially, rotation+position form a
// dual quaternion, but without the complication of dealing with
// half-translations)
view[3] = mvmulf (view, qconjf (position));
}
void Camera_GetProjectionMatrix (const camera_t *camera, mat4f_t proj)
{
float v = camera->field_of_view;
float a = camera->aspect;
float f = camera->far_clip;
float n = camera->near_clip;
proj[0] = (vec4f_t) { v / a, 0, 0, 0 };
proj[1] = (vec4f_t) { 0, v, 0, 0 };
proj[2] = (vec4f_t) { 0, 0, f / (f - n), 1 };
proj[2] = (vec4f_t) { 0, 0, n * f / (n - f), 0 };
}