-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCharacter.java
More file actions
126 lines (100 loc) · 3.85 KB
/
Character.java
File metadata and controls
126 lines (100 loc) · 3.85 KB
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
/*
* Character.java
* Project Disconnect
*
* Created by Drew Malin on 8/31/2011.
* Copyright 2011 Drew Malin. All rights reserved.
*
*/
import java.util.ArrayList;
import java.lang.Math;
public abstract class Character extends WorldEntity {
ArrayList<Attribute> attributes;
public float currentDirectionVect[];
public float targetDirectionVect[];
public float movementRate;
public Character() {
attributes = new ArrayList<Attribute>();
movementRate = 0.025f;
currentDirectionVect = new float[3];
targetDirectionVect = new float[3];
currentDirectionVect[0] = 0;
currentDirectionVect[1] = 0;
currentDirectionVect[2] = -1;
targetDirectionVect[0] = 0;
targetDirectionVect[1] = 0;
targetDirectionVect[2] = -1;
}
public void setTargetVect(float x, float y, float z) {
float l = (float) Math.pow((x*x) + (y*y) + (z*z), .5);
targetDirectionVect[0] = x / l;
targetDirectionVect[1] = y / l;
targetDirectionVect[2] = z / l;
}
public void unitDirectionVect(float x, float y, float z) {
float l = (float) Math.pow((x*x) + (y*y) + (z*z), .5);
currentDirectionVect[0] = x / l;
currentDirectionVect[1] = y / l;
currentDirectionVect[2] = z / l;
}
public void calculateRotation() {
float remainingRads, remainingAngle;
// If we are already looking in the direction of the click, we're done,
// the remaining angle to rotate through is 0.
if (currentDirectionVect[0] == targetDirectionVect[0] &&
currentDirectionVect[2] == targetDirectionVect[2]) {
remainingAngle = 0;
}
else {
//Calculate the remaining angle to rotate through (in radians) then
//translate into degrees.
remainingRads = calculateAngleDiscrepency();
remainingAngle = remainingRads * (180 / (float) Math.PI);
//Adjust angle, use the cross product to determine the correct direction
//of rotation. If the cross product results with a positive y value, then
//the fastest way to rotate is counterclockwise. If the y value is negative,
//the fastest direction of rotation is clockwise.
if (!cross(currentDirectionVect, targetDirectionVect)) {
remainingAngle *= -1;
}
}
//Update the character's necessary angle of rotation for drawing later
changeRotationY(remainingAngle);
//Set the current direction vector to the target vector.
currentDirectionVect[0] = targetDirectionVect[0];
currentDirectionVect[2] = targetDirectionVect[2];
}
/*
* Method to calculate the angle created by the clicked map location,
* the hero's position, and a point on the current view (direction)
* vector. Following the law of cosines, this angle, g, is:
* g = arccos((a^2 + b^2 - c^2) / 2ab)
* where a is the distance from the hero to the clicked point, b is the
* distance from the hero to the point on the direction vector,
* and c is the distance between a and b (pythagorean theorem).
*
*/
//TODO USE DOT PRODUCT!!!!
// a dot b = a1*b1 + a2*b2 + a3*b3
// a dot b = ||a|| * ||b|| cos theta
// theta = arccos((a1*b1 + a2*b2 + a3*b3)/(||a|| * ||b||))
private float calculateAngleDiscrepency() {
// Calculate dot product currentDirection dot targetDirection
float aDotB = (currentDirectionVect[0] * targetDirectionVect[0]) +
(currentDirectionVect[2] * targetDirectionVect[2]);
// Solve for theta (since these vectors are unit vectors, we don't
// need to solve for, then divide by, their lengths)
float theta = (float)Math.acos(aDotB);
// Was getting dot product value greater than 1 in some specific circumstances
// (value was something like 1.0000000001) which is outside of the domain for
// arc cosine. If this ever occurs, force theta to be 0 (as if aDotB were 1)
if (aDotB > 1)
theta = 0;
return theta;
}
//Cross product. Thank you Wikipedia.
private boolean cross(float[] a, float[] b) {
float yVal = a[2]*b[0] - a[0]*b[2];
return yVal >= 0 ? true : false;
}
}