ProtoTracer  1.0
Real-time 3D rendering and animation engine
Loading...
Searching...
No Matches
ObjectDeformer.cpp
Go to the documentation of this file.
1#include "ObjectDeformer.h"
2
3bool ObjectDeformer::CheckClipAxis(Vector3D base, bool positive, Axis valueCheckAxis){
4 if (valueCheckAxis == XAxis && positive && base.X > 0){
5 return true;
6 }
7 else if (valueCheckAxis == XAxis && !positive && base.X < 0){
8 return true;
9 }
10 else if (valueCheckAxis == YAxis && positive && base.Y > 0){
11 return true;
12 }
13 else if (valueCheckAxis == YAxis && !positive && base.Y < 0){
14 return true;
15 }
16 else if (valueCheckAxis == ZAxis && positive && base.Z > 0){
17 return true;
18 }
19 else if (valueCheckAxis == ZAxis && !positive && base.Z < 0){
20 return true;
21 }
22 else{
23 return false;
24 }
25}
26
28 objects = new Object3D*[1];
29
30 objects[0] = object;
31
32 objectCount = 1;
33}
34
35ObjectDeformer::ObjectDeformer(Object3D** objects, int objectCount){
36 this->objects = objects;
37 this->objectCount = objectCount;
38}
39
40void ObjectDeformer::PerspectiveDeform(float scaleRatio, Vector3D center, Axis axis){//0.0f close, 1.0f uniform, infinite infinite
41 for(int i = 0; i < objectCount; i++){
42 for(int j = 0; j < objects[i]->GetTriangleGroup()->GetVertexCount(); j++){
43 switch(axis){
44 case XAxis:
45 objects[i]->GetTriangleGroup()->GetVertices()[j].Y = objects[i]->GetTriangleGroup()->GetVertices()[j].Y * (1.0f - (objects[i]->GetTriangleGroup()->GetVertices()[j].X + center.X) / scaleRatio);
46 objects[i]->GetTriangleGroup()->GetVertices()[j].Z = objects[i]->GetTriangleGroup()->GetVertices()[j].Z * (1.0f - (objects[i]->GetTriangleGroup()->GetVertices()[j].X + center.X) / scaleRatio);
47 break;
48 case YAxis:
49 objects[i]->GetTriangleGroup()->GetVertices()[j].X = objects[i]->GetTriangleGroup()->GetVertices()[j].X * (1.0f - (objects[i]->GetTriangleGroup()->GetVertices()[j].Y + center.Y) / scaleRatio);
50 objects[i]->GetTriangleGroup()->GetVertices()[j].Z = objects[i]->GetTriangleGroup()->GetVertices()[j].Z * (1.0f - (objects[i]->GetTriangleGroup()->GetVertices()[j].Y + center.Y) / scaleRatio);
51 break;
52 case ZAxis:
53 objects[i]->GetTriangleGroup()->GetVertices()[j].X = objects[i]->GetTriangleGroup()->GetVertices()[j].X * (1.0f - (objects[i]->GetTriangleGroup()->GetVertices()[j].Z + center.Z) / scaleRatio);
54 objects[i]->GetTriangleGroup()->GetVertices()[j].Y = objects[i]->GetTriangleGroup()->GetVertices()[j].Y * (1.0f - (objects[i]->GetTriangleGroup()->GetVertices()[j].Z + center.Z) / scaleRatio);
55 break;
56 default:
57 break;
58 }
59 }
60 }
61}
62
63void ObjectDeformer::SinusoidalDeform(float magnitude, float timeRatio, float periodModifier, float frequencyModifier, Axis axis){
64 for(int i = 0; i < objectCount; i++){
65 for(int j = 0; j < objects[i]->GetTriangleGroup()->GetVertexCount(); j++){
67
68 switch(axis){
69 case XAxis:
70 objects[i]->GetTriangleGroup()->GetVertices()[j].X = (sinf((base.Y) + timeRatio * frequencyModifier) * periodModifier + cosf((base.Z) + timeRatio * frequencyModifier) * periodModifier) * magnitude;
71 break;
72 case YAxis:
73 objects[i]->GetTriangleGroup()->GetVertices()[j].Y = (sinf((base.X) + timeRatio * frequencyModifier) * periodModifier + cosf((base.Z) + timeRatio * frequencyModifier) * periodModifier) * magnitude;
74 break;
75 case ZAxis:
76 objects[i]->GetTriangleGroup()->GetVertices()[j].Z = (sinf((base.X) + timeRatio * frequencyModifier) * periodModifier + cosf((base.Y) + timeRatio * frequencyModifier) * periodModifier) * magnitude;
77 break;
78 default:
79 break;
80 }
81 }
82 }
83}
84
85void ObjectDeformer::DropwaveDeform(float magnitude, float timeRatio, float periodModifier, float frequencyModifier, Axis axis){
86 for(int i = 0; i < objectCount; i++){
87 for(int j = 0; j < objects[i]->GetTriangleGroup()->GetVertexCount(); j++){
89
90 switch(axis){
91 case XAxis:
92 objects[i]->GetTriangleGroup()->GetVertices()[j].X = -(1.0f + cosf(12.0f*sqrt(base.Y * base.Y + base.Z + base.Z) + timeRatio * frequencyModifier) * periodModifier) / (0.5f * (base.Y * base.Y + base.Z + base.Z) + 2.0f) * magnitude;
93 break;
94 case YAxis:
95 objects[i]->GetTriangleGroup()->GetVertices()[j].Y = -(1.0f + cosf(12.0f*sqrt(base.X * base.X + base.Z + base.Z) + timeRatio * frequencyModifier) * periodModifier) / (0.5f * (base.X * base.X + base.Z + base.Z) + 2.0f) * magnitude;
96 break;
97 case ZAxis:
98 objects[i]->GetTriangleGroup()->GetVertices()[j].Z = -(1.0f + cosf(12.0f*sqrt(base.X * base.X + base.Y * base.Y) + timeRatio * frequencyModifier) * periodModifier) / (0.5f * (base.X * base.X + base.Y * base.Y) + 2.0f) * magnitude;
99 break;
100 default:
101 break;
102 }
103 }
104 }
105}
106
107void ObjectDeformer::SineWaveSurfaceDeform(Vector3D offset, float magnitude, float timeRatio, float periodModifier, float frequencyModifier, Axis axis){
108 for(int i = 0; i < objectCount; i++){
109 for(int j = 0; j < objects[i]->GetTriangleGroup()->GetVertexCount(); j++){
110 Vector3D base = objects[i]->GetTriangleGroup()->GetVertices()[j] - offset;
111
112 switch(axis){
113 case XAxis:
114 objects[i]->GetTriangleGroup()->GetVertices()[j].X = objects[i]->GetTriangleGroup()->GetVertices()[j].X + sinf((sqrtf(base.Y * base.Y + base.Z * base.Z) + timeRatio * frequencyModifier) * periodModifier) * magnitude;
115 break;
116 case YAxis:
117 objects[i]->GetTriangleGroup()->GetVertices()[j].Y = objects[i]->GetTriangleGroup()->GetVertices()[j].Y + sinf((sqrtf(base.X * base.X + base.Z * base.Z) + timeRatio * frequencyModifier) * periodModifier) * magnitude;
118 break;
119 case ZAxis:
120 objects[i]->GetTriangleGroup()->GetVertices()[j].Z = objects[i]->GetTriangleGroup()->GetVertices()[j].Z + sinf((sqrtf(base.X * base.X + base.Y * base.Y) + timeRatio * frequencyModifier) * periodModifier) * magnitude;
121 break;
122 default:
123 break;
124 }
125 }
126 }
127}
128
129void ObjectDeformer::CosineInterpolationDeformer(float* pointMultiplier, int points, float scale, float minAxis, float maxAxis, Axis selectionAxis, Axis deformAxis){
130 //map axis offsets based on value range for multiplying vertex coordinates at set intervals spaced evenly across minimum and maximum range of selected axis
131 for(int i = 0; i < objectCount; i++){
132 for(int j = 0; j < objects[i]->GetTriangleGroup()->GetVertexCount(); j++){
133 float value;
134
135 switch(selectionAxis){
136 case XAxis:
137 value = objects[i]->GetTriangleGroup()->GetVertices()[j].X;
138 break;
139 case YAxis:
140 value = objects[i]->GetTriangleGroup()->GetVertices()[j].Y;
141 break;
142 case ZAxis:
143 value = objects[i]->GetTriangleGroup()->GetVertices()[j].Z;
144 break;
145 default:
146 value = 0.0f;
147 break;
148 }
149
150 float stepWindow = (maxAxis - minAxis) / points;//window size for the step interval
151
152 float roundUpWindow = Mathematics::RoundUpWindow(value, stepWindow);
153 float roundDownWindow = roundUpWindow - stepWindow;
154 int roundUpIndex = (roundUpWindow - minAxis) / stepWindow;
155
156 float intervalMultiplier, windowRatio;
157
158 if (roundUpIndex < 1){//below range
159 intervalMultiplier = 1.0f;// Mathematics::CosineInterpolation(1.0f, pointMultiplier[0], windowRatio)
160 }
161 else if (roundUpIndex > points){//above range
162 intervalMultiplier = 1.0f;// Mathematics::CosineInterpolation(pointMultiplier[points - 1], 1.0f, windowRatio)
163 }
164 else{
165 windowRatio = (value - roundDownWindow) / stepWindow;
166 intervalMultiplier = Mathematics::CosineInterpolation(pointMultiplier[roundUpIndex], pointMultiplier[roundUpIndex - 1], 1.0f - windowRatio);
167 }
168
169
170 //calculate where the axis fits on the range
171
172 switch(deformAxis){
173 case XAxis:
174 objects[i]->GetTriangleGroup()->GetVertices()[j].X = objects[i]->GetTriangleGroup()->GetVertices()[j].X + scale * intervalMultiplier;
175 break;
176 case YAxis:
177 objects[i]->GetTriangleGroup()->GetVertices()[j].Y = objects[i]->GetTriangleGroup()->GetVertices()[j].Y + scale * intervalMultiplier;
178 break;
179 case ZAxis:
180 objects[i]->GetTriangleGroup()->GetVertices()[j].Z = objects[i]->GetTriangleGroup()->GetVertices()[j].Z + scale * intervalMultiplier;
181 break;
182 default:
183 break;
184 }
185 }
186 }
187}
188
189void ObjectDeformer::AxisZeroClipping(bool positive, Axis clipAxis, Axis valueCheckAxis){
190 for(int i = 0; i < objectCount; i++){
191 for(int j = 0; j < objects[i]->GetTriangleGroup()->GetVertexCount(); j++){
192 Vector3D base = objects[i]->GetTriangleGroup()->GetVertices()[j];
193
194 switch(clipAxis){
195 case XAxis:
196 if(CheckClipAxis(base, positive, valueCheckAxis)) base.X = 0;
197 break;
198 case YAxis:
199 if(CheckClipAxis(base, positive, valueCheckAxis)) base.Y = 0;
200 break;
201 case ZAxis:
202 if(CheckClipAxis(base, positive, valueCheckAxis)) base.Z = 0;
203 break;
204 default:
205 break;
206 }
207 }
208 }
209}
Defines the ObjectDeformer class for deforming 3D objects using various transformations.
virtual Vector3D * GetVertices()=0
Retrieves the array of mutable vertices in the triangle group.
static int RoundUpWindow(int value, int multiple)
Rounds value up to the nearest multiple of multiple.
static float CosineInterpolation(float beg, float fin, float ratio)
Applies a cosine-based interpolation between two values.
Represents a 3D object with geometry, material, and transformation data.
Definition Object3D.h:28
ITriangleGroup * GetTriangleGroup()
Retrieves the modifiable geometry of the object.
Definition Object3D.cpp:72
Object3D ** objects
Array of pointers to Object3D instances to be deformed.
void DropwaveDeform(float magnitude, float timeRatio, float periodModifier, float frequencyModifier, Axis axis)
Applies a dropwave deformation to the object(s).
void SineWaveSurfaceDeform(Vector3D offset, float magnitude, float timeRatio, float periodModifier, float frequencyModifier, Axis axis)
Applies a sine wave surface deformation to the object(s).
ObjectDeformer(Object3D *object)
Constructs an ObjectDeformer for a single object.
void CosineInterpolationDeformer(float *pointMultiplier, int points, float scale, float minAxis, float maxAxis, Axis selectionAxis, Axis deformAxis)
Applies cosine interpolation deformation to the object(s).
void AxisZeroClipping(bool positive, Axis clipAxis, Axis valueCheckAxis)
Clips the object(s) along a specified axis.
bool CheckClipAxis(Vector3D base, bool positive, Axis valueCheckAxis)
Checks if a given axis value exceeds a clipping threshold.
void SinusoidalDeform(float magnitude, float timeRatio, float periodModifier, float frequencyModifier, Axis axis)
Applies a sinusoidal deformation to the object(s).
void PerspectiveDeform(float scaleRatio, Vector3D center, Axis axis)
Applies a perspective deformation to the object(s).
Axis
Represents the axis of deformation or clipping.
int objectCount
Number of objects in the objects array.
Represents a 3D vector (X, Y, Z) and provides methods for vector arithmetic.
Definition Vector3D.h:26
float Z
The Z-component of the 3D vector.
Definition Vector3D.h:30
float X
The X-component of the 3D vector.
Definition Vector3D.h:28
float Y
The Y-component of the 3D vector.
Definition Vector3D.h:29