File: vector.h

package info (click to toggle)
warzone2100 4.6.1-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 660,348 kB
  • sloc: cpp: 675,711; ansic: 387,204; javascript: 75,107; python: 16,628; php: 4,294; sh: 3,941; makefile: 2,330; lisp: 1,492; cs: 489; xml: 404; perl: 224; ruby: 156; java: 89
file content (155 lines) | stat: -rw-r--r-- 4,664 bytes parent folder | download | duplicates (3)
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
	This file is part of Warzone 2100.
	Copyright (C) 2007-2020  Warzone 2100 Project

	Warzone 2100 is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	Warzone 2100 is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with Warzone 2100; if not, write to the Free Software
	Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef VECTOR_H
#define VECTOR_H

#if defined(WZ_CC_MSVC)
#pragma warning( disable : 4201)
#endif
#define GLM_FORCE_SWIZZLE
#define GLM_FORCE_SILENT_WARNINGS

#include <stdint.h>

#include "wzglobal.h"
#include "frame.h"
#include "lib/framework/types.h"
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>

using Vector3i = glm::ivec3;
using Vector2i = glm::ivec2;
using Vector2f = glm::vec2;
using Vector3f = glm::vec3;
struct Rotation
{
	Rotation()
	{
		direction = 0;
		pitch = 0;
		roll = 0;
	}
	Rotation(int direction, int pitch, int roll) : direction((uint16_t)direction), pitch((uint16_t)pitch), roll((uint16_t)roll) {}
	Rotation(Vector3i xyz) : direction((uint16_t)xyz.x), pitch((uint16_t)xyz.y), roll((uint16_t)xyz.z) {}
	uint16_t direction, pitch, roll;  ///< Object rotation in 0..64k range
};
typedef Vector3i Position;  ///< Map position in world coordinates

static inline Vector3i toVector(Rotation const &r)
{
	return Vector3i(r.direction, r.pitch, r.roll);
}

// vector * vector -> scalar
// Note: glm doesn't provide dot operator for integral vector.
static inline WZ_DECL_PURE int dot(Vector2i const &a, Vector2i const &b)
{
	return a.x * b.x + a.y * b.y;
}
static inline WZ_DECL_PURE int dot(Vector3i const &a, Vector3i const &b)
{
	return a.x * b.x + a.y * b.y + a.z * b.z;
}

// iSinCosR(angle, scalar) -> 2d_vector
static inline WZ_DECL_PURE Vector2i iSinCosR(uint16_t a, int32_t r)
{
	return Vector2i(iSinR(a, r), iCosR(a, r));
}

// iAtan2(2d_vector) -> angle
static inline WZ_DECL_PURE int iAtan2(Vector2i const &a)
{
	return iAtan2(a.x, a.y);
}

// iHypot(vector) -> scalar
static inline WZ_DECL_PURE int iHypot(Vector2i const &a)
{
	return iHypot(a.x, a.y);
}
static inline WZ_DECL_PURE int iHypot(Vector3i const &a)
{
	return iHypot3(a.x, a.y, a.z);
}

/*!
 * Rotate v
 * \param v vector to rotate
 * \param angle the amount * 32768/π to rotate in counterclockwise direction
 * \return Result
 */
static inline WZ_DECL_PURE Vector2f Vector2f_Rotate2f(Vector2f v, int angle)
{
	Vector2f result;
	result.x = (v.x * iCos((uint16_t)angle) - v.y * iSin((uint16_t)angle)) / 65536;
	result.y = (v.x * iSin((uint16_t)angle) + v.y * iCos((uint16_t)angle)) / 65536;

	return result;
}


/*!
 * Much the same as Vector2i_InCircle except that it works in 3-axis by discarding the z-component and with
 * circles.
 * \param v Vector to test
 * \param c Vector containing the centre of the circle
 * \param r The radius of the circle
 * \return If v falls within the circle
 */
static inline bool WZ_DECL_PURE Vector3i_InCircle(Vector3i v, Vector3i c, unsigned r)
{
	Vector2i delta = Vector3i(v - c).xy();
	// Explictily cast to "unsigned int" because this number never can be
	// negative, due to the fact that these numbers are squared. Still GCC
	// warns about a comparison of a comparison between an unsigned and a
	// signed integer.
	return (unsigned int)dot(delta, delta) < r * r;
}


/*!
 * Much the same as Vector2i_InCircle except that it works in 3-axis and with
 * spheres.
 * The equation used is also ever so slightly different:
 * (x - a)^2 + (y - b)^2 + (z - c)^2 = r^2. Notice how it is still squared and
 * _not_ cubed!
 * \param v Vector to test
 * \param c Vector containing the centre of the sphere
 * \param r The radius of the sphere
 * \return If v falls within the sphere
 */
static inline bool WZ_DECL_PURE Vector3i_InSphere(Vector3i v, Vector3i c, unsigned r)
{
	Vector3i delta = v - c;
	// Explictily cast to "unsigned int" because this number never can be
	// negative, due to the fact that these numbers are squared. Still GCC
	// warns about a comparison of a comparison between an unsigned and a
	// signed integer.
	return (unsigned int)dot(delta, delta) < r * r;
}

// Round direction to nearest axis-aligned direction.
static inline uint16_t snapDirection(uint16_t direction)
{
	return (direction + 0x2000) & 0xC000;
}

#endif // VECTOR_H