static inline void DrawFeatureColVol(const CFeature* f) { const CollisionVolume* v = f->collisionVolume; if (!f->IsInLosForAllyTeam(gu->myAllyTeam) && !gu->spectatingFullView) return; if (!camera->InView(f->pos, f->drawRadius)) return; const bool vCustomType = (v->GetVolumeType() < CollisionVolume::COLVOL_TYPE_SPHERE); const bool vCustomDims = ((v->GetOffsets()).SqLength() >= 1.0f || math::fabs(v->GetBoundingRadius() - f->radius) >= 1.0f); glPushMatrix(); glMultMatrixf(f->GetTransformMatrixRef()); DrawObjectMidAndAimPos(f); if (!v->IgnoreHits()) { DrawCollisionVolume(v); } if (vCustomType || vCustomDims) { // assume this is a custom volume glColor3f(0.5f, 0.5f, 0.5f); glScalef(f->radius, f->radius, f->radius); glWireSphere(&volumeDisplayListIDs[0], 20, 20); } glPopMatrix(); }
static inline void DrawCollisionVolume(const CollisionVolume* vol) { static unsigned int listIDs[3] = {0, 0, 0}; switch (vol->GetVolumeType()) { case CollisionVolume::COLVOL_TYPE_FOOTPRINT: // fall through, this is too hard to render correctly so just render sphere :) case CollisionVolume::COLVOL_TYPE_SPHERE: // fall through, sphere is special case of ellipsoid case CollisionVolume::COLVOL_TYPE_ELLIPSOID: { // scaled sphere: radius, slices, stacks glTranslatef(vol->GetOffset(0), vol->GetOffset(1), vol->GetOffset(2)); glScalef(vol->GetHScale(0), vol->GetHScale(1), vol->GetHScale(2)); glWireSphere(&listIDs[0], 20, 20); } break; case CollisionVolume::COLVOL_TYPE_CYLINDER: { // scaled cylinder: base-radius, top-radius, height, slices, stacks // // (cylinder base is drawn at unit center by default so add offset // by half major axis to visually match the mathematical situation, // height of the cylinder equals the unit's full major axis) switch (vol->GetPrimaryAxis()) { case CollisionVolume::COLVOL_AXIS_X: { glTranslatef(-(vol->GetHScale(0)), 0.0f, 0.0f); glTranslatef(vol->GetOffset(0), vol->GetOffset(1), vol->GetOffset(2)); glScalef(vol->GetScale(0), vol->GetHScale(1), vol->GetHScale(2)); glRotatef( 90.0f, 0.0f, 1.0f, 0.0f); } break; case CollisionVolume::COLVOL_AXIS_Y: { glTranslatef(0.0f, -(vol->GetHScale(1)), 0.0f); glTranslatef(vol->GetOffset(0), vol->GetOffset(1), vol->GetOffset(2)); glScalef(vol->GetHScale(0), vol->GetScale(1), vol->GetHScale(2)); glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); } break; case CollisionVolume::COLVOL_AXIS_Z: { glTranslatef(0.0f, 0.0f, -(vol->GetHScale(2))); glTranslatef(vol->GetOffset(0), vol->GetOffset(1), vol->GetOffset(2)); glScalef(vol->GetHScale(0), vol->GetHScale(1), vol->GetScale(2)); } break; } glWireCylinder(&listIDs[1], 20, 1.0f); } break; case CollisionVolume::COLVOL_TYPE_BOX: { // scaled cube: length, width, height glTranslatef(vol->GetOffset(0), vol->GetOffset(1), vol->GetOffset(2)); glScalef(vol->GetScale(0), vol->GetScale(1), vol->GetScale(2)); glWireCube(&listIDs[2]); } break; } }
static inline void DrawCollisionVolume(const CollisionVolume* vol) { glPushMatrix(); switch (vol->GetVolumeType()) { case CollisionVolume::COLVOL_TYPE_ELLIPSOID: case CollisionVolume::COLVOL_TYPE_SPHERE: { // scaled sphere is special case of ellipsoid: radius, slices, stacks glTranslatef(vol->GetOffset(0), vol->GetOffset(1), vol->GetOffset(2)); glScalef(vol->GetHScale(0), vol->GetHScale(1), vol->GetHScale(2)); glWireSphere(&volumeDisplayListIDs[0], 20, 20); } break; case CollisionVolume::COLVOL_TYPE_CYLINDER: { // scaled cylinder: base-radius, top-radius, height, slices, stacks // // (cylinder base is drawn at unit center by default so add offset // by half major axis to visually match the mathematical situation, // height of the cylinder equals the unit's full major axis) switch (vol->GetPrimaryAxis()) { case CollisionVolume::COLVOL_AXIS_X: { glTranslatef(-(vol->GetHScale(0)), 0.0f, 0.0f); glTranslatef(vol->GetOffset(0), vol->GetOffset(1), vol->GetOffset(2)); glScalef(vol->GetScale(0), vol->GetHScale(1), vol->GetHScale(2)); glRotatef( 90.0f, 0.0f, 1.0f, 0.0f); } break; case CollisionVolume::COLVOL_AXIS_Y: { glTranslatef(0.0f, -(vol->GetHScale(1)), 0.0f); glTranslatef(vol->GetOffset(0), vol->GetOffset(1), vol->GetOffset(2)); glScalef(vol->GetHScale(0), vol->GetScale(1), vol->GetHScale(2)); glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); } break; case CollisionVolume::COLVOL_AXIS_Z: { glTranslatef(0.0f, 0.0f, -(vol->GetHScale(2))); glTranslatef(vol->GetOffset(0), vol->GetOffset(1), vol->GetOffset(2)); glScalef(vol->GetHScale(0), vol->GetHScale(1), vol->GetScale(2)); } break; } glWireCylinder(&volumeDisplayListIDs[1], 20, 1.0f); } break; case CollisionVolume::COLVOL_TYPE_BOX: { // scaled cube: length, width, height glTranslatef(vol->GetOffset(0), vol->GetOffset(1), vol->GetOffset(2)); glScalef(vol->GetScale(0), vol->GetScale(1), vol->GetScale(2)); glWireCube(&volumeDisplayListIDs[2]); } break; } glPopMatrix(); }
static inline void DrawUnitColVol(const CUnit* u) { if (!(u->losStatus[gu->myAllyTeam] & LOS_INLOS) && !gu->spectatingFullView) return; if (!camera->InView(u->drawMidPos, u->drawRadius)) return; const CollisionVolume* v = u->collisionVolume; const bool vCustomType = (v->GetVolumeType() < CollisionVolume::COLVOL_TYPE_SPHERE); const bool vCustomDims = ((v->GetOffsets()).SqLength() >= 1.0f || math::fabs(v->GetBoundingRadius() - u->radius) >= 1.0f); glPushMatrix(); glMultMatrixf(u->GetTransformMatrix()); DrawObjectMidAndAimPos(u); if (v->DefaultToPieceTree()) { // draw only the piece volumes for less clutter CMatrix44f mat(u->relMidPos * float3(0.0f, -1.0f, 0.0f)); DrawUnitDebugPieceTree(u->localModel->GetRoot(), u->lastAttackedPiece, u->lastAttackedPieceFrame, mat); } else { if (!v->IgnoreHits()) { // make it fade red under attack if (u->lastAttackFrame > 0 && ((gs->frameNum - u->lastAttackFrame) < 150)) { glColor3f((1.0f - ((gs->frameNum - u->lastAttackFrame) / 150.0f)), 0.0f, 0.0f); } DrawCollisionVolume(v); if (u->lastAttackFrame > 0 && ((gs->frameNum - u->lastAttackFrame) < 150)) { glColorf3(DEFAULT_VOLUME_COLOR); } } } if (vCustomType || vCustomDims) { // assume this is a custom volume glColor3f(0.5f, 0.5f, 0.5f); glScalef(u->radius, u->radius, u->radius); glWireSphere(&volumeDisplayListIDs[0], 20, 20); } glPopMatrix(); }
static inline void DrawFeatureColVol(const CFeature* f) { const CollisionVolume* v = &f->collisionVolume; if (f->IsInVoid()) return; if (!f->IsInLosForAllyTeam(gu->myAllyTeam) && !gu->spectatingFullView) return; if (!camera->InView(f->pos, f->GetDrawRadius())) return; const bool vCustomType = (v->GetVolumeType() < CollisionVolume::COLVOL_TYPE_SPHERE); const bool vCustomDims = ((v->GetOffsets()).SqLength() >= 1.0f || math::fabs(v->GetBoundingRadius() - f->radius) >= 1.0f); glPushMatrix(); glMultMatrixf(f->GetTransformMatrixRef()); DrawObjectMidAndAimPos(f); if (v->DefaultToPieceTree()) { // draw only the piece volumes for less clutter // note: relMidPos transform is on the stack at this // point but all piece-positions are relative to pos // --> undo it glTranslatef3(-f->relMidPos * WORLD_TO_OBJECT_SPACE); DrawObjectDebugPieces(f); glTranslatef3(f->relMidPos * WORLD_TO_OBJECT_SPACE); } else { if (!v->IgnoreHits()) { DrawCollisionVolume(v); } } if (vCustomType || vCustomDims) { // assume this is a custom volume glColor4f(0.5f, 0.5f, 0.5f, 0.35f); glScalef(f->radius, f->radius, f->radius); glWireSphere(&volumeDisplayListIDs[0], 20, 20); } glPopMatrix(); }
static inline void DrawUnitColVol(const CUnit* u) { if (u->IsInVoid()) return; if (!(u->losStatus[gu->myAllyTeam] & LOS_INLOS) && !gu->spectatingFullView) return; if (!camera->InView(u->drawMidPos, u->GetDrawRadius())) return; const CollisionVolume* v = &u->collisionVolume; const bool vCustomType = (v->GetVolumeType() < CollisionVolume::COLVOL_TYPE_SPHERE); const bool vCustomDims = ((v->GetOffsets()).SqLength() >= 1.0f || math::fabs(v->GetBoundingRadius() - u->radius) >= 1.0f); GLUquadricObj* q = gluNewQuadric(); gluQuadricDrawStyle(q, GLU_FILL); glDisable(GL_DEPTH_TEST); for (const CWeapon* w: u->weapons) { glPushMatrix(); glTranslatef3(w->aimFromPos); glColor4f(1.0f, 1.0f, 0.0f, 0.4f); gluSphere(q, 1.0f, 5, 5); glPopMatrix(); glPushMatrix(); glTranslatef3(w->weaponMuzzlePos); if (w->HaveTarget()) { glColor4f(1.0f, 0.8f, 0.0f, 0.4f); } else { glColor4f(1.0f, 0.0f, 0.0f, 0.4f); } gluSphere(q, 1.0f, 5, 5); glPopMatrix(); if (w->HaveTarget()) { glPushMatrix(); glTranslatef3(w->GetCurrentTargetPos()); glColor4f(1.0f, 0.8f, 0.0f, 0.4f); gluSphere(q, 1.0f, 5, 5); glPopMatrix(); } } glColorf4(DEFAULT_VOLUME_COLOR); glEnable(GL_DEPTH_TEST); gluDeleteQuadric(q); glPushMatrix(); glMultMatrixf(u->GetTransformMatrix()); DrawObjectMidAndAimPos(u); if (v->DefaultToPieceTree()) { // draw only the piece volumes for less clutter // note: relMidPos transform is on the stack at this // point but all piece-positions are relative to pos // --> undo it glTranslatef3(-u->relMidPos * WORLD_TO_OBJECT_SPACE); DrawObjectDebugPieces(u); glTranslatef3(u->relMidPos * WORLD_TO_OBJECT_SPACE); } else { if (!v->IgnoreHits()) { // make it fade red under attack if (u->lastAttackFrame > 0 && ((gs->frameNum - u->lastAttackFrame) < 150)) { glColor3f((1.0f - ((gs->frameNum - u->lastAttackFrame) / 150.0f)), 0.0f, 0.0f); } // if drawing this, disable the DrawObjectMidAndAimPos call // DrawCollisionVolume((u->localModel).GetBoundingVolume()); DrawCollisionVolume(v); if (u->lastAttackFrame > 0 && ((gs->frameNum - u->lastAttackFrame) < 150)) { glColorf4(DEFAULT_VOLUME_COLOR); } } } if (u->shieldWeapon != nullptr) { const CPlasmaRepulser* shield = static_cast<const CPlasmaRepulser*>(u->shieldWeapon); glColor4f(0.0f, 0.0f, 0.6f, 0.35f); DrawCollisionVolume(&shield->collisionVolume); } if (vCustomType || vCustomDims) { // assume this is a custom volume glColor4f(0.5f, 0.5f, 0.5f, 0.35f); glScalef(u->radius, u->radius, u->radius); glWireSphere(&volumeDisplayListIDs[0], 20, 20); } glPopMatrix(); }