1 /*
2  * Copyright 2011-2012 Arx Libertatis Team (see the AUTHORS file)
3  *
4  * This file is part of Arx Libertatis.
5  *
6  * Arx Libertatis is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Arx Libertatis is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Arx Libertatis.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 /* Based on:
20 ===========================================================================
21 ARX FATALIS GPL Source Code
22 Copyright (C) 1999-2010 Arkane Studios SA, a ZeniMax Media company.
23 
24 This file is part of the Arx Fatalis GPL Source Code ('Arx Fatalis Source Code').
25 
26 Arx Fatalis Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
27 License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
28 
29 Arx Fatalis Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
30 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
31 
32 You should have received a copy of the GNU General Public License along with Arx Fatalis Source Code.  If not, see
33 <http://www.gnu.org/licenses/>.
34 
35 In addition, the Arx Fatalis Source Code is also subject to certain additional terms. You should have received a copy of these
36 additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Arx
37 Fatalis Source Code. If not, please request a copy in writing from Arkane Studios at the address below.
38 
39 If you have questions concerning this license or the applicable additional terms, you may contact in writing Arkane Studios, c/o
40 ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
41 ===========================================================================
42 */
43 // Code: Cyril Meynier
44 //
45 // Copyright (c) 1999 ARKANE Studios SA. All rights reserved
46 
47 #include "graphics/GraphicsUtility.h"
48 
Util_SetViewMatrix(EERIEMATRIX & mat,const Vec3f & vFrom,const Vec3f & vAt,const Vec3f & vWorldUp)49 bool Util_SetViewMatrix(EERIEMATRIX & mat, const Vec3f & vFrom,
50                            const Vec3f & vAt, const Vec3f & vWorldUp) {
51 
52 	// Get the z basis vector, which points straight ahead. This is the
53 	// difference from the eyepoint to the lookat point.
54 	Vec3f vView = vAt - vFrom;
55 
56 	// Normalize the z basis vector
57 	float fLength = vView.normalize();
58 
59 	if (fLength < 1e-6f)
60 		return false;
61 
62 	// Get the dot product, and calculate the projection of the z basis
63 	// vector onto the up vector. The projection is the y basis vector.
64 	float fDotProduct = dot(vWorldUp, vView);
65 
66 	Vec3f vUp = vWorldUp - vView * fDotProduct;
67 
68 	// If this vector has near-zero length because the input specified a
69 	// bogus up vector, let's try a default up vector
70 	if (1e-6f > (fLength = vUp.length()))
71 	{
72 		vUp = Vec3f::Y_AXIS - vView * vView.y;
73 
74 		// If we still have near-zero length, resort to a different axis.
75 		if (1e-6f > (fLength = vUp.length()))
76 		{
77 			vUp = Vec3f::Z_AXIS - vView * vView.z;
78 
79 			if (1e-6f > (fLength = vUp.length()))
80 				return false;
81 		}
82 	}
83 
84 	// Normalize the y basis vector
85 	vUp /= fLength;
86 
87 	// The x basis vector is found simply with the cross product of the y
88 	// and z basis vectors
89 	Vec3f vRight = cross(vUp, vView);
90 
91 	// Start building the matrix. The first three rows contains the basis
92 	// vectors used to rotate the view to point at the lookat point
93 	Util_SetIdentityMatrix(mat);
94 	mat._11 = vRight.x;
95 	mat._12 = vUp.x;
96 	mat._13 = vView.x;
97 	mat._21 = vRight.y;
98 	mat._22 = vUp.y;
99 	mat._23 = vView.y;
100 	mat._31 = vRight.z;
101 	mat._32 = vUp.z;
102 	mat._33 = vView.z;
103 
104 	// Do the translation values (rotations are still about the eyepoint)
105 	mat._41 = -dot(vFrom, vRight);
106 	mat._42 = -dot(vFrom, vUp);
107 	mat._43 = -dot(vFrom, vView);
108 
109 	return true;
110 }
111