Showing the changes to libraries/render-utils/src/AnimDebugDraw.cpp (1 of 8 files). Show all
Unified · Split
| @@ -10,10 +10,11 @@ · 9 unmodified lines | |||
| 10 | #include "animdebugdraw_vert.h" | 10 | #include "animdebugdraw_vert.h" |
| 11 | #include "animdebugdraw_frag.h" | 11 | #include "animdebugdraw_frag.h" |
| 12 | #include <gpu/Batch.h> | 12 | #include <gpu/Batch.h> |
| 13 | |||
| 14 | #include "AnimDebugDraw.h" | ||
| 15 | #include "AbstractViewStateInterface.h" | 13 | #include "AbstractViewStateInterface.h" |
| 16 | #include "RenderUtilsLogging.h" | 14 | #include "RenderUtilsLogging.h" |
| 15 | #include "GLMHelpers.h" | ||
| 16 | |||
| 17 | #include "AnimDebugDraw.h" | ||
| 17 | 18 | ||
| 18 | struct Vertex { | 19 | struct Vertex { |
| 19 | glm::vec3 pos; | 20 | glm::vec3 pos; |
| @@ -165,45 +166,120 @@ static const uint32_t green = toRGBA(0, 255, 0, 255); · 145 unmodified lines | |||
| 165 | static const uint32_t blue = toRGBA(0, 0, 255, 255); | 166 | static const uint32_t blue = toRGBA(0, 0, 255, 255); |
| 166 | static const uint32_t cyan = toRGBA(0, 128, 128, 255); | 167 | static const uint32_t cyan = toRGBA(0, 128, 128, 255); |
| 167 | 168 | ||
| 168 | static void addWireframeSphereWithAxes(const AnimPose& rootPose, const AnimPose& pose, float radius, Vertex*& v) { | 169 | const int NUM_CIRCLE_SLICES = 24; |
| 169 | 170 | ||
| 171 | static void addBone(const AnimPose& rootPose, const AnimPose& pose, float radius, Vertex*& v) { | ||
| 172 | |||
| 173 | AnimPose finalPose = rootPose * pose; | ||
| 170 | glm::vec3 base = rootPose * pose.trans; | 174 | glm::vec3 base = rootPose * pose.trans; |
| 171 | 175 | ||
| 176 | glm::vec3 xRing[NUM_CIRCLE_SLICES + 1]; // one extra for last index. | ||
| 177 | glm::vec3 yRing[NUM_CIRCLE_SLICES + 1]; | ||
| 178 | glm::vec3 zRing[NUM_CIRCLE_SLICES + 1]; | ||
| 179 | const float dTheta = (2.0f * (float)M_PI) / NUM_CIRCLE_SLICES; | ||
| 180 | for (int i = 0; i < NUM_CIRCLE_SLICES + 1; i++) { | ||
| 181 | float rCosTheta = radius * cos(dTheta * i); | ||
| 182 | float rSinTheta = radius * sin(dTheta * i); | ||
| 183 | xRing[i] = finalPose * glm::vec3(0.0f, rCosTheta, rSinTheta); | ||
| 184 | yRing[i] = finalPose * glm::vec3(rCosTheta, 0.0f, rSinTheta); | ||
| 185 | zRing[i] = finalPose *glm::vec3(rCosTheta, rSinTheta, 0.0f); | ||
| 186 | } | ||
| 187 | |||
| 172 | // x-axis | 188 | // x-axis |
| 173 | v->pos = base; | 189 | v->pos = base; |
| 174 | v->rgba = red; | 190 | v->rgba = red; |
| 175 | v++; | 191 | v++; |
| 176 | v->pos = rootPose * (pose.trans + pose.rot * glm::vec3(radius, 0.0f, 0.0f)); | 192 | v->pos = finalPose * glm::vec3(radius * 2.0f, 0.0f, 0.0f); |
| 177 | v->rgba = red; | 193 | v->rgba = red; |
| 178 | v++; | 194 | v++; |
| 179 | 195 | ||
| 196 | // x-ring | ||
| 197 | for (int i = 0; i < NUM_CIRCLE_SLICES; i++) { | ||
| 198 | v->pos = xRing[i]; | ||
| 199 | v->rgba = red; | ||
| 200 | v++; | ||
| 201 | v->pos = xRing[i + 1]; | ||
| 202 | v->rgba = red; | ||
| 203 | v++; | ||
| 204 | } | ||
| 205 | |||
| 180 | // y-axis | 206 | // y-axis |
| 181 | v->pos = base; | 207 | v->pos = base; |
| 182 | v->rgba = green; | 208 | v->rgba = green; |
| 183 | v++; | 209 | v++; |
| 184 | v->pos = rootPose * (pose.trans + pose.rot * glm::vec3(0.0f, radius, 0.0f)); | 210 | v->pos = finalPose * glm::vec3(0.0f, radius * 2.0f, 0.0f); |
| 185 | v->rgba = green; | 211 | v->rgba = green; |
| 186 | v++; | 212 | v++; |
| 187 | 213 | ||
| 214 | // y-ring | ||
| 215 | for (int i = 0; i < NUM_CIRCLE_SLICES; i++) { | ||
| 216 | v->pos = yRing[i]; | ||
| 217 | v->rgba = green; | ||
| 218 | v++; | ||
| 219 | v->pos = yRing[i + 1]; | ||
| 220 | v->rgba = green; | ||
| 221 | v++; | ||
| 222 | } | ||
| 223 | |||
| 188 | // z-axis | 224 | // z-axis |
| 189 | v->pos = base; | 225 | v->pos = base; |
| 190 | v->rgba = blue; | 226 | v->rgba = blue; |
| 191 | v++; | 227 | v++; |
| 192 | v->pos = rootPose * (pose.trans + pose.rot * glm::vec3(0.0f, 0.0f, radius)); | 228 | v->pos = finalPose * glm::vec3(0.0f, 0.0f, radius * 2.0f); |
| 193 | v->rgba = blue; | 229 | v->rgba = blue; |
| 194 | v++; | 230 | v++; |
| 195 | } | ||
| 196 | 231 | ||
| 197 | static void addWireframeBoneAxis(const AnimPose& rootPose, const AnimPose& pose, | 232 | // z-ring |
| 198 | const AnimPose& parentPose, float radius, Vertex*& v) { | 233 | for (int i = 0; i < NUM_CIRCLE_SLICES; i++) { |
| 199 | v->pos = rootPose * pose.trans; | 234 | v->pos = zRing[i]; |
| 200 | v->rgba = cyan; | 235 | v->rgba = blue; |
| 201 | v++; | 236 | v++; |
| 202 | v->pos = rootPose * parentPose.trans; | 237 | v->pos = zRing[i + 1]; |
| 203 | v->rgba = cyan; | 238 | v->rgba = blue; |
| 204 | v++; | 239 | v++; |
| 240 | } | ||
| 205 | } | 241 | } |
| 206 | 242 | ||
| 243 | static void addLink(const AnimPose& rootPose, const AnimPose& pose, | ||
| 244 | const AnimPose& parentPose, float radius, Vertex*& v) { | ||
| 245 | |||
| 246 | AnimPose pose0 = rootPose * parentPose; | ||
| 247 | AnimPose pose1 = rootPose * pose; | ||
| 248 | |||
| 249 | glm::vec3 boneAxisWorld = glm::normalize(pose1.trans - pose0.trans); | ||
| 250 | glm::vec3 boneAxis0 = glm::normalize(pose0.inverse().xformVector(boneAxisWorld)); | ||
| 251 | glm::vec3 boneAxis1 = glm::normalize(pose1.inverse().xformVector(boneAxisWorld)); | ||
| 252 | |||
| 253 | glm::vec3 uAxis, vAxis, wAxis; | ||
| 254 | generateBasisVectors(boneAxis0, glm::vec3(1, 0, 0), uAxis, vAxis, wAxis); | ||
| 255 | |||
| 256 | const int NUM_BASE_CORNERS = 4; | ||
| 257 | glm::vec3 boneBaseCorners[NUM_BASE_CORNERS]; | ||
| 258 | boneBaseCorners[0] = pose0 * ((uAxis * radius) + (vAxis * radius) + (wAxis * radius)); | ||
| 259 | boneBaseCorners[1] = pose0 * ((uAxis * radius) - (vAxis * radius) + (wAxis * radius)); | ||
| 260 | boneBaseCorners[2] = pose0 * ((uAxis * radius) - (vAxis * radius) - (wAxis * radius)); | ||
| 261 | boneBaseCorners[3] = pose0 * ((uAxis * radius) + (vAxis * radius) - (wAxis * radius)); | ||
| 262 | |||
| 263 | glm::vec3 boneTip = pose1 * (boneAxis1 * -radius); | ||
| 264 | |||
| 265 | for (int i = 0; i < NUM_BASE_CORNERS; i++) { | ||
| 266 | v->pos = boneBaseCorners[i]; | ||
| 267 | v->rgba = cyan; | ||
| 268 | v++; | ||
| 269 | v->pos = boneBaseCorners[(i + 1) % NUM_BASE_CORNERS]; | ||
| 270 | v->rgba = cyan; | ||
| 271 | v++; | ||
| 272 | } | ||
| 273 | |||
| 274 | for (int i = 0; i < NUM_BASE_CORNERS; i++) { | ||
| 275 | v->pos = boneBaseCorners[i]; | ||
| 276 | v->rgba = cyan; | ||
| 277 | v++; | ||
| 278 | v->pos = boneTip; | ||
| 279 | v->rgba = cyan; | ||
| 280 | v++; | ||
| 281 | } | ||
| 282 | } | ||
| 207 | 283 | ||
| 208 | void AnimDebugDraw::update() { | 284 | void AnimDebugDraw::update() { |
| 209 | 285 | ||
| @@ -215,15 +291,20 @@ void AnimDebugDraw::update() { · 5 unmodified lines | |||
| 215 | render::PendingChanges pendingChanges; | 291 | render::PendingChanges pendingChanges; |
| 216 | pendingChanges.updateItem<AnimDebugDrawData>(_itemID, [&](AnimDebugDrawData& data) { | 292 | pendingChanges.updateItem<AnimDebugDrawData>(_itemID, [&](AnimDebugDrawData& data) { |
| 217 | 293 | ||
| 294 | const size_t VERTICES_PER_BONE = (6 + (NUM_CIRCLE_SLICES * 2) * 3); | ||
| 295 | const size_t VERTICES_PER_LINK = 8 * 2; | ||
| 296 | |||
| 297 | const float BONE_RADIUS = 0.0075f; | ||
| 298 | |||
| 218 | // figure out how many verts we will need. | 299 | // figure out how many verts we will need. |
| 219 | int numVerts = 0; | 300 | int numVerts = 0; |
| 220 | for (auto&& iter : _skeletons) { | 301 | for (auto&& iter : _skeletons) { |
| 221 | AnimSkeleton::Pointer& skeleton = iter.second.first; | 302 | AnimSkeleton::Pointer& skeleton = iter.second.first; |
| 222 | numVerts += skeleton->getNumJoints() * 6; | 303 | numVerts += skeleton->getNumJoints() * VERTICES_PER_BONE; |
| 223 | for (int i = 0; i < skeleton->getNumJoints(); i++) { | 304 | for (int i = 0; i < skeleton->getNumJoints(); i++) { |
| 224 | auto parentIndex = skeleton->getParentIndex(i); | 305 | auto parentIndex = skeleton->getParentIndex(i); |
| 225 | if (parentIndex >= 0) { | 306 | if (parentIndex >= 0) { |
| 226 | numVerts += 2; | 307 | numVerts += VERTICES_PER_LINK; |
| 227 | } | 308 | } |
| 228 | } | 309 | } |
| 229 | } | 310 | } |
| @@ -231,12 +312,12 @@ void AnimDebugDraw::update() { · 1 unmodified line | |||
| 231 | for (auto&& iter : _animNodes) { | 312 | for (auto&& iter : _animNodes) { |
| 232 | AnimNode::Pointer& animNode = iter.second.first; | 313 | AnimNode::Pointer& animNode = iter.second.first; |
| 233 | auto poses = animNode->getPosesInternal(); | 314 | auto poses = animNode->getPosesInternal(); |
| 234 | numVerts += poses.size() * 6; | 315 | numVerts += poses.size() * VERTICES_PER_BONE; |
| 235 | auto skeleton = animNode->getSkeleton(); | 316 | auto skeleton = animNode->getSkeleton(); |
| 236 | for (size_t i = 0; i < poses.size(); i++) { | 317 | for (size_t i = 0; i < poses.size(); i++) { |
| 237 | auto parentIndex = skeleton->getParentIndex(i); | 318 | auto parentIndex = skeleton->getParentIndex(i); |
| 238 | if (parentIndex >= 0) { | 319 | if (parentIndex >= 0) { |
| 239 | numVerts += 2; | 320 | numVerts += VERTICES_PER_LINK; |
| 240 | } | 321 | } |
| 241 | } | 322 | } |
| 242 | } | 323 | } |
| @@ -251,16 +332,17 @@ void AnimDebugDraw::update() { · 8 unmodified lines | |||
| 251 | for (int i = 0; i < skeleton->getNumJoints(); i++) { | 332 | for (int i = 0; i < skeleton->getNumJoints(); i++) { |
| 252 | AnimPose pose = skeleton->getAbsoluteBindPose(i); | 333 | AnimPose pose = skeleton->getAbsoluteBindPose(i); |
| 253 | 334 | ||
| 254 | // draw axes | 335 | const float radius = BONE_RADIUS / (pose.scale.x * rootPose.scale.x); |
| 255 | const float radius = 0.1f; | 336 | |
| 256 | addWireframeSphereWithAxes(rootPose, pose, radius, v); | 337 | // draw bone |
| 338 | addBone(rootPose, pose, radius, v); | ||
| 257 | 339 | ||
| 258 | // line to parent. | 340 | // draw link to parent |
| 259 | auto parentIndex = skeleton->getParentIndex(i); | 341 | auto parentIndex = skeleton->getParentIndex(i); |
| 260 | if (parentIndex >= 0) { | 342 | if (parentIndex >= 0) { |
| 261 | assert(parentIndex < skeleton->getNumJoints()); | 343 | assert(parentIndex < skeleton->getNumJoints()); |
| 262 | AnimPose parentPose = skeleton->getAbsoluteBindPose(parentIndex); | 344 | AnimPose parentPose = skeleton->getAbsoluteBindPose(parentIndex); |
| 263 | addWireframeBoneAxis(rootPose, pose, parentPose, radius, v); | 345 | addLink(rootPose, pose, parentPose, radius, v); |
| 264 | } | 346 | } |
| 265 | } | 347 | } |
| 266 | } | 348 | } |
| @@ -284,14 +366,13 @@ void AnimDebugDraw::update() { · 17 unmodified lines | |||
| 284 | absAnimPose[i] = poses[i]; | 366 | absAnimPose[i] = poses[i]; |
| 285 | } | 367 | } |
| 286 | 368 | ||
| 287 | // draw axes | 369 | const float radius = BONE_RADIUS / (absAnimPose[i].scale.x * rootPose.scale.x); |
| 288 | const float radius = 0.1f; | 370 | addBone(rootPose, absAnimPose[i], radius, v); |
| 289 | addWireframeSphereWithAxes(rootPose, absAnimPose[i], radius, v); | ||
| 290 | 371 | ||
| 291 | if (parentIndex >= 0) { | 372 | if (parentIndex >= 0) { |
| 292 | assert((size_t)parentIndex < poses.size()); | 373 | assert((size_t)parentIndex < poses.size()); |
| 293 | // draw line to parent | 374 | // draw line to parent |
| 294 | addWireframeBoneAxis(rootPose, absAnimPose[i], absAnimPose[parentIndex], radius, v); | 375 | addLink(rootPose, absAnimPose[i], absAnimPose[parentIndex], radius, v); |
| 295 | } | 376 | } |
| 296 | } | 377 | } |
| 297 | } | 378 | } |