Serious-Engine/Sources/Engine/Math/Projection_Simple_DOUBLE.cpp
2016-03-11 15:57:17 +02:00

174 lines
5.8 KiB
C++

/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h"
#include <Engine/Math/Projection_DOUBLE.h>
#include <Engine/Math/AABBox.h>
#include <Engine/Math/Geometry.h>
#include <Engine/Math/Clipping.inl>
/*
* Default constructor.
*/
CSimpleProjection3D_DOUBLE::CSimpleProjection3D_DOUBLE(void) {
pr_Prepared = FALSE;
pr_ObjectStretch = FLOAT3D(1.0f, 1.0f, 1.0f);
}
/*
* Prepare for projecting.
*/
void CSimpleProjection3D_DOUBLE::Prepare(void)
{
DOUBLEmatrix3D t3dObjectStretch; // matrix for object stretch
DOUBLEmatrix3D t3dObjectRotation; // matrix for object angles
// calc. matrices for viewer and object angles and stretch
t3dObjectRotation ^= pr_ObjectPlacement.pl_OrientationAngle; // object normally
pr_ViewerRotationMatrix != pr_ViewerPlacement.pl_OrientationAngle; // viewer inverse
t3dObjectStretch.Diagonal(FLOATtoDOUBLE(pr_ObjectStretch));
// first apply object stretch then object rotation and then viewer rotation
pr_RotationMatrix = pr_ViewerRotationMatrix*t3dObjectRotation*t3dObjectStretch;
// calc. offset of object from viewer
pr_TranslationVector = FLOATtoDOUBLE(pr_ObjectPlacement.pl_PositionVector - pr_ViewerPlacement.pl_PositionVector);
// rotate offset only by viewer angles
pr_TranslationVector = pr_TranslationVector*pr_ViewerRotationMatrix;
// mark as prepared
pr_Prepared = TRUE;
}
/*
* Project 3D object point into 3D view space.
*/
void CSimpleProjection3D_DOUBLE::ProjectCoordinate(const DOUBLE3D &v3dObjectPoint,
DOUBLE3D &v3dViewPoint) const
{
// check that the projection object is prepared for projecting
ASSERT(pr_Prepared);
// rotate and translate the point
v3dViewPoint = v3dObjectPoint*pr_RotationMatrix + pr_TranslationVector;
}
/*
* Project 3D object direction vector into 3D view space.
*/
void CSimpleProjection3D_DOUBLE::ProjectDirection(const DOUBLE3D &v3dObjectPoint,
DOUBLE3D &v3dViewPoint) const
{
// rotate the direction
v3dViewPoint = v3dObjectPoint*pr_RotationMatrix;
}
/*
* Project 3D object placement into 3D view space.
*/
void CSimpleProjection3D_DOUBLE::ProjectPlacement(const CPlacement3D &plObject,
CPlacement3D &plView) const
{
// rotate and translate the position vector
plView.pl_PositionVector = DOUBLEtoFLOAT(
FLOATtoDOUBLE(plObject.pl_PositionVector)*pr_RotationMatrix + pr_TranslationVector);
// rotate the orientation
DOUBLEmatrix3D mOrientation;
mOrientation ^= plObject.pl_OrientationAngle;
plView.pl_OrientationAngle ^= pr_RotationMatrix*mOrientation;
}
/*
* Project 3D object mapping into 3D view space.
*/
void CSimpleProjection3D_DOUBLE::ProjectMapping(const CMappingDefinition &mdObject,
const DOUBLEplane3D &plObject,
CMappingDefinition &mdView) const
{
// check that the projection object is prepared for projecting
ASSERT(pr_Prepared);
// make mapping vectors for given plane
CMappingVectors mvObjectDefault;
mvObjectDefault.FromPlane_DOUBLE(plObject);
CMappingVectors mvObject;
mdObject.ToMappingVectors(mvObjectDefault, mvObject);
// make projected plane and vectors
DOUBLEplane3D plView;
Project(plObject, plView);
CMappingVectors mvViewDefault;
mvViewDefault.FromPlane_DOUBLE(plView);
DOUBLE3D vO, vU, vV;
ProjectCoordinate(FLOATtoDOUBLE(mvObject.mv_vO), vO);
ProjectDirection(FLOATtoDOUBLE(mvObject.mv_vU), vU);
ProjectDirection(FLOATtoDOUBLE(mvObject.mv_vV), vV);
CMappingVectors mvView;
mvView.mv_vO = DOUBLEtoFLOAT(vO);
mvView.mv_vU = DOUBLEtoFLOAT(vU);
mvView.mv_vV = DOUBLEtoFLOAT(vV);
// create definition back from the vectors
mdView.FromMappingVectors(mvViewDefault, mvView);
}
/*
* Project 3D object axis aligned bounding box into 3D view space.
*/
void CSimpleProjection3D_DOUBLE::ProjectAABBox(const DOUBLEaabbox3D &boxObject,
DOUBLEaabbox3D &boxView) const
{
// check that the projection object is prepared for projecting
ASSERT(pr_Prepared);
// get center and max axial extent of object box
const DOUBLE3D vObjectBoxCenter = boxObject.Center();
const DOUBLE fObjectBoxMaxExtent = boxObject.Size().MaxNorm();
// project the center to view space
DOUBLE3D vViewBoxCenter;
ProjectCoordinate(vObjectBoxCenter, vViewBoxCenter);
// let the view box have center there and radius of twice max axial extent of object box
boxView = DOUBLEaabbox3D(vViewBoxCenter, 2*fObjectBoxMaxExtent);
/* // clear view box
boxView = DOUBLEaabbox3D();
// create all vertex points of object box
DOUBLE3D avObjectBoxVertices[8];
avObjectBoxVertices[0](1) = boxObject.Min()(1);
avObjectBoxVertices[0](2) = boxObject.Min()(2);
avObjectBoxVertices[0](3) = boxObject.Min()(3);
avObjectBoxVertices[0](1) = boxObject.Min()(1);
avObjectBoxVertices[0](2) = boxObject.Min()(2);
avObjectBoxVertices[0](3) = boxObject.Min()(3);
avObjectBoxVertices[0](1) = boxObject.Max()(1);
// project all vertex points of object box
// add all vertex points of object box to view box
*/
}
/*
* Project 3D object plane into 3D view space.
*/
void CSimpleProjection3D_DOUBLE::Project(const DOUBLEplane3D &p3dObjectPlane,
DOUBLEplane3D &p3dTransformedPlane) const
{
// check that the projection object is prepared for projecting
ASSERT(pr_Prepared);
// rotate the plane
p3dTransformedPlane = p3dObjectPlane*pr_RotationMatrix;
// renormalize it in case of stretch
if (pr_ObjectStretch(1)!=1.0f || pr_ObjectStretch(2)!=1.0f || pr_ObjectStretch(3)!=1.0f) {
FLOAT fLen = ((DOUBLE3D&)p3dTransformedPlane).Length();
p3dTransformedPlane = DOUBLEplane3D(
((DOUBLE3D&)p3dTransformedPlane)/fLen,
p3dTransformedPlane.Distance()*fLen);
}
// translate the plane
p3dTransformedPlane += pr_TranslationVector;
}