Quake3World.com
https://www.quake3world.com/forum/

Third person crosshair feature
https://www.quake3world.com/forum/viewtopic.php?f=16&t=54946
Page 1 of 1

Author:  LegendGuard [ 10-03-2022 01:11 PM ]
Post subject:  Third person crosshair feature

I'm trying to do exactly the same of this: https://streamable.com/u1wogh

The crosshair part only happens when the camera is in third person mode.
I tried to use CG_Trace inside CG_DrawCrosshair function in cg_draw.c.
I manipulated Y-axis for the crosshair, but no success:
Code:
trap_R_DrawStretchPic( x + cg.refdef.x + 0.5 * (cg.refdef.width - w),
      y + trace.endpos[2] /*cg.refdef.y*/ + 0.5 * (cg.refdef.height - h),
      w, h, 0, 0, 1, 1, hShader );

I used ZEQ2-Lite source code looking for the feature, I'm not doing pretty well though.
Possibly, some game mod did the same, but idk and I don't have references of this stuff. BFP is the only game mod I see about.
A guy gave me a tip that the view came from the head and could be extracted from a refEntity_t variable.

I hope to obtain any help to reach this goal.

Author:  LegendGuard [ 10-08-2022 03:06 PM ]
Post subject:  Re: Third person crosshair functionality

Yeeeeaaaah! I did it! BFP third person traceable crosshair!

https://github.com/LegendaryGuard/BFP/c ... dfb979b285

Author:  LegendGuard [ 09-12-2023 02:09 AM ]
Post subject:  Re: Third person crosshair functionality

I update the code here, I just made tweaks to make the crosshair move smoothly and now matches 100% to BFP ones.

These are the commits:
https://github.com/LegendaryGuard/BFP/c ... f4a2a245eb
https://github.com/LegendaryGuard/BFP/c ... 431de86652

Look further to the commits before implementing this feature.

cg_draw.c -CG_DrawCrosshair- full code:

Code:
static void CG_DrawCrosshair(void) {
   float      w, h;
   qhandle_t   hShader;
   float      f;
   float      x, y;
   int         ca;
   trace_t      trace;
   playerState_t   *ps;
   vec3_t      muzzle, forward, up, start, end;
   static float lastPositionY = 480.0f; // BFP - Last Y position for traceable crosshair to move smoothly like BFP vanilla does

   ps = &cg.predictedPlayerState;

   if ( !cg_drawCrosshair.integer ) {
      return;
   }

   if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR) {
      return;
   }

// BFP - do not brake here when using third person view
#if 0
   if ( cg.renderingThirdPerson ) {
      return;
   }
#endif

#if 0
   // set color based on health
   if ( cg_crosshairHealth.integer ) {
      vec4_t      hcolor;

      CG_ColorForHealth( hcolor );
      trap_R_SetColor( hcolor );
   }
#endif

   // Read: https://www.quake3world.com/forum/viewtopic.php?f=16&t=55019
   CG_SetCrosshairColor(); // BFP - Crosshair color

   w = h = cg_crosshairSize.value;

   // BFP - pulse the size of the crosshair when hitting someone (before: when picking up items)
   f = cg.time - cg.opponentHitBlendTime;
   if ( f > 0 && f < HIT_BLOB_TIME ) {
      f /= HIT_BLOB_TIME;
      // BFP - Make crosshair size starting from biggest to current
      w = LERP( w*2, w, f ); // before: w *= ( 1 + f );
      h = LERP( h*2, h, f ); // before: h *= ( 1 + f );
      if ( cg_crosshairHealth.integer && f <= 0.35f ) { // BFP - BFP crosshair health feature
         trap_R_SetColor( colorRed );
      }
   }

   x = cg_crosshairX.integer;
   y = cg_crosshairY.integer;

   ca = cg_drawCrosshair.integer;
   if (ca < 0) {
      ca = 0;
   }
   hShader = cgs.media.crosshairShader[ ca % NUM_CROSSHAIRS ];

   if ( cg_thirdPerson.integer >= 1 && cg_stableCrosshair.integer <= 0 ) { // BFP - Third person traceable crosshair
      AngleVectors( ps->viewangles, forward, NULL, up );
      VectorCopy( ps->origin, muzzle );
      VectorMA( muzzle, ps->viewheight, up, muzzle );
      VectorMA( muzzle, 14, forward, muzzle );
      VectorCopy( muzzle, start );
      VectorMA( start, 131072, forward, end );
      CG_Trace( &trace, start, NULL, NULL, end, cg.snap->ps.clientNum, CONTENTS_SOLID | CONTENTS_BODY );
      if ( !CG_WorldCoordToScreenCoordFloat( trace.endpos, &x, &y ) ) {
         return;
      }

      CG_AdjustFrom640( &x, &y, &w, &h );

      // BFP - Make the traceable crosshair move smoothly like BFP vanilla does
      // LERP( <last (or initial) position>, <destination>, (float)(cg.frametime / 1000.00f) * <speed factor> );
      y = LERP( lastPositionY, y, (float)(cg.frametime / 1000.00f) * 12.0f );

      trap_R_DrawStretchPic( x - 0.5f * w, // 492.799987
      y - 0.5f * h,
      w, h, 0, 0, 1, 1, hShader );
      lastPositionY = y; // last Y position where it was "lerped"
   } else { // Q3 default crosshair position
      // x: 492.799987
      // y: 364.799987
      CG_AdjustFrom640( &x, &y, &w, &h );
      trap_R_DrawStretchPic( x + cg.refdef.x + 0.5 * (cg.refdef.width - w),
      y + cg.refdef.y + 0.5 * (cg.refdef.height - h),
      w, h, 0, 0, 1, 1, hShader );
   }
}

