mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0026344: Visualization - provide a support of zoom persistent selection
1) New Graphic3d_TransformPers structure for defining parameters and algorithm methods, featuring: a) application of transformation to projection and world view matrices; b) computation of model-world transformation of persistent object; c) computation of transformed bounding box of persistent object. 2) Transform persistence algorithm does not make any changes to model-world transformation of object (deals with projection and world view matrices only), thus making possible to employ local transformation in a usual way. 3) Support of BVH selection for transform persistent objects (pan, rotate, zoom, trihedron persistence only). 4) Support efficient frustum culling for transform persistent objects (pan, rotate, zoom, trihedron persistence only). 5) Support of z-fitting algorithm for world-view space transform persistent objects (rotate, zoom persistence only). 6) Rewrite usage of transform persistence structures and utilities classes: a) Replaced Graphic3d_CTransPers, TEL_TRANSFORM_PERSISTENCE by Graphic3d_TransformPers; b) Move functions from OpenGl_Utils.hxx to Graphic3d_TransformUtils.hxx; c) Extract matrix stack class from OpenGl_Utils.hxx to OpenGl_MatrixStack.hxx; 7) New class Graphic3d_WorldViewProjState to keep track of projection, world view matrices changes for a camera. 8) New test case bugs/vis/bug26344. 9) Renamed method Graphic3d_Camera::ModelViewState of to ::WorldViewState for consistency.
This commit is contained in:
@@ -55,7 +55,6 @@ Graphic3d_CStructure.cxx
|
||||
Graphic3d_CStructure.hxx
|
||||
Graphic3d_CStructurePtr.hxx
|
||||
Graphic3d_CTexture.hxx
|
||||
Graphic3d_CTransPersStruct.hxx
|
||||
Graphic3d_CUserDraw.hxx
|
||||
Graphic3d_CView.hxx
|
||||
Graphic3d_CycleError.hxx
|
||||
@@ -143,6 +142,8 @@ Graphic3d_TextureParams.hxx
|
||||
Graphic3d_TextureRoot.cxx
|
||||
Graphic3d_TextureRoot.hxx
|
||||
Graphic3d_TransformError.hxx
|
||||
Graphic3d_TransformPers.hxx
|
||||
Graphic3d_TransformUtils.hxx
|
||||
Graphic3d_TransModeFlags.hxx
|
||||
Graphic3d_TypeOfBackground.hxx
|
||||
Graphic3d_TypeOfComposition.hxx
|
||||
@@ -169,5 +170,6 @@ Graphic3d_Vertex.hxx
|
||||
Graphic3d_VerticalTextAlignment.hxx
|
||||
Graphic3d_ViewAffinity.cxx
|
||||
Graphic3d_ViewAffinity.hxx
|
||||
Graphic3d_WorldViewProjState.hxx
|
||||
Graphic3d_ZLayerId.hxx
|
||||
Graphic3d_ZLayerSettings.hxx
|
||||
|
@@ -57,10 +57,4 @@ Graphic3d_CStructure::Graphic3d_CStructure (const Handle(Graphic3d_StructureMana
|
||||
ContextFillArea.IsSet = 0,
|
||||
ContextMarker.IsSet = 0,
|
||||
ContextText.IsSet = 0;
|
||||
|
||||
TransformPersistence.IsSet = 0;
|
||||
TransformPersistence.Flag = Graphic3d_TMF_None;
|
||||
TransformPersistence.Point.x = 0.0;
|
||||
TransformPersistence.Point.y = 0.0;
|
||||
TransformPersistence.Point.z = 0.0;
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include <Graphic3d_SequenceOfHClipPlane.hxx>
|
||||
#include <Graphic3d_TypeOfComposition.hxx>
|
||||
#include <Graphic3d_ViewAffinity.hxx>
|
||||
#include <Graphic3d_TransformPers.hxx>
|
||||
#include <Graphic3d_Vec3.hxx>
|
||||
#include <Graphic3d_ZLayerId.hxx>
|
||||
|
||||
@@ -143,7 +144,7 @@ public:
|
||||
unsigned IsMutable : 1;
|
||||
unsigned Is2dText : 1;
|
||||
|
||||
CALL_DEF_TRANSFORM_PERSISTENCE TransformPersistence;
|
||||
Graphic3d_TransformPers TransformPersistence;
|
||||
|
||||
protected:
|
||||
|
||||
|
@@ -1,27 +0,0 @@
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
/*============================================================================*/
|
||||
/*==== Titel: Graphic3d_CTransPersStruct.hxx */
|
||||
/*==== Role : */
|
||||
/*==== */
|
||||
/*==== Implementation: This is a primitive type implemented with typedef */
|
||||
/*============================================================================*/
|
||||
|
||||
#ifndef _Graphic3d_CTransPersStruct_HeaderFile
|
||||
#define _Graphic3d_CTransPersStruct_HeaderFile
|
||||
|
||||
#include <InterfaceGraphic_Graphic3d.hxx>
|
||||
typedef CALL_DEF_TRANSFORM_PERSISTENCE Graphic3d_CTransPersStruct;
|
||||
|
||||
#endif /*_Graphic3d_CTransPersStruct_HeaderFile*/
|
@@ -16,8 +16,9 @@
|
||||
#include <gp_Pln.hxx>
|
||||
#include <Standard_ShortReal.hxx>
|
||||
|
||||
#include <Graphic3d_Vec4.hxx>
|
||||
#include <Graphic3d_Camera.hxx>
|
||||
#include <Graphic3d_Vec4.hxx>
|
||||
#include <Graphic3d_WorldViewProjState.hxx>
|
||||
|
||||
#include <Standard_Atomic.hxx>
|
||||
#include <Standard_Assert.hxx>
|
||||
@@ -50,9 +51,9 @@ namespace
|
||||
static Standard_Real zEpsilon (const Standard_Real theValue)
|
||||
{
|
||||
if (theValue == 0)
|
||||
{
|
||||
{
|
||||
return FLT_EPSILON;
|
||||
}
|
||||
}
|
||||
Standard_Real aLogRadix = Log10 (Abs (theValue)) / Log10 (FLT_RADIX);
|
||||
Standard_Real aExp = Floor (aLogRadix);
|
||||
return FLT_EPSILON * Pow (FLT_RADIX, aExp);
|
||||
@@ -79,8 +80,9 @@ Graphic3d_Camera::Graphic3d_Camera()
|
||||
myIOD (0.05),
|
||||
myIODType (IODType_Relative)
|
||||
{
|
||||
myProjectionState = (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER);
|
||||
myOrientationState = (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER);
|
||||
myWorldViewProjState.Initialize ((Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER),
|
||||
(Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER),
|
||||
this);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -89,6 +91,8 @@ Graphic3d_Camera::Graphic3d_Camera()
|
||||
// =======================================================================
|
||||
Graphic3d_Camera::Graphic3d_Camera (const Handle(Graphic3d_Camera)& theOther)
|
||||
{
|
||||
myWorldViewProjState.Initialize (this);
|
||||
|
||||
Copy (theOther);
|
||||
}
|
||||
|
||||
@@ -98,17 +102,18 @@ Graphic3d_Camera::Graphic3d_Camera (const Handle(Graphic3d_Camera)& theOther)
|
||||
// =======================================================================
|
||||
void Graphic3d_Camera::CopyMappingData (const Handle(Graphic3d_Camera)& theOtherCamera)
|
||||
{
|
||||
myFOVy = theOtherCamera->myFOVy;
|
||||
myZNear = theOtherCamera->myZNear;
|
||||
myZFar = theOtherCamera->myZFar;
|
||||
myAspect = theOtherCamera->myAspect;
|
||||
myScale = theOtherCamera->myScale;
|
||||
myZFocus = theOtherCamera->myZFocus;
|
||||
myZFocusType = theOtherCamera->myZFocusType;
|
||||
myIOD = theOtherCamera->myIOD;
|
||||
myIODType = theOtherCamera->myIODType;
|
||||
myProjType = theOtherCamera->myProjType;
|
||||
myProjectionState = theOtherCamera->myProjectionState;
|
||||
myFOVy = theOtherCamera->myFOVy;
|
||||
myZNear = theOtherCamera->myZNear;
|
||||
myZFar = theOtherCamera->myZFar;
|
||||
myAspect = theOtherCamera->myAspect;
|
||||
myScale = theOtherCamera->myScale;
|
||||
myZFocus = theOtherCamera->myZFocus;
|
||||
myZFocusType = theOtherCamera->myZFocusType;
|
||||
myIOD = theOtherCamera->myIOD;
|
||||
myIODType = theOtherCamera->myIODType;
|
||||
myProjType = theOtherCamera->myProjType;
|
||||
|
||||
myWorldViewProjState.ProjectionState() = theOtherCamera->ProjectionState();
|
||||
|
||||
InvalidateProjection();
|
||||
}
|
||||
@@ -119,11 +124,12 @@ void Graphic3d_Camera::CopyMappingData (const Handle(Graphic3d_Camera)& theOther
|
||||
// =======================================================================
|
||||
void Graphic3d_Camera::CopyOrientationData (const Handle(Graphic3d_Camera)& theOtherCamera)
|
||||
{
|
||||
myUp = theOtherCamera->myUp;
|
||||
myEye = theOtherCamera->myEye;
|
||||
myCenter = theOtherCamera->myCenter;
|
||||
myAxialScale = theOtherCamera->myAxialScale;
|
||||
myOrientationState = theOtherCamera->myOrientationState;
|
||||
myUp = theOtherCamera->myUp;
|
||||
myEye = theOtherCamera->myEye;
|
||||
myCenter = theOtherCamera->myCenter;
|
||||
myAxialScale = theOtherCamera->myAxialScale;
|
||||
|
||||
myWorldViewProjState.WorldViewState() = theOtherCamera->WorldViewState();
|
||||
|
||||
InvalidateOrientation();
|
||||
}
|
||||
@@ -847,7 +853,7 @@ void Graphic3d_Camera::InvalidateProjection()
|
||||
{
|
||||
myMatricesD.ResetProjection();
|
||||
myMatricesF.ResetProjection();
|
||||
myProjectionState = (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER);
|
||||
myWorldViewProjState.ProjectionState() = (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -858,7 +864,7 @@ void Graphic3d_Camera::InvalidateOrientation()
|
||||
{
|
||||
myMatricesD.ResetOrientation();
|
||||
myMatricesF.ResetOrientation();
|
||||
myOrientationState = (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER);
|
||||
myWorldViewProjState.WorldViewState() = (Standard_Size)Standard_Atomic_Increment (&THE_STATE_COUNTER);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#include <Graphic3d_Mat4d.hxx>
|
||||
#include <Graphic3d_Mat4.hxx>
|
||||
#include <Graphic3d_Vec3.hxx>
|
||||
#include <Graphic3d_WorldViewProjState.hxx>
|
||||
|
||||
#include <NCollection_Handle.hxx>
|
||||
|
||||
@@ -31,6 +32,7 @@
|
||||
#include <Bnd_Box.hxx>
|
||||
|
||||
//! Forward declaration
|
||||
class Graphic3d_WorldViewProjState;
|
||||
|
||||
//! Camera class provides object-oriented approach to setting up projection
|
||||
//! and orientation properties of 3D view.
|
||||
@@ -436,16 +438,23 @@ public:
|
||||
//! @name Camera modification state
|
||||
public:
|
||||
|
||||
//! @return projection modification state of the camera.
|
||||
const Graphic3d_WorldViewProjState& WorldViewProjState() const
|
||||
{
|
||||
return myWorldViewProjState;
|
||||
}
|
||||
|
||||
|
||||
//! Returns modification state of camera projection matrix
|
||||
Standard_Size ProjectionState() const
|
||||
{
|
||||
return myProjectionState;
|
||||
return myWorldViewProjState.ProjectionState();
|
||||
}
|
||||
|
||||
//! Returns modification state of camera model-view matrix
|
||||
Standard_Size ModelViewState() const
|
||||
//! Returns modification state of camera world view transformation matrix.
|
||||
Standard_Size WorldViewState() const
|
||||
{
|
||||
return myOrientationState;
|
||||
return myWorldViewProjState.WorldViewState();
|
||||
}
|
||||
|
||||
//! @name Lazily-computed orientation and projection matrices derived from camera parameters
|
||||
@@ -613,13 +622,11 @@ private:
|
||||
mutable TransformMatrices<Standard_Real> myMatricesD;
|
||||
mutable TransformMatrices<Standard_ShortReal> myMatricesF;
|
||||
|
||||
mutable Standard_Size myProjectionState;
|
||||
mutable Standard_Size myOrientationState;
|
||||
mutable Graphic3d_WorldViewProjState myWorldViewProjState;
|
||||
|
||||
public:
|
||||
|
||||
DEFINE_STANDARD_RTTI(Graphic3d_Camera, Standard_Transient);
|
||||
|
||||
};
|
||||
|
||||
DEFINE_STANDARD_HANDLE (Graphic3d_Camera, Standard_Transient)
|
||||
|
@@ -132,7 +132,7 @@ void Graphic3d_Structure::CalculateBoundBox()
|
||||
{
|
||||
Graphic3d_BndBox4d aBox;
|
||||
addTransformed (aBox, Standard_True);
|
||||
if (aBox.IsValid() && myCStructure->TransformPersistence.Flag == 0)
|
||||
if (aBox.IsValid())
|
||||
{
|
||||
Graphic3d_Vec4 aMinPt (RealToShortReal (aBox.CornerMin().x()),
|
||||
RealToShortReal (aBox.CornerMin().y()),
|
||||
@@ -1689,14 +1689,10 @@ void Graphic3d_Structure::SetTransformPersistence (const Graphic3d_TransModeFlag
|
||||
{
|
||||
if (IsDeleted()) return;
|
||||
|
||||
myCStructure->TransformPersistence.Flag = theFlag;
|
||||
myCStructure->TransformPersistence.Point.x = float (thePoint.X());
|
||||
myCStructure->TransformPersistence.Point.y = float (thePoint.Y());
|
||||
myCStructure->TransformPersistence.Point.z = float (thePoint.Z());
|
||||
myCStructure->UpdateAspects();
|
||||
CalculateBoundBox();
|
||||
|
||||
myCStructure->TransformPersistence.IsSet = 1;
|
||||
myCStructure->TransformPersistence.Flags = theFlag;
|
||||
myCStructure->TransformPersistence.Point.x() = thePoint.X();
|
||||
myCStructure->TransformPersistence.Point.y() = thePoint.Y();
|
||||
myCStructure->TransformPersistence.Point.z() = thePoint.Z();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
@@ -1705,7 +1701,7 @@ void Graphic3d_Structure::SetTransformPersistence (const Graphic3d_TransModeFlag
|
||||
//=============================================================================
|
||||
Graphic3d_TransModeFlags Graphic3d_Structure::TransformPersistenceMode() const
|
||||
{
|
||||
return myCStructure->TransformPersistence.Flag;
|
||||
return myCStructure->TransformPersistence.Flags;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
@@ -1715,9 +1711,9 @@ Graphic3d_TransModeFlags Graphic3d_Structure::TransformPersistenceMode() const
|
||||
gp_Pnt Graphic3d_Structure::TransformPersistencePoint() const
|
||||
{
|
||||
gp_Pnt aPnt (0.0, 0.0, 0.0);
|
||||
aPnt.SetX (myCStructure->TransformPersistence.Point.x);
|
||||
aPnt.SetY (myCStructure->TransformPersistence.Point.y);
|
||||
aPnt.SetZ (myCStructure->TransformPersistence.Point.z);
|
||||
aPnt.SetX (myCStructure->TransformPersistence.Point.x());
|
||||
aPnt.SetY (myCStructure->TransformPersistence.Point.y());
|
||||
aPnt.SetZ (myCStructure->TransformPersistence.Point.z());
|
||||
return aPnt;
|
||||
}
|
||||
|
||||
|
@@ -38,6 +38,7 @@
|
||||
#include <Graphic3d_TypeOfConnection.hxx>
|
||||
#include <Graphic3d_MapOfStructure.hxx>
|
||||
#include <Graphic3d_TypeOfComposition.hxx>
|
||||
#include <Graphic3d_TransformPers.hxx>
|
||||
#include <Graphic3d_TransModeFlags.hxx>
|
||||
#include <Graphic3d_BndBox4f.hxx>
|
||||
#include <Graphic3d_BndBox4d.hxx>
|
||||
@@ -438,7 +439,10 @@ public:
|
||||
|
||||
//! Get the current point of relative modelling transform persistence
|
||||
Standard_EXPORT gp_Pnt TransformPersistencePoint() const;
|
||||
|
||||
|
||||
//! @return transform persistence of the presentable object.
|
||||
const Graphic3d_TransformPers& TransformPersistence() const;
|
||||
|
||||
//! Sets if the structure location has mutable nature (content or location will be changed regularly).
|
||||
Standard_EXPORT void SetMutable (const Standard_Boolean theIsMutable);
|
||||
|
||||
|
@@ -21,3 +21,12 @@ inline const Handle(Graphic3d_CStructure)& Graphic3d_Structure::CStructure() con
|
||||
{
|
||||
return myCStructure;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : TransformPersistence
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
inline const Graphic3d_TransformPers& Graphic3d_Structure::TransformPersistence() const
|
||||
{
|
||||
return myCStructure->TransformPersistence;
|
||||
}
|
||||
|
357
src/Graphic3d/Graphic3d_TransformPers.hxx
Normal file
357
src/Graphic3d/Graphic3d_TransformPers.hxx
Normal file
@@ -0,0 +1,357 @@
|
||||
// Created on: 2015-06-18
|
||||
// Created by: Anton POLETAEV
|
||||
// Copyright (c) 2015 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _Graphic3d_TransformPers_HeaderFile
|
||||
#define _Graphic3d_TransformPers_HeaderFile
|
||||
|
||||
#include <Bnd_Box.hxx>
|
||||
#include <BVH_Box.hxx>
|
||||
#include <Graphic3d_TransformUtils.hxx>
|
||||
#include <Graphic3d_TransModeFlags.hxx>
|
||||
#include <NCollection_Mat4.hxx>
|
||||
#include <NCollection_Vec4.hxx>
|
||||
|
||||
//! Class for keeping and computing transformation persistence.
|
||||
class Graphic3d_TransformPers
|
||||
{
|
||||
public:
|
||||
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
//! Default constructor.
|
||||
Graphic3d_TransformPers()
|
||||
: Flags (Graphic3d_TMF_None),
|
||||
Point (0.0, 0.0, 0.0) {}
|
||||
|
||||
//! Transformation persistence mode flags.
|
||||
Graphic3d_TransModeFlags Flags;
|
||||
|
||||
//! Reference point for transformation.
|
||||
Graphic3d_Vec3d Point;
|
||||
|
||||
public:
|
||||
|
||||
//! Apply transformation to bounding box of presentation.
|
||||
//! @param theProjection [in] the projection transformation matrix.
|
||||
//! @param theWorldView [in] the world view transformation matrix.
|
||||
//! @param theViewportWidth [in] the width of viewport (for 2d persistence).
|
||||
//! @param theViewportHeight [in] the height of viewport (for 2d persistence).
|
||||
//! @param theBoundingBox [in/out] the bounding box to transform.
|
||||
template<class T>
|
||||
void Apply (const NCollection_Mat4<T>& theProjection,
|
||||
const NCollection_Mat4<T>& theWorldView,
|
||||
const Standard_Integer theViewportWidth,
|
||||
const Standard_Integer theViewportHeight,
|
||||
Bnd_Box& theBoundingBox) const;
|
||||
|
||||
//! Apply transformation to bounding box of presentation
|
||||
//! @param theProjection [in] the projection transformation matrix.
|
||||
//! @param theWorldView [in] the world view transformation matrix.
|
||||
//! @param theViewportWidth [in] the width of viewport (for 2d persistence).
|
||||
//! @param theViewportHeight [in] the height of viewport (for 2d persistence).
|
||||
//! @param theBoundingBox [in/out] the bounding box to transform.
|
||||
template<class T>
|
||||
void Apply (const NCollection_Mat4<T>& theProjection,
|
||||
const NCollection_Mat4<T>& theWorldView,
|
||||
const Standard_Integer theViewportWidth,
|
||||
const Standard_Integer theViewportHeight,
|
||||
BVH_Box<T, 4>& theBoundingBox) const;
|
||||
|
||||
//! Compute transformation.
|
||||
//! Computed matrix can be applied to model world transformation
|
||||
//! of an object to implement effect of transformation persistence.
|
||||
//! @param theProjection [in] the projection transformation matrix.
|
||||
//! @param theWorldView [in] the world view transformation matrix.
|
||||
//! @param theViewportWidth [in] the width of viewport (for 2d persistence).
|
||||
//! @param theViewportHeight [in] the height of viewport (for 2d persistence).
|
||||
//! @return transformation matrix to be applied to model world transformation of an object.
|
||||
template<class T>
|
||||
NCollection_Mat4<T> Compute (const NCollection_Mat4<T>& theProjection,
|
||||
const NCollection_Mat4<T>& theWorldView,
|
||||
const Standard_Integer theViewportWidth,
|
||||
const Standard_Integer theViewportHeight) const;
|
||||
|
||||
template<class T>
|
||||
void Apply (NCollection_Mat4<T>& theProjection,
|
||||
NCollection_Mat4<T>& theWorldView,
|
||||
const Standard_Integer theViewportWidth,
|
||||
const Standard_Integer theViewportHeight) const;
|
||||
};
|
||||
|
||||
// =======================================================================
|
||||
// function : Apply
|
||||
// purpose : Apply transformation to world view and projection matrices.
|
||||
// =======================================================================
|
||||
template<class T>
|
||||
void Graphic3d_TransformPers::Apply (NCollection_Mat4<T>& theProjection,
|
||||
NCollection_Mat4<T>& theWorldView,
|
||||
const Standard_Integer theViewportWidth,
|
||||
const Standard_Integer theViewportHeight) const
|
||||
{
|
||||
if (!Flags)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Flags & Graphic3d_TMF_2d)
|
||||
{
|
||||
T aLeft = -static_cast<T> (theViewportWidth / 2);
|
||||
T aRight = static_cast<T> (theViewportWidth / 2);
|
||||
T aBottom = -static_cast<T> (theViewportHeight / 2);
|
||||
T aTop = static_cast<T> (theViewportHeight / 2);
|
||||
T aGap = static_cast<T> (Point.z());
|
||||
if (Point.x() > 0)
|
||||
{
|
||||
aLeft -= static_cast<T> (theViewportWidth / 2) - aGap;
|
||||
aRight -= static_cast<T> (theViewportWidth / 2) - aGap;
|
||||
}
|
||||
else if (Point.x() < 0)
|
||||
{
|
||||
aLeft += static_cast<T> (theViewportWidth / 2) - aGap;
|
||||
aRight += static_cast<T> (theViewportWidth / 2) - aGap;
|
||||
}
|
||||
if (Point.y() > 0)
|
||||
{
|
||||
aBottom -= static_cast<T> (theViewportHeight / 2) - aGap;
|
||||
aTop -= static_cast<T> (theViewportHeight / 2) - aGap;
|
||||
}
|
||||
else if (Point.y() < 0)
|
||||
{
|
||||
aBottom += static_cast<T> (theViewportHeight / 2) - aGap;
|
||||
aTop += static_cast<T> (theViewportHeight / 2) - aGap;
|
||||
}
|
||||
if (Flags == Graphic3d_TMF_2d_IsTopDown)
|
||||
{
|
||||
const T aTemp = aTop;
|
||||
aTop = aBottom;
|
||||
aBottom = aTemp;
|
||||
}
|
||||
|
||||
Graphic3d_TransformUtils::Ortho2D<T> (theProjection, aLeft, aRight, aBottom, aTop);
|
||||
|
||||
theWorldView.InitIdentity();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Compute reference point for transformation in untransformed projection space.
|
||||
NCollection_Vec4<T> aRefPoint (static_cast<T> (Point.x()),
|
||||
static_cast<T> (Point.y()),
|
||||
static_cast<T> (Point.z()),
|
||||
static_cast<T> (1.0));
|
||||
NCollection_Vec4<T> aRefPointProj;
|
||||
if ((Flags & Graphic3d_TMF_PanPers) != Graphic3d_TMF_PanPers)
|
||||
{
|
||||
aRefPointProj = theProjection * (theWorldView * aRefPoint);
|
||||
aRefPointProj /= aRefPointProj.w();
|
||||
}
|
||||
|
||||
// Prevent zooming.
|
||||
if ((Flags & Graphic3d_TMF_ZoomPers) || (Flags == Graphic3d_TMF_TriedronPers))
|
||||
{
|
||||
// Compute fixed-zoom multiplier. Actually function works ugly with TelPerspective!
|
||||
const T aDet2 = static_cast<T> (0.002) / Max (theProjection.GetValue (1, 1), theProjection.GetValue (0, 0));
|
||||
theProjection.ChangeValue (0, 0) *= aDet2;
|
||||
theProjection.ChangeValue (1, 1) *= aDet2;
|
||||
theProjection.ChangeValue (2, 2) *= aDet2;
|
||||
}
|
||||
|
||||
// Prevent translation by nullifying translation component.
|
||||
if ((Flags & Graphic3d_TMF_PanPers) || Flags == Graphic3d_TMF_TriedronPers)
|
||||
{
|
||||
theWorldView .SetValue (0, 3, static_cast<T> (0.0));
|
||||
theWorldView .SetValue (1, 3, static_cast<T> (0.0));
|
||||
theWorldView .SetValue (2, 3, static_cast<T> (0.0));
|
||||
theProjection.SetValue (0, 3, static_cast<T> (0.0));
|
||||
theProjection.SetValue (1, 3, static_cast<T> (0.0));
|
||||
theProjection.SetValue (2, 3, static_cast<T> (0.0));
|
||||
}
|
||||
|
||||
// Prevent scaling-on-axis.
|
||||
if (Flags & Graphic3d_TMF_ZoomPers)
|
||||
{
|
||||
NCollection_Vec3<T> aVecX = theWorldView.GetColumn (0).xyz();
|
||||
NCollection_Vec3<T> aVecY = theWorldView.GetColumn (1).xyz();
|
||||
NCollection_Vec3<T> aVecZ = theWorldView.GetColumn (2).xyz();
|
||||
T aScaleX = aVecX.Modulus();
|
||||
T aScaleY = aVecY.Modulus();
|
||||
T aScaleZ = aVecZ.Modulus();
|
||||
for (Standard_Integer anI = 0; anI < 3; ++anI)
|
||||
{
|
||||
theWorldView.ChangeValue (0, anI) /= aScaleX;
|
||||
theWorldView.ChangeValue (1, anI) /= aScaleY;
|
||||
theWorldView.ChangeValue (2, anI) /= aScaleZ;
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent rotation by nullifying rotation component.
|
||||
if (Flags & Graphic3d_TMF_RotatePers)
|
||||
{
|
||||
theWorldView.SetValue (0, 0, static_cast<T> (1.0));
|
||||
theWorldView.SetValue (1, 0, static_cast<T> (0.0));
|
||||
theWorldView.SetValue (2, 0, static_cast<T> (0.0));
|
||||
|
||||
theWorldView.SetValue (0, 1, static_cast<T> (0.0));
|
||||
theWorldView.SetValue (1, 1, static_cast<T> (1.0));
|
||||
theWorldView.SetValue (2, 1, static_cast<T> (0.0));
|
||||
|
||||
theWorldView.SetValue (0, 2, static_cast<T> (0.0));
|
||||
theWorldView.SetValue (1, 2, static_cast<T> (0.0));
|
||||
theWorldView.SetValue (2, 2, static_cast<T> (1.0));
|
||||
}
|
||||
|
||||
if (Flags == Graphic3d_TMF_TriedronPers)
|
||||
{
|
||||
if (Point.x() != 0.0 && Point.y() != 0.0)
|
||||
{
|
||||
NCollection_Mat4<T> anUnviewMat;
|
||||
|
||||
if (!(theProjection).Inverted (anUnviewMat))
|
||||
{
|
||||
Standard_ProgramError::Raise ("Graphic3d_TransformPers::Apply, can not inverse projection matrix.");
|
||||
}
|
||||
|
||||
NCollection_Vec4<T> aProjMax (static_cast<T> ( 1.0), static_cast<T> ( 1.0), static_cast<T> (0.0), static_cast<T> (1.0));
|
||||
NCollection_Vec4<T> aProjMin (static_cast<T> (-1.0), static_cast<T> (-1.0), static_cast<T> (0.0), static_cast<T> (1.0));
|
||||
NCollection_Vec4<T> aViewMax = anUnviewMat * aProjMax;
|
||||
NCollection_Vec4<T> aViewMin = anUnviewMat * aProjMin;
|
||||
|
||||
aViewMax /= aViewMax.w();
|
||||
aViewMin /= aViewMin.w();
|
||||
|
||||
T aMoveX = static_cast<T> (0.5) * (aViewMax.x() - aViewMin.x() - static_cast<T> (Point.z()));
|
||||
T aMoveY = static_cast<T> (0.5) * (aViewMax.y() - aViewMin.y() - static_cast<T> (Point.z()));
|
||||
|
||||
aMoveX = (Point.x() > 0.0) ? aMoveX : -aMoveX;
|
||||
aMoveY = (Point.y() > 0.0) ? aMoveY : -aMoveY;
|
||||
|
||||
Graphic3d_TransformUtils::Translate<T> (theProjection, aMoveX, aMoveY, static_cast<T> (0.0));
|
||||
}
|
||||
}
|
||||
else if ((Flags & Graphic3d_TMF_PanPers) != Graphic3d_TMF_PanPers)
|
||||
{
|
||||
NCollection_Mat4<T> anUnviewMat;
|
||||
|
||||
if (!(theProjection * theWorldView).Inverted (anUnviewMat))
|
||||
{
|
||||
Standard_ProgramError::Raise ("Graphic3d_TransformPers::Apply, can not inverse world view projection matrix.");
|
||||
}
|
||||
|
||||
// Move to reference point location in transformed view projection space.
|
||||
aRefPoint = anUnviewMat * aRefPointProj;
|
||||
aRefPoint /= aRefPoint.w();
|
||||
|
||||
Graphic3d_TransformUtils::Translate<T> (theWorldView, aRefPoint.x(), aRefPoint.y(), aRefPoint.z());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Apply
|
||||
// purpose : Apply transformation to bounding box of presentation.
|
||||
// =======================================================================
|
||||
template<class T>
|
||||
void Graphic3d_TransformPers::Apply (const NCollection_Mat4<T>& theProjection,
|
||||
const NCollection_Mat4<T>& theWorldView,
|
||||
const Standard_Integer theViewportWidth,
|
||||
const Standard_Integer theViewportHeight,
|
||||
Bnd_Box& theBoundingBox) const
|
||||
{
|
||||
T aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
|
||||
|
||||
theBoundingBox.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
|
||||
|
||||
typename BVH_Box<T, 4>::BVH_VecNt aMin (aXmin, aYmin, aZmin, static_cast<T> (1.0));
|
||||
typename BVH_Box<T, 4>::BVH_VecNt aMax (aXmax, aYmax, aZmax, static_cast<T> (1.0));
|
||||
BVH_Box<T, 4> aBBox (aMin, aMax);
|
||||
|
||||
Apply (theProjection, theWorldView, theViewportWidth, theViewportHeight, aBBox);
|
||||
|
||||
theBoundingBox = Bnd_Box();
|
||||
theBoundingBox.Update (aBBox.CornerMin().x(), aBBox.CornerMin().y(), aBBox.CornerMin().z(),
|
||||
aBBox.CornerMax().x(), aBBox.CornerMax().y(), aBBox.CornerMax().z());
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Apply
|
||||
// purpose : Apply transformation to bounding box of presentation.
|
||||
// =======================================================================
|
||||
template<class T>
|
||||
void Graphic3d_TransformPers::Apply (const NCollection_Mat4<T>& theProjection,
|
||||
const NCollection_Mat4<T>& theWorldView,
|
||||
const Standard_Integer theViewportWidth,
|
||||
const Standard_Integer theViewportHeight,
|
||||
BVH_Box<T, 4>& theBoundingBox) const
|
||||
{
|
||||
NCollection_Mat4<T> aTPers = Compute (theProjection, theWorldView, theViewportWidth, theViewportHeight);
|
||||
|
||||
if (aTPers.IsIdentity())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const typename BVH_Box<T, 4>::BVH_VecNt& aMin = theBoundingBox.CornerMin();
|
||||
const typename BVH_Box<T, 4>::BVH_VecNt& aMax = theBoundingBox.CornerMax();
|
||||
|
||||
typename BVH_Box<T, 4>::BVH_VecNt anArrayOfCorners[8];
|
||||
anArrayOfCorners[0] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMin.y(), aMin.z(), static_cast<T> (1.0));
|
||||
anArrayOfCorners[1] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMin.y(), aMax.z(), static_cast<T> (1.0));
|
||||
anArrayOfCorners[2] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMax.y(), aMin.z(), static_cast<T> (1.0));
|
||||
anArrayOfCorners[3] = typename BVH_Box<T, 4>::BVH_VecNt (aMin.x(), aMax.y(), aMax.z(), static_cast<T> (1.0));
|
||||
anArrayOfCorners[4] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMin.y(), aMin.z(), static_cast<T> (1.0));
|
||||
anArrayOfCorners[5] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMin.y(), aMax.z(), static_cast<T> (1.0));
|
||||
anArrayOfCorners[6] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMax.y(), aMin.z(), static_cast<T> (1.0));
|
||||
anArrayOfCorners[7] = typename BVH_Box<T, 4>::BVH_VecNt (aMax.x(), aMax.y(), aMax.z(), static_cast<T> (1.0));
|
||||
|
||||
theBoundingBox.Clear();
|
||||
for (Standard_Integer anIt = 0; anIt < 8; ++anIt)
|
||||
{
|
||||
typename BVH_Box<T, 4>::BVH_VecNt& aCorner = anArrayOfCorners[anIt];
|
||||
aCorner = aTPers * aCorner;
|
||||
aCorner /= aCorner.w();
|
||||
theBoundingBox.Add (aCorner);
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Compute
|
||||
// purpose : Compute transformation.
|
||||
// =======================================================================
|
||||
template<class T>
|
||||
NCollection_Mat4<T> Graphic3d_TransformPers::Compute (const NCollection_Mat4<T>& theProjection,
|
||||
const NCollection_Mat4<T>& theWorldView,
|
||||
const Standard_Integer theViewportWidth,
|
||||
const Standard_Integer theViewportHeight) const
|
||||
{
|
||||
if (Flags == Graphic3d_TMF_None)
|
||||
{
|
||||
return NCollection_Mat4<T>();
|
||||
}
|
||||
|
||||
NCollection_Mat4<T> anUnviewMat;
|
||||
|
||||
if (!(theProjection * theWorldView).Inverted (anUnviewMat))
|
||||
{
|
||||
return NCollection_Mat4<T>();
|
||||
}
|
||||
|
||||
NCollection_Mat4<T> aProjection (theProjection);
|
||||
NCollection_Mat4<T> aWorldView (theWorldView);
|
||||
|
||||
Apply (aProjection, aWorldView, theViewportWidth, theViewportHeight);
|
||||
|
||||
return anUnviewMat * (aProjection * aWorldView);
|
||||
}
|
||||
|
||||
#endif // _Graphic3d_TransformPers_HeaderFile
|
452
src/Graphic3d/Graphic3d_TransformUtils.hxx
Normal file
452
src/Graphic3d/Graphic3d_TransformUtils.hxx
Normal file
@@ -0,0 +1,452 @@
|
||||
// Created on: 2015-06-18
|
||||
// Copyright (c) 2015 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _Graphic3d_TransformUtils_HeaderFile
|
||||
#define _Graphic3d_TransformUtils_HeaderFile
|
||||
|
||||
#include <Graphic3d_Vec.hxx>
|
||||
#include <Standard_math.hxx> // M_PI
|
||||
|
||||
//! Helper class that implements transformation matrix functionality.
|
||||
namespace Graphic3d_TransformUtils
|
||||
{
|
||||
template<class T> struct MatrixType {};
|
||||
|
||||
template<> struct MatrixType<Standard_Real> { typedef Graphic3d_Mat4d Mat4; };
|
||||
|
||||
template<> struct MatrixType<Standard_ShortReal> { typedef Graphic3d_Mat4 Mat4; };
|
||||
|
||||
template<class T> struct VectorType {};
|
||||
|
||||
template<> struct VectorType<Standard_Real> {
|
||||
typedef Graphic3d_Vec2d Vec2;
|
||||
typedef Graphic3d_Vec3d Vec3;
|
||||
typedef Graphic3d_Vec4d Vec4;
|
||||
};
|
||||
|
||||
template<> struct VectorType<Standard_ShortReal> {
|
||||
typedef Graphic3d_Vec2 Vec2;
|
||||
typedef Graphic3d_Vec3 Vec3;
|
||||
typedef Graphic3d_Vec4 Vec4;
|
||||
};
|
||||
|
||||
//! Constructs a 3D orthographic projection matrix.
|
||||
template<class T>
|
||||
static void Ortho (typename MatrixType<T>::Mat4& theOut,
|
||||
const T theLeft,
|
||||
const T theRight,
|
||||
const T theBottom,
|
||||
const T theTop,
|
||||
const T theZNear,
|
||||
const T theZFar);
|
||||
|
||||
//! Constructs a 2D orthographic projection matrix.
|
||||
template<class T>
|
||||
static void Ortho2D (typename MatrixType<T>::Mat4& theOut,
|
||||
const T theLeft,
|
||||
const T theRight,
|
||||
const T theBottom,
|
||||
const T theTop);
|
||||
|
||||
//! Maps object coordinates to window coordinates.
|
||||
template<class T>
|
||||
static Standard_Boolean Project (const T theObjX,
|
||||
const T theObjY,
|
||||
const T theObjZ,
|
||||
const typename MatrixType<T>::Mat4& theModViewMat,
|
||||
const typename MatrixType<T>::Mat4& theProjectMat,
|
||||
const Standard_Integer theViewport[4],
|
||||
T& theWinX,
|
||||
T& theWinY,
|
||||
T& theWinZ);
|
||||
|
||||
//! Maps window coordinates to object coordinates.
|
||||
template<class T>
|
||||
static Standard_Boolean UnProject (const T theWinX,
|
||||
const T theWinY,
|
||||
const T theWinZ,
|
||||
const typename MatrixType<T>::Mat4& theModViewMat,
|
||||
const typename MatrixType<T>::Mat4& theProjectMat,
|
||||
const Standard_Integer theViewport[4],
|
||||
T& theObjX,
|
||||
T& theObjY,
|
||||
T& theObjZ);
|
||||
|
||||
//! Constructs a 4x4 rotation matrix.
|
||||
template<class T>
|
||||
static void ConstructRotate (typename MatrixType<T>::Mat4& theOut,
|
||||
T theA,
|
||||
T theX,
|
||||
T theY,
|
||||
T theZ);
|
||||
|
||||
//! Constructs a 4x4 rotation matrix.
|
||||
template<class T>
|
||||
static void Rotate (typename MatrixType<T>::Mat4& theOut,
|
||||
T theA,
|
||||
T theX,
|
||||
T theY,
|
||||
T theZ);
|
||||
|
||||
//! Constructs a 4x4 scaling matrix.
|
||||
template<class T>
|
||||
static void Scale (typename MatrixType<T>::Mat4& theOut,
|
||||
T theX,
|
||||
T theY,
|
||||
T theZ);
|
||||
|
||||
//! Constructs a 4x4 translation matrix.
|
||||
template<class T>
|
||||
static void Translate (typename MatrixType<T>::Mat4& theOut,
|
||||
T theX,
|
||||
T theY,
|
||||
T theZ);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Rotate
|
||||
// purpose : Constructs a 4x4 rotation matrix
|
||||
// =======================================================================
|
||||
template<class T>
|
||||
void Graphic3d_TransformUtils::Rotate (typename MatrixType<T>::Mat4& theOut,
|
||||
T theA,
|
||||
T theX,
|
||||
T theY,
|
||||
T theZ)
|
||||
{
|
||||
typename MatrixType<T>::Mat4 aMat;
|
||||
ConstructRotate (aMat, theA, theX, theY, theZ);
|
||||
theOut = theOut * aMat;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Translate
|
||||
// purpose : Constructs a 4x4 translation matrix
|
||||
// =======================================================================
|
||||
template<class T>
|
||||
void Graphic3d_TransformUtils::Translate (typename MatrixType<T>::Mat4& theOut,
|
||||
T theX,
|
||||
T theY,
|
||||
T theZ)
|
||||
{
|
||||
theOut.ChangeValue (0, 3) = theOut.GetValue (0, 0) * theX +
|
||||
theOut.GetValue (0, 1) * theY +
|
||||
theOut.GetValue (0, 2) * theZ +
|
||||
theOut.GetValue (0, 3);
|
||||
|
||||
theOut.ChangeValue (1, 3) = theOut.GetValue (1, 0) * theX +
|
||||
theOut.GetValue (1, 1) * theY +
|
||||
theOut.GetValue (1, 2) * theZ +
|
||||
theOut.GetValue (1, 3);
|
||||
|
||||
theOut.ChangeValue (2, 3) = theOut.GetValue (2, 0) * theX +
|
||||
theOut.GetValue (2, 1) * theY +
|
||||
theOut.GetValue (2, 2) * theZ +
|
||||
theOut.GetValue (2, 3);
|
||||
|
||||
theOut.ChangeValue (3, 3) = theOut.GetValue (3, 0) * theX +
|
||||
theOut.GetValue (3, 1) * theY +
|
||||
theOut.GetValue (3, 2) * theZ +
|
||||
theOut.GetValue (3, 3);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Scale
|
||||
// purpose : Constructs a 4x4 scaling matrix
|
||||
// =======================================================================
|
||||
template<class T>
|
||||
void Graphic3d_TransformUtils::Scale (typename MatrixType<T>::Mat4& theOut,
|
||||
T theX,
|
||||
T theY,
|
||||
T theZ)
|
||||
{
|
||||
theOut.ChangeValue (0, 0) *= theX;
|
||||
theOut.ChangeValue (1, 0) *= theX;
|
||||
theOut.ChangeValue (2, 0) *= theX;
|
||||
theOut.ChangeValue (3, 0) *= theX;
|
||||
|
||||
theOut.ChangeValue (0, 1) *= theY;
|
||||
theOut.ChangeValue (1, 1) *= theY;
|
||||
theOut.ChangeValue (2, 1) *= theY;
|
||||
theOut.ChangeValue (3, 1) *= theY;
|
||||
|
||||
theOut.ChangeValue (0, 2) *= theZ;
|
||||
theOut.ChangeValue (1, 2) *= theZ;
|
||||
theOut.ChangeValue (2, 2) *= theZ;
|
||||
theOut.ChangeValue (3, 2) *= theZ;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : ConstructRotate
|
||||
// purpose : Constructs a 4x4 rotation matrix
|
||||
// =======================================================================
|
||||
template<class T>
|
||||
void Graphic3d_TransformUtils::ConstructRotate (typename MatrixType<T>::Mat4& theOut,
|
||||
T theA,
|
||||
T theX,
|
||||
T theY,
|
||||
T theZ)
|
||||
{
|
||||
const T aSin = std::sin (theA * static_cast<T> (M_PI / 180.0));
|
||||
const T aCos = std::cos (theA * static_cast<T> (M_PI / 180.0));
|
||||
|
||||
const Standard_Boolean isOnlyX = (theX != static_cast<T> (0.0))
|
||||
&& (theY == static_cast<T> (0.0))
|
||||
&& (theZ == static_cast<T> (0.0));
|
||||
|
||||
const Standard_Boolean isOnlyY = (theX == static_cast<T> (0.0))
|
||||
&& (theY != static_cast<T> (0.0))
|
||||
&& (theZ == static_cast<T> (0.0));
|
||||
|
||||
const Standard_Boolean isOnlyZ = (theX == static_cast<T> (0.0))
|
||||
&& (theY == static_cast<T> (0.0))
|
||||
&& (theZ != static_cast<T> (0.0));
|
||||
|
||||
if (isOnlyX) // Rotation only around X.
|
||||
{
|
||||
theOut.SetValue (1, 1, aCos);
|
||||
theOut.SetValue (2, 2, aCos);
|
||||
|
||||
if (theX < static_cast<T> (0.0))
|
||||
{
|
||||
theOut.SetValue (1, 2, aSin);
|
||||
theOut.SetValue (2, 1, -aSin);
|
||||
}
|
||||
else
|
||||
{
|
||||
theOut.SetValue (1, 2, -aSin);
|
||||
theOut.SetValue (2, 1, aSin);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else if (isOnlyY) // Rotation only around Y.
|
||||
{
|
||||
theOut.SetValue (0, 0, aCos);
|
||||
theOut.SetValue (2, 2, aCos);
|
||||
|
||||
if (theY < static_cast<T> (0.0))
|
||||
{
|
||||
theOut.SetValue (0, 2, -aSin);
|
||||
theOut.SetValue (2, 0, aSin);
|
||||
}
|
||||
else
|
||||
{
|
||||
theOut.SetValue (0, 2, aSin);
|
||||
theOut.SetValue (2, 0, -aSin);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else if (isOnlyZ) // Rotation only around Z.
|
||||
{
|
||||
theOut.SetValue (0, 0, aCos);
|
||||
theOut.SetValue (1, 1, aCos);
|
||||
|
||||
if (theZ < static_cast<T> (0.0))
|
||||
{
|
||||
theOut.SetValue (0, 1, aSin);
|
||||
theOut.SetValue (1, 0, -aSin);
|
||||
}
|
||||
else
|
||||
{
|
||||
theOut.SetValue (0, 1, -aSin);
|
||||
theOut.SetValue (1, 0, aSin);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
T aNorm = std::sqrt (theX * theX + theY * theY + theZ * theZ);
|
||||
|
||||
if (aNorm <= static_cast<T> (1.0e-4))
|
||||
{
|
||||
return; // Negligible rotation.
|
||||
}
|
||||
|
||||
aNorm = static_cast<T> (1.0) / aNorm;
|
||||
|
||||
theX *= aNorm;
|
||||
theY *= aNorm;
|
||||
theZ *= aNorm;
|
||||
|
||||
const T aXX = theX * theX;
|
||||
const T aYY = theY * theY;
|
||||
const T aZZ = theZ * theZ;
|
||||
const T aXY = theX * theY;
|
||||
const T aYZ = theY * theZ;
|
||||
const T aZX = theZ * theX;
|
||||
const T aSinX = theX * aSin;
|
||||
const T aSinY = theY * aSin;
|
||||
const T aSinZ = theZ * aSin;
|
||||
|
||||
const T aOneMinusCos = static_cast<T> (1.0) - aCos;
|
||||
|
||||
theOut.SetValue (0, 0, aOneMinusCos * aXX + aCos);
|
||||
theOut.SetValue (0, 1, aOneMinusCos * aXY - aSinZ);
|
||||
theOut.SetValue (0, 2, aOneMinusCos * aZX + aSinY);
|
||||
|
||||
theOut.SetValue (1, 0, aOneMinusCos * aXY + aSinZ);
|
||||
theOut.SetValue (1, 1, aOneMinusCos * aYY + aCos);
|
||||
theOut.SetValue (1, 2, aOneMinusCos * aYZ - aSinX);
|
||||
|
||||
theOut.SetValue (2, 0, aOneMinusCos * aZX - aSinY);
|
||||
theOut.SetValue (2, 1, aOneMinusCos * aYZ + aSinX);
|
||||
theOut.SetValue (2, 2, aOneMinusCos * aZZ + aCos);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Ortho
|
||||
// purpose : Constructs a 3D orthographic projection matrix
|
||||
// =======================================================================
|
||||
template<class T>
|
||||
void Graphic3d_TransformUtils::Ortho (typename MatrixType<T>::Mat4& theOut,
|
||||
const T theLeft,
|
||||
const T theRight,
|
||||
const T theBottom,
|
||||
const T theTop,
|
||||
const T theZNear,
|
||||
const T theZFar)
|
||||
{
|
||||
theOut.InitIdentity();
|
||||
|
||||
T* aData = theOut.ChangeData();
|
||||
|
||||
const T anInvDx = static_cast<T> (1.0) / (theRight - theLeft);
|
||||
const T anInvDy = static_cast<T> (1.0) / (theTop - theBottom);
|
||||
const T anInvDz = static_cast<T> (1.0) / (theZFar - theZNear);
|
||||
|
||||
aData[0] = static_cast<T> ( 2.0) * anInvDx;
|
||||
aData[5] = static_cast<T> ( 2.0) * anInvDy;
|
||||
aData[10] = static_cast<T> (-2.0) * anInvDz;
|
||||
|
||||
aData[12] = -(theRight + theLeft) * anInvDx;
|
||||
aData[13] = -(theTop + theBottom) * anInvDy;
|
||||
aData[14] = -(theZFar + theZNear) * anInvDz;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Ortho2D
|
||||
// purpose : Constructs a 2D orthographic projection matrix
|
||||
// =======================================================================
|
||||
template<class T>
|
||||
void Graphic3d_TransformUtils::Ortho2D (typename MatrixType<T>::Mat4& theOut,
|
||||
const T theLeft,
|
||||
const T theRight,
|
||||
const T theBottom,
|
||||
const T theTop)
|
||||
{
|
||||
Ortho (theOut, theLeft, theRight, theBottom, theTop, static_cast<T> (-1.0), static_cast<T> (1.0));
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Project
|
||||
// purpose : Maps object coordinates to window coordinates
|
||||
// =======================================================================
|
||||
template<class T>
|
||||
static Standard_Boolean Graphic3d_TransformUtils::Project (const T theObjX,
|
||||
const T theObjY,
|
||||
const T theObjZ,
|
||||
const typename MatrixType<T>::Mat4& theModViewMat,
|
||||
const typename MatrixType<T>::Mat4& theProjectMat,
|
||||
const Standard_Integer theViewport[4],
|
||||
T& theWinX,
|
||||
T& theWinY,
|
||||
T& theWinZ)
|
||||
{
|
||||
typename VectorType<T>::Vec4 anIn (theObjX, theObjY, theObjZ, static_cast<T> (1.0));
|
||||
|
||||
typename VectorType<T>::Vec4 anOut = theProjectMat * (theModViewMat * anIn);
|
||||
|
||||
if (anOut.w() == static_cast<T> (0.0))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
anOut.w() = static_cast<T> (1.0) / anOut.w();
|
||||
|
||||
anOut.x() *= anOut.w();
|
||||
anOut.y() *= anOut.w();
|
||||
anOut.z() *= anOut.w();
|
||||
|
||||
// Map x, y and z to range 0-1.
|
||||
anOut.x() = anOut.x() * static_cast<T> (0.5) + static_cast<T> (0.5);
|
||||
anOut.y() = anOut.y() * static_cast<T> (0.5) + static_cast<T> (0.5);
|
||||
anOut.z() = anOut.z() * static_cast<T> (0.5) + static_cast<T> (0.5);
|
||||
|
||||
// Map x,y to viewport.
|
||||
anOut.x() = anOut.x() * theViewport[2] + theViewport[0];
|
||||
anOut.y() = anOut.y() * theViewport[3] + theViewport[1];
|
||||
|
||||
theWinX = anOut.x();
|
||||
theWinY = anOut.y();
|
||||
theWinZ = anOut.z();
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : UnProject
|
||||
// purpose : Maps window coordinates to object coordinates
|
||||
// =======================================================================
|
||||
template<class T>
|
||||
static Standard_Boolean Graphic3d_TransformUtils::UnProject (const T theWinX,
|
||||
const T theWinY,
|
||||
const T theWinZ,
|
||||
const typename MatrixType<T>::Mat4& theModViewMat,
|
||||
const typename MatrixType<T>::Mat4& theProjectMat,
|
||||
const Standard_Integer theViewport[4],
|
||||
T& theObjX,
|
||||
T& theObjY,
|
||||
T& theObjZ)
|
||||
{
|
||||
typename MatrixType<T>::Mat4 anUnviewMat;
|
||||
|
||||
if (!(theProjectMat * theModViewMat).Inverted (anUnviewMat))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
typename VectorType<T>::Vec4 anIn (theWinX, theWinY, theWinZ, static_cast<T> (1.0));
|
||||
|
||||
// Map x and y from window coordinates.
|
||||
anIn.x() = (anIn.x() - theViewport[0]) / theViewport[2];
|
||||
anIn.y() = (anIn.y() - theViewport[1]) / theViewport[3];
|
||||
|
||||
// Map to range -1 to 1.
|
||||
anIn.x() = anIn.x() * static_cast<T> (2.0) - static_cast<T> (1.0);
|
||||
anIn.y() = anIn.y() * static_cast<T> (2.0) - static_cast<T> (1.0);
|
||||
anIn.z() = anIn.z() * static_cast<T> (2.0) - static_cast<T> (1.0);
|
||||
|
||||
typename VectorType<T>::Vec4 anOut = anUnviewMat * anIn;
|
||||
|
||||
if (anOut.w() == static_cast<T> (0.0))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
anOut.w() = static_cast<T> (1.0) / anOut.w();
|
||||
|
||||
anOut.x() *= anOut.w();
|
||||
anOut.y() *= anOut.w();
|
||||
anOut.z() *= anOut.w();
|
||||
|
||||
theObjX = anOut.x();
|
||||
theObjY = anOut.y();
|
||||
theObjZ = anOut.z();
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
#endif // _Graphic3d_TransformUtils_HeaderFile
|
161
src/Graphic3d/Graphic3d_WorldViewProjState.hxx
Normal file
161
src/Graphic3d/Graphic3d_WorldViewProjState.hxx
Normal file
@@ -0,0 +1,161 @@
|
||||
// Created on: 2015-06-30
|
||||
// Created by: Anton POLETAEV
|
||||
// Copyright (c) 2015 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _Graphic3d_WorldViewProjState_HeaderFile
|
||||
#define _Graphic3d_WorldViewProjState_HeaderFile
|
||||
|
||||
#include <Standard_Transient.hxx>
|
||||
#include <Standard_TypeDef.hxx>
|
||||
|
||||
//! Helper class for keeping reference on world-view-projection state.
|
||||
//! Helpful for synchronizing state of WVP dependent data structures.
|
||||
class Graphic3d_WorldViewProjState
|
||||
{
|
||||
public:
|
||||
|
||||
//! Default constructor.
|
||||
Graphic3d_WorldViewProjState()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
//! Constructor for custom projector type.
|
||||
//! @param theProjectionState [in] the projection state.
|
||||
//! @param theWorldViewState [in] the world view state.
|
||||
//! @param theCamera [in] the pointer to the class supplying projection and
|
||||
//! world view matrices (camera).
|
||||
Graphic3d_WorldViewProjState (const Standard_Size theProjectionState,
|
||||
const Standard_Size theWorldViewState,
|
||||
const Standard_Transient* theCamera = NULL)
|
||||
{
|
||||
Initialize (theProjectionState, theWorldViewState, theCamera);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//! Check state validity.
|
||||
//! @return true if state is set.
|
||||
Standard_Boolean IsValid()
|
||||
{
|
||||
return myIsValid;
|
||||
}
|
||||
|
||||
//! Invalidate world view projection state.
|
||||
void Reset()
|
||||
{
|
||||
myIsValid = Standard_False;
|
||||
myCamera = NULL;
|
||||
myProjectionState = 0;
|
||||
myWorldViewState = 0;
|
||||
}
|
||||
|
||||
//! Initialize world view projection state.
|
||||
void Initialize (const Standard_Size theProjectionState,
|
||||
const Standard_Size theWorldViewState,
|
||||
const Standard_Transient* theCamera = NULL)
|
||||
{
|
||||
myIsValid = Standard_True;
|
||||
myCamera = const_cast<Standard_Transient*> (theCamera);
|
||||
myProjectionState = theProjectionState;
|
||||
myWorldViewState = theWorldViewState;
|
||||
}
|
||||
|
||||
//! Initialize world view projection state.
|
||||
void Initialize (const Standard_Transient* theCamera = NULL)
|
||||
{
|
||||
myIsValid = Standard_True;
|
||||
myCamera = const_cast<Standard_Transient*> (theCamera);
|
||||
myProjectionState = 0;
|
||||
myWorldViewState = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//! @return projection state counter.
|
||||
Standard_Size& ProjectionState()
|
||||
{
|
||||
return myProjectionState;
|
||||
}
|
||||
|
||||
//! @return world view state counter.
|
||||
Standard_Size& WorldViewState()
|
||||
{
|
||||
return myWorldViewState;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//! Compare projection with other state.
|
||||
//! @return true when the projection of the given camera state differs from this one.
|
||||
Standard_Boolean IsProjectionChanged (const Graphic3d_WorldViewProjState& theState)
|
||||
{
|
||||
return myIsValid != theState.myIsValid
|
||||
|| myCamera != theState.myCamera
|
||||
|| myProjectionState != theState.myProjectionState;
|
||||
}
|
||||
|
||||
//! Compare world view transformation with other state.
|
||||
//! @return true when the orientation of the given camera state differs from this one.
|
||||
Standard_Boolean IsWorldViewChanged (const Graphic3d_WorldViewProjState& theState)
|
||||
{
|
||||
return myIsValid != theState.myIsValid
|
||||
|| myCamera != theState.myCamera
|
||||
|| myWorldViewState != theState.myWorldViewState;
|
||||
}
|
||||
|
||||
//! Compare with other world view projection state.
|
||||
//! @return true when the projection of the given camera state differs from this one.
|
||||
Standard_Boolean IsChanged (const Graphic3d_WorldViewProjState& theState)
|
||||
{
|
||||
return *this != theState;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//! Compare with other world view projection state.
|
||||
//! @return true if the other projection state is different to this one.
|
||||
bool operator != (const Graphic3d_WorldViewProjState& theOther) const
|
||||
{
|
||||
return !(*this == theOther);
|
||||
}
|
||||
|
||||
//! Compare with other world view projection state.
|
||||
//! @return true if the other projection state is equal to this one.
|
||||
bool operator == (const Graphic3d_WorldViewProjState& theOther) const
|
||||
{
|
||||
return myIsValid == theOther.myIsValid
|
||||
&& myCamera == theOther.myCamera
|
||||
&& myProjectionState == theOther.myProjectionState
|
||||
&& myWorldViewState == theOther.myWorldViewState;
|
||||
}
|
||||
|
||||
//! Copy world view projection state.
|
||||
void operator = (const Graphic3d_WorldViewProjState& theOther)
|
||||
{
|
||||
myIsValid = theOther.myIsValid;
|
||||
myCamera = theOther.myCamera;
|
||||
myProjectionState = theOther.myProjectionState;
|
||||
myWorldViewState = theOther.myWorldViewState;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Standard_Boolean myIsValid;
|
||||
Standard_Transient* myCamera;
|
||||
Standard_Size myProjectionState;
|
||||
Standard_Size myWorldViewState;
|
||||
};
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user