void FSkyVertexBuffer::SkyVertex(int r, int c, bool zflip) { static const FAngle maxSideAngle = 60.f; static const float scale = 10000.; FAngle topAngle = (c / (float)mColumns * 360.f); FAngle sideAngle = maxSideAngle * (mRows - r) / mRows; float height = sideAngle.Sin(); float realRadius = scale * sideAngle.Cos(); FVector2 pos = topAngle.ToVector(realRadius); float z = (!zflip) ? scale * height : -scale * height; FSkyVertex vert; vert.color = r == 0 ? 0xffffff : 0xffffffff; // And the texture coordinates. if (!zflip) // Flipped Y is for the lower hemisphere. { vert.u = (-c / (float)mColumns); vert.v = (r / (float)mRows); } else { vert.u = (-c / (float)mColumns); vert.v = 1.0f + ((mRows - r) / (float)mRows); } if (r != 4) z += 300; // And finally the vertex. vert.x = -pos.X; // Doom mirrors the sky vertically! vert.y = z - 1.f; vert.z = pos.Y; mVertices.Push(vert); }
void P_BobWeapon (player_t *player, float *x, float *y, double ticfrac) { static float curbob; double xx[2], yy[2]; AWeapon *weapon; float bobtarget; weapon = player->ReadyWeapon; if (weapon == nullptr || weapon->WeaponFlags & WIF_DONTBOB) { *x = *y = 0; return; } // [XA] Get the current weapon's bob properties. int bobstyle = weapon->BobStyle; float BobSpeed = (weapon->BobSpeed * 128); float Rangex = weapon->BobRangeX; float Rangey = weapon->BobRangeY; for (int i = 0; i < 2; i++) { // Bob the weapon based on movement speed. ([SP] And user's bob speed setting) FAngle angle = (BobSpeed * player->userinfo.GetWBobSpeed() * 35 / TICRATE*(level.time - 1 + i)) * (360.f / 8192.f); // [RH] Smooth transitions between bobbing and not-bobbing frames. // This also fixes the bug where you can "stick" a weapon off-center by // shooting it when it's at the peak of its swing. bobtarget = float((player->WeaponState & WF_WEAPONBOBBING) ? player->bob : 0.); if (curbob != bobtarget) { if (fabsf(bobtarget - curbob) <= 1) { curbob = bobtarget; } else { float zoom = MAX(1.f, fabsf(curbob - bobtarget) / 40); if (curbob > bobtarget) { curbob -= zoom; } else { curbob += zoom; } } } if (curbob != 0) { float bobx = float(player->bob * Rangex); float boby = float(player->bob * Rangey); switch (bobstyle) { case AWeapon::BobNormal: xx[i] = bobx * angle.Cos(); yy[i] = boby * fabsf(angle.Sin()); break; case AWeapon::BobInverse: xx[i] = bobx*angle.Cos(); yy[i] = boby * (1.f - fabsf(angle.Sin())); break; case AWeapon::BobAlpha: xx[i] = bobx * angle.Sin(); yy[i] = boby * fabsf(angle.Sin()); break; case AWeapon::BobInverseAlpha: xx[i] = bobx * angle.Sin(); yy[i] = boby * (1.f - fabsf(angle.Sin())); break; case AWeapon::BobSmooth: xx[i] = bobx*angle.Cos(); yy[i] = 0.5f * (boby * (1.f - ((angle * 2).Cos()))); break; case AWeapon::BobInverseSmooth: xx[i] = bobx*angle.Cos(); yy[i] = 0.5f * (boby * (1.f + ((angle * 2).Cos()))); } } else { xx[i] = 0; yy[i] = 0; } } *x = (float)(xx[0] * (1. - ticfrac) + xx[1] * ticfrac); *y = (float)(yy[0] * (1. - ticfrac) + yy[1] * ticfrac); }
bool GLSprite::CalculateVertices(HWDrawInfo *di, FVector3 *v, DVector3 *vp) { const auto &HWAngles = di->Viewpoint.HWAngles; if (actor != nullptr && (actor->renderflags & RF_SPRITETYPEMASK) == RF_FLATSPRITE) { Matrix3x4 mat; mat.MakeIdentity(); // [MC] Rotate around the center or offsets given to the sprites. // Counteract any existing rotations, then rotate the angle. // Tilt the actor up or down based on pitch (increase 'somersaults' forward). // Then counteract the roll and DO A BARREL ROLL. FAngle pitch = (float)-Angles.Pitch.Degrees; pitch.Normalized180(); mat.Translate(x, z, y); mat.Rotate(0, 1, 0, 270. - Angles.Yaw.Degrees); mat.Rotate(1, 0, 0, pitch.Degrees); if (actor->renderflags & RF_ROLLCENTER) { float cx = (x1 + x2) * 0.5; float cy = (y1 + y2) * 0.5; mat.Translate(cx - x, 0, cy - y); mat.Rotate(0, 1, 0, - Angles.Roll.Degrees); mat.Translate(-cx, -z, -cy); } else { mat.Rotate(0, 1, 0, - Angles.Roll.Degrees); mat.Translate(-x, -z, -y); } v[0] = mat * FVector3(x2, z, y2); v[1] = mat * FVector3(x1, z, y2); v[2] = mat * FVector3(x2, z, y1); v[3] = mat * FVector3(x1, z, y1); return true; } // [BB] Billboard stuff const bool drawWithXYBillboard = ((particle && gl_billboard_particles) || (!(actor && actor->renderflags & RF_FORCEYBILLBOARD) //&& di->mViewActor != nullptr && (gl_billboard_mode == 1 || (actor && actor->renderflags & RF_FORCEXYBILLBOARD)))); const bool drawBillboardFacingCamera = gl_billboard_faces_camera; // [Nash] has +ROLLSPRITE const bool drawRollSpriteActor = (actor != nullptr && actor->renderflags & RF_ROLLSPRITE); // [fgsfds] check sprite type mask uint32_t spritetype = (uint32_t)-1; if (actor != nullptr) spritetype = actor->renderflags & RF_SPRITETYPEMASK; // [Nash] is a flat sprite const bool isFlatSprite = (actor != nullptr) && (spritetype == RF_WALLSPRITE || spritetype == RF_FLATSPRITE); const bool useOffsets = (actor != nullptr) && !(actor->renderflags & RF_ROLLCENTER); // [Nash] check for special sprite drawing modes if (drawWithXYBillboard || drawBillboardFacingCamera || drawRollSpriteActor || isFlatSprite) { // Compute center of sprite float xcenter = (x1 + x2)*0.5; float ycenter = (y1 + y2)*0.5; float zcenter = (z1 + z2)*0.5; float xx = -xcenter + x; float zz = -zcenter + z; float yy = -ycenter + y; Matrix3x4 mat; mat.MakeIdentity(); mat.Translate(xcenter, zcenter, ycenter); // move to sprite center // Order of rotations matters. Perform yaw rotation (Y, face camera) before pitch (X, tilt up/down). if (drawBillboardFacingCamera && !isFlatSprite) { // [CMB] Rotate relative to camera XY position, not just camera direction, // which is nicer in VR float xrel = xcenter - vp->X; float yrel = ycenter - vp->Y; float absAngleDeg = RAD2DEG(atan2(-yrel, xrel)); float counterRotationDeg = 270. - HWAngles.Yaw.Degrees; // counteracts existing sprite rotation float relAngleDeg = counterRotationDeg + absAngleDeg; mat.Rotate(0, 1, 0, relAngleDeg); } // [fgsfds] calculate yaw vectors float yawvecX = 0, yawvecY = 0, rollDegrees = 0; float angleRad = (270. - HWAngles.Yaw).Radians(); if (actor) rollDegrees = Angles.Roll.Degrees; if (isFlatSprite) { yawvecX = Angles.Yaw.Cos(); yawvecY = Angles.Yaw.Sin(); } // [fgsfds] Rotate the sprite about the sight vector (roll) if (spritetype == RF_WALLSPRITE) { mat.Rotate(0, 1, 0, 0); if (drawRollSpriteActor) { if (useOffsets) mat.Translate(xx, zz, yy); mat.Rotate(yawvecX, 0, yawvecY, rollDegrees); if (useOffsets) mat.Translate(-xx, -zz, -yy); } } else if (drawRollSpriteActor) { if (useOffsets) mat.Translate(xx, zz, yy); if (drawWithXYBillboard) { mat.Rotate(-sin(angleRad), 0, cos(angleRad), -HWAngles.Pitch.Degrees); } mat.Rotate(cos(angleRad), 0, sin(angleRad), rollDegrees); if (useOffsets) mat.Translate(-xx, -zz, -yy); } else if (drawWithXYBillboard) { // Rotate the sprite about the vector starting at the center of the sprite // triangle strip and with direction orthogonal to where the player is looking // in the x/y plane. mat.Rotate(-sin(angleRad), 0, cos(angleRad), -HWAngles.Pitch.Degrees); } mat.Translate(-xcenter, -zcenter, -ycenter); // retreat from sprite center v[0] = mat * FVector3(x1, z1, y1); v[1] = mat * FVector3(x2, z1, y2); v[2] = mat * FVector3(x1, z2, y1); v[3] = mat * FVector3(x2, z2, y2); } else // traditional "Y" billboard mode { v[0] = FVector3(x1, z1, y1); v[1] = FVector3(x2, z1, y2); v[2] = FVector3(x1, z2, y1); v[3] = FVector3(x2, z2, y2); } return false; }