summaryrefslogtreecommitdiff
path: root/common/algebra.cpp
blob: a34f91d4c9a5f34c12471b55c6b7b57f146f548a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//
// Math and Linear Algebra stuff.
//

#include "defines.h"
#include "algebra.h"

// ============================================================================
// 4x4 Matrix class.

void Matrix44::CreateLookAt(const Point3& Eye, const Point3& Target, const Vector3& Up)
{
	Vector3 x, y, z;

	// Z = Eye - Target
	z = Eye - Target;

  // X = Y Cross Z
	x = Cross3(Up, z);

  // Y = Z Cross X
	y = Cross3(z, x);

	// Normalize everything.
	x.Normalize();
	y.Normalize();
	z.Normalize();

	m_Rows[0] = Float4(x.GetX(), y.GetX(), z.GetX(), 0.0f);
	m_Rows[1] = Float4(x.GetY(), y.GetY(), z.GetY(), 0.0f);
	m_Rows[2] = Float4(x.GetZ(), y.GetZ(), z.GetZ(), 0.0f);
	m_Rows[3] = m_Rows[0]*-Eye.GetX() + m_Rows[1]*-Eye.GetY() + m_Rows[2]*-Eye.GetZ();
}

void Matrix44::CreatePerspective(float FoVy, float Aspect, float Near, float Far)
{
	float Left, Right, Bottom, Top;

	Top = Near * (float)tan(FoVy * LC_PI / 360.0f);
	Bottom = -Top;

	Left = Bottom * Aspect;
	Right = Top * Aspect;

	if ((Near <= 0.0f) || (Far <= 0.0f) || (Near == Far) || (Left == Right) || (Top == Bottom))
		return;

	float x, y, a, b, c, d;

	x = (2.0f * Near) / (Right - Left);
	y = (2.0f * Near) / (Top - Bottom);
	a = (Right + Left) / (Right - Left);
	b = (Top + Bottom) / (Top - Bottom);
	c = -(Far + Near) / (Far - Near);
	d = -(2.0f * Far * Near) / (Far - Near);

	m_Rows[0] = Float4(x, 0,  a, 0);
	m_Rows[1] = Float4(0, y,  b, 0);
	m_Rows[2] = Float4(0, 0,  c, d);
	m_Rows[3] = Float4(0, 0, -1, 0);
}

// ============================================================================
// Other Functions.

// Convert object coordinates to screen coordinates.
Point3 ProjectPoint(const Point3& Pt, const Matrix44& ModelView, const Matrix44& Projection, const int Viewport[4])
{
	Point3 Tmp;

	Tmp = Pt * ModelView;
	Tmp = Tmp * Projection;

	// Normalize.
	Tmp /= Tmp[3];

	// Screen coordinates.
	return Point3(Viewport[0]+(1+Tmp[0])*Viewport[2]/2, Viewport[1]+(1+Tmp[1])*Viewport[3]/2, (1+Tmp[2])/2);
}