Dali 3D User Interface Engine
projection.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 // CLASS HEADER
20 
21 // INTERNAL INCLUDES
29 
30 namespace Dali
31 {
32 
33 namespace Internal
34 {
35 
36 bool Unproject( const Vector4& windowPos,
37  const Matrix& inverseMvp,
38  float viewportWidth,
39  float viewportHeight,
40  Vector4& objectPos )
41 {
42  objectPos.x = windowPos.x;
43  objectPos.y = windowPos.y;
44  objectPos.z = windowPos.z;
45  objectPos.w = 1.0f;
46 
47  objectPos.x = objectPos.x / viewportWidth;
48  objectPos.y = objectPos.y / viewportHeight;
49 
50  objectPos.x = objectPos.x * 2.0f - 1.0f;
51  objectPos.y = objectPos.y * 2.0f - 1.0f;
52  objectPos.z = objectPos.z * 2.0f - 1.0f;
53 
54  objectPos = inverseMvp * objectPos;
55 
56  // In the case where objectPos.w is exactly zero, the unproject fails
57  if ( EqualsZero( objectPos.w ) )
58  {
59  return false;
60  }
61 
62  objectPos.x /= objectPos.w;
63  objectPos.y /= objectPos.w;
64  objectPos.z /= objectPos.w;
65 
66  return true;
67 }
68 
69 bool UnprojectFull( const Vector4& windowPos,
70  const Matrix& modelView,
71  const Matrix& projection,
72  float viewportWidth,
73  float viewportHeight,
74  Vector4& objectPos )
75 {
76  Matrix invertedMvp( false ); // Don't initialize.
77  Matrix::Multiply( invertedMvp, modelView, projection );
78 
79  if (invertedMvp.Invert())
80  {
81  return Unproject( windowPos, invertedMvp, viewportWidth, viewportHeight, objectPos );
82  }
83 
84  return false;
85 }
86 
87 bool XyPlaneIntersect( const Vector4& pointA, const Vector4& pointB, Vector4& intersect )
88 {
89  const Vector4* near = NULL;
90  const Vector4* far = NULL;
91 
92  if ( pointA.z > 0.0f && pointB.z < 0.0f )
93  {
94  near = &pointA;
95  far = &pointB;
96  }
97  else if ( pointB.z > 0.0f && pointA.z < 0.0f )
98  {
99  near = &pointB;
100  far = &pointA;
101  }
102  else
103  {
104  return false; // ray does not cross xy plane
105  }
106 
107  float dist = near->z / (near->z - far->z);
108 
109  intersect.x = near->x + (far->x - near->x) * dist;
110  intersect.y = near->y + (far->y - near->y) * dist;
111  intersect.z = 0.0f;
112 
113  return true;
114 }
115 
116 bool ProjectFull( const Vector4& position,
117  const Matrix& modelView,
118  const Matrix& projection,
119  float viewportX,
120  float viewportY,
121  float viewportWidth,
122  float viewportHeight,
123  Vector4& windowPos )
124 {
125  bool ok = false;
126 
127  Matrix Mvp( false ); // Don't initialize.
128  Matrix::Multiply( Mvp, modelView, projection );
129 
130  Vector4 p = Mvp * position;
131 
132  Vector2 depthRange(0,1);
133 
134  if( !EqualsZero( p.w ) )
135  {
136  float div = 1.0 / p.w;
137 
138  windowPos = Vector4( (1 + p.x * div) * viewportWidth / 2 + viewportX,
139  (1 - p.y * div) * viewportHeight / 2 + viewportY,
140  (p.z * div) * (depthRange.y - depthRange.x) + depthRange.x,
141  div);
142  ok = true;
143  }
144 
145  return ok;
146 }
147 
148 
149 } // namespace Internal
150 
151 } // namespace Dali
Dali Docs Home
Read more about Dali