From 980a31075521762a1a17925c59a9127cb39c0317 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Sun, 1 May 2016 14:08:09 -0500 Subject: [PATCH 1/7] GZDoom Roll Submission --- src/gl/scene/gl_sprite.cpp | 98 +++++++++++++++++++++++++++++++++----- 1 file changed, 85 insertions(+), 13 deletions(-) diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 3f90b251e..a596380a6 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -264,7 +264,8 @@ void GLSprite::Draw(int pass) && (gl_billboard_mode == 1 || (actor && actor->renderflags & RF_FORCEXYBILLBOARD)))); const bool drawBillboardFacingCamera = gl_billboard_faces_camera; - + // [Nash] has +ROLLSPRITE + const bool drawRollSpriteActor = (actor != NULL && actor->renderflags & RF_ROLLSPRITE); gl_RenderState.Apply(); FVector3 v1; @@ -272,7 +273,15 @@ void GLSprite::Draw(int pass) FVector3 v3; FVector3 v4; - if (drawWithXYBillboard || drawBillboardFacingCamera) + // [fgsfds] check sprite type mask + DWORD spritetype = (DWORD)-1; + if (actor != NULL) spritetype = actor->renderflags & RF_SPRITETYPEMASK; + + // [Nash] is a flat sprite + const bool isFlatSprite = (actor != NULL) && (spritetype == RF_WALLSPRITE || spritetype == RF_FLATSPRITE || spritetype == RF_PITCHFLATSPRITE); + + // [Nash] check for special sprite drawing modes + if (drawWithXYBillboard || drawBillboardFacingCamera || drawRollSpriteActor || isFlatSprite) { // Compute center of sprite float xcenter = (x1 + x2)*0.5; @@ -284,7 +293,8 @@ void GLSprite::Draw(int pass) 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) { + if (drawBillboardFacingCamera) + { // [CMB] Rotate relative to camera XY position, not just camera direction, // which is nicer in VR float xrel = xcenter - GLRenderer->mViewActor->X(); @@ -296,13 +306,64 @@ void GLSprite::Draw(int pass) mat.Rotate(0, 1, 0, relAngleDeg); } - if (drawWithXYBillboard) + // [fgsfds] calculate yaw vectors + float yawvecX = 0, yawvecY = 0, FlatAngle = 0, rollDegrees = 0; + float angleRad = (270. - GLRenderer->mAngles.Yaw).Radians(); + if (actor) rollDegrees = actor->Angles.Roll.Degrees; + if (isFlatSprite) + { + yawvecX = actor->Angles.Yaw.Cos(); + yawvecY = actor->Angles.Yaw.Sin(); + FlatAngle = actor->FlatAngle.Degrees; + } + + // [MC] This is the only thing that I changed in Nash's submission which + // was constantly applying roll to everything. That was wrong. Flat sprites + // with roll literally look like paper thing space ships trying to swerve. + // However, it does well with wall sprites. + // Also, renamed FLOORSPRITE to FLATSPRITE because that's technically incorrect. + // I plan on adding proper FLOORSPRITEs which can actually curve along sloped + // 3D floors later... if possible. + + // Here we need some form of priority in order to work. + if (spritetype == RF_PITCHFLATSPRITE) + { + float pitchDegrees = actor->Angles.Pitch.Degrees; + mat.Rotate(0, 1, 0, -FlatAngle); + if (drawRollSpriteActor) + { + mat.Rotate(yawvecX, 0, yawvecY, rollDegrees); + } + mat.Rotate(-yawvecY, 0, yawvecX, pitchDegrees); + } + else if (spritetype == RF_FLATSPRITE) + { // [fgsfds] rotate the sprite so it faces upwards/downwards + mat.Rotate(-yawvecY, 0, yawvecX, -90.f); + if (drawRollSpriteActor) + mat.Rotate(yawvecX, 0, yawvecY, rollDegrees); + } + // [fgsfds] Rotate the sprite about the sight vector (roll) + else if (spritetype == RF_WALLSPRITE) + { + mat.Rotate(0, 1, 0, -FlatAngle); + if (drawRollSpriteActor) + mat.Rotate(yawvecX, 0, yawvecY, rollDegrees); + } + else if (drawRollSpriteActor) + { + if (drawWithXYBillboard) + { + mat.Rotate(-sin(angleRad), 0, cos(angleRad), -GLRenderer->mAngles.Pitch.Degrees); + } + mat.Rotate(cos(angleRad), 0, sin(angleRad), rollDegrees); + } + + // apply the transform + 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. - float angleRad = (270. - GLRenderer->mAngles.Yaw).Radians(); - mat.Rotate(-sin(angleRad), 0, cos(angleRad), -GLRenderer->mAngles.Pitch.Degrees); } mat.Translate(-xcenter, -zcenter, -ycenter); // retreat from sprite center @@ -623,16 +684,25 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) bottomclip = rendersector->PortalBlocksMovement(sector_t::floor) ? -LARGE_VALUE : rendersector->GetPortalPlaneZ(sector_t::floor); x = thingpos.X; - z = thingpos.Z - thing->Floorclip; y = thingpos.Y; - // [RH] Make floatbobbing a renderer-only effect. - if (thing->flags2 & MF2_FLOATBOB) + DWORD spritetype = thing->renderflags & RF_SPRITETYPEMASK; + + switch (spritetype) { - float fz = thing->GetBobOffset(r_TicFracF); - z += fz; + case RF_FLATSPRITE: + case RF_PITCHFLATSPRITE: + z = thingpos.Z; + default: + z = thingpos.Z - thing->Floorclip; + // [RH] Make floatbobbing a renderer-only effect. + if (thing->flags2 & MF2_FLOATBOB) + { + float fz = thing->GetBobOffset(r_TicFracF); + z += fz; + } + break; } - modelframe = gl_FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED)); if (!modelframe) { @@ -677,7 +747,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) float viewvecX; float viewvecY; - switch (thing->renderflags & RF_SPRITETYPEMASK) + switch (spritetype) { case RF_FACESPRITE: viewvecX = GLRenderer->mViewVector.X; @@ -689,6 +759,8 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) y2 = y + viewvecX*rightfac; break; + case RF_FLATSPRITE: + case RF_PITCHFLATSPRITE: case RF_WALLSPRITE: viewvecX = thing->Angles.Yaw.Cos(); viewvecY = thing->Angles.Yaw.Sin(); From a163220e8c25b3eb5bbba85c0740d73cff3f09f4 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Sun, 1 May 2016 17:30:30 -0500 Subject: [PATCH 2/7] Removed FlatAngle. --- src/gl/scene/gl_sprite.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index a596380a6..a99eb5b82 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -307,14 +307,13 @@ void GLSprite::Draw(int pass) } // [fgsfds] calculate yaw vectors - float yawvecX = 0, yawvecY = 0, FlatAngle = 0, rollDegrees = 0; + float yawvecX = 0, yawvecY = 0, rollDegrees = 0; float angleRad = (270. - GLRenderer->mAngles.Yaw).Radians(); if (actor) rollDegrees = actor->Angles.Roll.Degrees; if (isFlatSprite) { yawvecX = actor->Angles.Yaw.Cos(); yawvecY = actor->Angles.Yaw.Sin(); - FlatAngle = actor->FlatAngle.Degrees; } // [MC] This is the only thing that I changed in Nash's submission which @@ -329,7 +328,7 @@ void GLSprite::Draw(int pass) if (spritetype == RF_PITCHFLATSPRITE) { float pitchDegrees = actor->Angles.Pitch.Degrees; - mat.Rotate(0, 1, 0, -FlatAngle); + mat.Rotate(0, 1, 0, 0); if (drawRollSpriteActor) { mat.Rotate(yawvecX, 0, yawvecY, rollDegrees); @@ -345,7 +344,7 @@ void GLSprite::Draw(int pass) // [fgsfds] Rotate the sprite about the sight vector (roll) else if (spritetype == RF_WALLSPRITE) { - mat.Rotate(0, 1, 0, -FlatAngle); + mat.Rotate(0, 1, 0, 0); if (drawRollSpriteActor) mat.Rotate(yawvecX, 0, yawvecY, rollDegrees); } From 673dab7f23c933146d460187f9f4f5b54b59bd0c Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Mon, 2 May 2016 06:29:19 -0500 Subject: [PATCH 3/7] Removed PITCHFLATSPRITE. FLATSPRITE now encompasses the behavior. --- src/gl/scene/gl_sprite.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index a99eb5b82..abefe6191 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -325,7 +325,7 @@ void GLSprite::Draw(int pass) // 3D floors later... if possible. // Here we need some form of priority in order to work. - if (spritetype == RF_PITCHFLATSPRITE) + if (spritetype == RF_FLATSPRITE) { float pitchDegrees = actor->Angles.Pitch.Degrees; mat.Rotate(0, 1, 0, 0); @@ -335,12 +335,6 @@ void GLSprite::Draw(int pass) } mat.Rotate(-yawvecY, 0, yawvecX, pitchDegrees); } - else if (spritetype == RF_FLATSPRITE) - { // [fgsfds] rotate the sprite so it faces upwards/downwards - mat.Rotate(-yawvecY, 0, yawvecX, -90.f); - if (drawRollSpriteActor) - mat.Rotate(yawvecX, 0, yawvecY, rollDegrees); - } // [fgsfds] Rotate the sprite about the sight vector (roll) else if (spritetype == RF_WALLSPRITE) { From 9ec3093a3429a5c483c3a3165ca23e519631af9d Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Mon, 2 May 2016 08:52:44 -0500 Subject: [PATCH 4/7] Fixed some missed cases. --- src/gl/scene/gl_sprite.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index abefe6191..52c9f6aa9 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -278,7 +278,7 @@ void GLSprite::Draw(int pass) if (actor != NULL) spritetype = actor->renderflags & RF_SPRITETYPEMASK; // [Nash] is a flat sprite - const bool isFlatSprite = (actor != NULL) && (spritetype == RF_WALLSPRITE || spritetype == RF_FLATSPRITE || spritetype == RF_PITCHFLATSPRITE); + const bool isFlatSprite = (actor != NULL) && (spritetype == RF_WALLSPRITE || spritetype == RF_FLATSPRITE); // [Nash] check for special sprite drawing modes if (drawWithXYBillboard || drawBillboardFacingCamera || drawRollSpriteActor || isFlatSprite) @@ -684,7 +684,6 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) switch (spritetype) { case RF_FLATSPRITE: - case RF_PITCHFLATSPRITE: z = thingpos.Z; default: z = thingpos.Z - thing->Floorclip; @@ -753,7 +752,6 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) break; case RF_FLATSPRITE: - case RF_PITCHFLATSPRITE: case RF_WALLSPRITE: viewvecX = thing->Angles.Yaw.Cos(); viewvecY = thing->Angles.Yaw.Sin(); From 16bea6cf1fdc59dc8a724571477d20597e43cbb3 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Mon, 2 May 2016 10:46:44 -0500 Subject: [PATCH 5/7] - Fixed: Roll must orient the rotation based on pitch, not the other way around. --- src/gl/scene/gl_sprite.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 52c9f6aa9..2301fc7ba 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -329,11 +329,11 @@ void GLSprite::Draw(int pass) { float pitchDegrees = actor->Angles.Pitch.Degrees; mat.Rotate(0, 1, 0, 0); + mat.Rotate(-yawvecY, 0, yawvecX, pitchDegrees); if (drawRollSpriteActor) { mat.Rotate(yawvecX, 0, yawvecY, rollDegrees); } - mat.Rotate(-yawvecY, 0, yawvecX, pitchDegrees); } // [fgsfds] Rotate the sprite about the sight vector (roll) else if (spritetype == RF_WALLSPRITE) From e58c6de7d68cb6c901a85a676bcae2243c524d51 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Sun, 5 Jun 2016 15:14:40 -0500 Subject: [PATCH 6/7] DONTFLIP flag prevents the backside from flipping over. --- src/gl/scene/gl_sprite.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 2301fc7ba..37d9ebd82 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -279,6 +279,7 @@ void GLSprite::Draw(int pass) // [Nash] is a flat sprite const bool isFlatSprite = (actor != NULL) && (spritetype == RF_WALLSPRITE || spritetype == RF_FLATSPRITE); + const bool dontFlip = (actor != nullptr) && (actor->renderflags & RF_DONTFLIP); // [Nash] check for special sprite drawing modes if (drawWithXYBillboard || drawBillboardFacingCamera || drawRollSpriteActor || isFlatSprite) @@ -327,8 +328,12 @@ void GLSprite::Draw(int pass) // Here we need some form of priority in order to work. if (spritetype == RF_FLATSPRITE) { + DVector3 diff = actor->Vec3To(GLRenderer->mViewActor); + DAngle angto = diff.Angle(); + angto = deltaangle(actor->Angles.Yaw, angto); + float pitchDegrees = actor->Angles.Pitch.Degrees; - mat.Rotate(0, 1, 0, 0); + mat.Rotate(0, 1, 0, (!dontFlip || (fabs(angto) < 90.)) ? 0 : 180); mat.Rotate(-yawvecY, 0, yawvecX, pitchDegrees); if (drawRollSpriteActor) { From b2d2389343cbd2ac8247a321cf229a22bb14956d Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Sun, 5 Jun 2016 15:21:19 -0500 Subject: [PATCH 7/7] Fixed: Slanted flat + roll sprites didn't take DONTFLIP into account. --- src/gl/scene/gl_sprite.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 37d9ebd82..fb6d6b411 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -333,11 +333,12 @@ void GLSprite::Draw(int pass) angto = deltaangle(actor->Angles.Yaw, angto); float pitchDegrees = actor->Angles.Pitch.Degrees; - mat.Rotate(0, 1, 0, (!dontFlip || (fabs(angto) < 90.)) ? 0 : 180); - mat.Rotate(-yawvecY, 0, yawvecX, pitchDegrees); + bool noFlipSprite = (!dontFlip || (fabs(angto) < 90.)); + mat.Rotate(0, 1, 0, (noFlipSprite) ? 0 : 180); + mat.Rotate(-yawvecY, 0, yawvecX, (noFlipSprite) ? -pitchDegrees : pitchDegrees); if (drawRollSpriteActor) { - mat.Rotate(yawvecX, 0, yawvecY, rollDegrees); + mat.Rotate(yawvecX, 0, yawvecY, (noFlipSprite) ? -rollDegrees : rollDegrees); } } // [fgsfds] Rotate the sprite about the sight vector (roll)