Author:  LegendGuard [ 10-02-2023 03:03 AM ]
Post subject:  Re: Third person crosshair feature

I just implemented the ESF (Earth Special Forces) style if someone wanna play it:
Code:
#define ESF_STYLE   1   // BFP - That isn't BFP, it's Earth Special Forces (ESF) style :P
static void CG_DrawCrosshair(void) {
   float      w, h;
   qhandle_t   hShader;
   float      f;
   float      x, y;
   int         ca;
   trace_t      trace;
   playerState_t   *ps;
   vec3_t      muzzle, forward, up, start, end;
#if ESF_STYLE
   static float lastPositionX = 640.0f; // BFP - Last X position for traceable crosshair to move smoothly like ESF does
#endif
   static float lastPositionY = 480.0f; // BFP - Last Y position for traceable crosshair to move smoothly like BFP vanilla does

   // BFP - TODO: BFP doesn't use the crosshair as player view,
   // e.g. if the camera angle is 90ยบ, the crosshair should look what's in this view,
   // not what the player sees

   ps = &cg.predictedPlayerState;

   if ( !cg_drawCrosshair.integer ) {
      return;
   }

   if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR) {
      return;
   }

   // Read: https://www.quake3world.com/forum/viewtopic.php?f=16&t=55019
   CG_SetCrosshairColor(); // BFP - Crosshair color

   w = h = cg_crosshairSize.value;

   // BFP - pulse the size of the crosshair when hitting someone (before: when picking up items)
   f = cg.time - cg.opponentHitBlendTime;
   if ( f > 0 && f < HIT_BLOB_TIME ) {
      f /= HIT_BLOB_TIME;
      // BFP - Make crosshair size starting from biggest to current
      w = LERP( w*2, w, f ); // before: w *= ( 1 + f );
      h = LERP( h*2, h, f ); // before: h *= ( 1 + f );
      if ( cg_crosshairHealth.integer && f <= 0.35f ) { // BFP - BFP crosshair health feature
         trap_R_SetColor( colorRed );
      }
   }

   x = cg_crosshairX.integer;
   y = cg_crosshairY.integer;

   ca = cg_drawCrosshair.integer;
   if (ca < 0) {
      ca = 0;
   }
   hShader = cgs.media.crosshairShader[ ca % NUM_CROSSHAIRS ];

   if ( cg_thirdPerson.integer >= 1 && cg_stableCrosshair.integer <= 0 ) { // BFP - Third person traceable crosshair
#if ESF_STYLE
      AngleVectors( cg.snap->ps.viewangles, forward, NULL, up );
      VectorCopy( cg.snap->ps.origin, muzzle );
      VectorMA( muzzle, cg.snap->ps.viewheight, up, muzzle );
#else
      AngleVectors( ps->viewangles, forward, NULL, up );
      VectorCopy( ps->origin, muzzle );
      VectorMA( muzzle, ps->viewheight, up, muzzle );
#endif
      VectorMA( muzzle, 14, forward, muzzle );
      VectorCopy( muzzle, start );
      VectorMA( start, 131072, forward, end );
      CG_Trace( &trace, start, NULL, NULL, end, cg.snap->ps.clientNum, CONTENTS_SOLID | CONTENTS_BODY );
      if ( !CG_WorldCoordToScreenCoordFloat( trace.endpos, &x, &y ) ) {
         return;
      }

      CG_AdjustFrom640( &x, &y, &w, &h );

      // BFP - Make the traceable crosshair move smoothly like BFP vanilla does
      // LERP( <last (or initial) position>, <destination>, (float)(cg.frametime / 1000.00f) * <speed factor> );
#if ESF_STYLE
      x = LERP( lastPositionX, x, (float)(cg.frametime / 1000.00f) * 18.0f );
      y = LERP( lastPositionY, y, (float)(cg.frametime / 1000.00f) * 18.0f );
#else
      y = LERP( lastPositionY, y, (float)(cg.frametime / 1000.00f) * 12.0f );
#endif

      trap_R_DrawStretchPic( x - 0.5f * w, // 492.799987
      y - 0.5f * h,
      w, h, 0, 0, 1, 1, hShader );
#if ESF_STYLE
      lastPositionX = x; // last X position where it was "lerped"
#endif
      lastPositionY = y; // last Y position where it was "lerped"
   } else { // Q3 default crosshair position
      // x: 492.799987
      // y: 364.799987
      CG_AdjustFrom640( &x, &y, &w, &h );
      trap_R_DrawStretchPic( x + cg.refdef.x + 0.5 * (cg.refdef.width - w),
      y + cg.refdef.y + 0.5 * (cg.refdef.height - h),
      w, h, 0, 0, 1, 1, hShader );
   }
}

Page 1 of 1 All times are UTC - 8 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/