void CGameStudioModelRenderer::SavePlayerState(entity_state_t *pplayer) { client_anim_state_t *st; cl_entity_t *ent = IEngineStudio.GetCurrentEntity(); if (!ent) return; st = &g_state; VectorCopy(ent->curstate.angles, st->angles); VectorCopy(ent->curstate.origin, st->origin); VectorCopy(ent->angles, st->realangles); st->sequence = ent->curstate.sequence; st->gaitsequence = pplayer->gaitsequence; st->animtime = ent->curstate.animtime; st->frame = ent->curstate.frame; st->framerate = ent->curstate.framerate; memcpy(st->blending, ent->curstate.blending, 2); memcpy(st->controller, ent->curstate.controller, 4); st->lv = ent->latched; }
/* ============================== StudioDrawPlayer ============================== */ int CGameStudioModelRenderer::StudioDrawPlayer(int flags, entity_state_t *pplayer) { int iret = 0; bool isLocalPlayer = false; // Set up for client? if(m_bLocal && IEngineStudio.GetCurrentEntity() == gEngfuncs.GetLocalPlayer()) { isLocalPlayer = true; } if(isLocalPlayer) { // Store original data SavePlayerState(pplayer); // Copy in client side animation data SetupClientAnimation(pplayer); } // Call real draw function iret = _StudioDrawPlayer(flags, pplayer); // Restore for client? if(isLocalPlayer) { // Restore the original data for the player RestorePlayerState(pplayer); } return iret; }
/* ============================== SetupClientAnimation Called to set up local player's animation values ============================== */ void CGameStudioModelRenderer::SetupClientAnimation(entity_state_t *pplayer) { static double oldtime; double curtime, dt; client_anim_state_t *st; float fr, gs; cl_entity_t *ent = IEngineStudio.GetCurrentEntity(); assert(ent); if(!ent) return; curtime = gEngfuncs.GetClientTime(); dt = curtime - oldtime; dt = min(1.0, max(0.0, dt)); oldtime = curtime; st = &g_clientstate; st->framerate = 1.0; int oldseq = st->sequence; Game_GetSequence(&st->sequence, &st->gaitsequence); //CVAR_GET_FLOAT( "sequence" ); Game_GetOrientation((float *)&st->origin, (float *)&st->angles); st->realangles = st->angles; if(st->sequence != oldseq) { st->frame = 0.0; st->lv.prevsequence = oldseq; st->lv.sequencetime = st->animtime; memcpy(st->lv.prevseqblending, st->blending, 2); memcpy(st->lv.prevcontroller, st->controller, 4); } void *pmodel = (studiohdr_t *)IEngineStudio.Mod_Extradata(ent->model); GetSequenceInfo(pmodel, st, &fr, &gs); st->m_fSequenceLoops = ((GetSequenceFlags(pmodel, st) & STUDIO_LOOPING) != 0); StudioFrameAdvance(st, fr, dt); // gEngfuncs.Con_Printf( "gs %i frame %f\n", st->gaitsequence, st->frame ); ent->angles = st->realangles; ent->curstate.angles = st->angles; ent->curstate.origin = st->origin; ent->curstate.sequence = st->sequence; pplayer->gaitsequence = st->gaitsequence; ent->curstate.animtime = st->animtime; ent->curstate.frame = st->frame; ent->curstate.framerate = st->framerate; memcpy(ent->curstate.blending, st->blending, 2); memcpy(ent->curstate.controller, st->controller, 4); ent->latched = st->lv; }
int CGameStudioModelRenderer::StudioDrawPlayer(int flags, entity_state_t *pplayer) { int iret = 0; bool isLocalPlayer = false; if (m_bLocal && IEngineStudio.GetCurrentEntity() == gEngfuncs.GetLocalPlayer()) isLocalPlayer = true; if (isLocalPlayer) { SavePlayerState(pplayer); SetupClientAnimation(pplayer); } iret = _StudioDrawPlayer(flags, pplayer); if (isLocalPlayer) RestorePlayerState(pplayer); return iret; }
/* ============================== RestorePlayerState Called to restore original player state information ============================== */ void CGameStudioModelRenderer::RestorePlayerState(entity_state_t *pplayer) { client_anim_state_t *st; cl_entity_t * ent = IEngineStudio.GetCurrentEntity(); assert(ent); if(!ent) return; st = &g_clientstate; st->angles = ent->curstate.angles; st->origin = ent->curstate.origin; st->realangles = ent->angles; st->sequence = ent->curstate.sequence; st->gaitsequence = pplayer->gaitsequence; st->animtime = ent->curstate.animtime; st->frame = ent->curstate.frame; st->framerate = ent->curstate.framerate; memcpy(st->blending, ent->curstate.blending, 2); memcpy(st->controller, ent->curstate.controller, 4); st->lv = ent->latched; st = &g_state; ent->curstate.angles = st->angles; ent->curstate.origin = st->origin; ent->angles = st->realangles; ent->curstate.sequence = st->sequence; pplayer->gaitsequence = st->gaitsequence; ent->curstate.animtime = st->animtime; ent->curstate.frame = st->frame; ent->curstate.framerate = st->framerate; memcpy(ent->curstate.blending, st->blending, 2); memcpy(ent->curstate.controller, st->controller, 4); ent->latched = st->lv; }
/* ==================== StudioDrawModel ==================== */ int CStudioModelRenderer::StudioDrawModel( int flags ) { alight_t lighting; vec3_t dir; m_pCurrentEntity = IEngineStudio.GetCurrentEntity(); IEngineStudio.GetTimes( &m_nFrameCount, &m_clTime, &m_clOldTime ); IEngineStudio.GetViewInfo( m_vRenderOrigin, m_vUp, m_vRight, m_vNormal ); IEngineStudio.GetAliasScale( &m_fSoftwareXScale, &m_fSoftwareYScale ); if (m_pCurrentEntity->curstate.renderfx == kRenderFxDeadPlayer) { entity_state_t deadplayer; int result; int save_interp; if (m_pCurrentEntity->curstate.renderamt <= 0 || m_pCurrentEntity->curstate.renderamt > gEngfuncs.GetMaxClients() ) return 0; // get copy of player deadplayer = *(IEngineStudio.GetPlayerState( m_pCurrentEntity->curstate.renderamt - 1 )); //cl.frames[cl.parsecount & CL_UPDATE_MASK].playerstate[m_pCurrentEntity->curstate.renderamt-1]; // clear weapon, movement state deadplayer.number = m_pCurrentEntity->curstate.renderamt; deadplayer.weaponmodel = 0; deadplayer.gaitsequence = 0; deadplayer.movetype = MOVETYPE_NONE; VectorCopy( m_pCurrentEntity->curstate.angles, deadplayer.angles ); VectorCopy( m_pCurrentEntity->curstate.origin, deadplayer.origin ); save_interp = m_fDoInterp; m_fDoInterp = 0; // draw as though it were a player result = StudioDrawPlayer( flags, &deadplayer ); m_fDoInterp = save_interp; return result; } m_pRenderModel = m_pCurrentEntity->model; m_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata (m_pRenderModel); IEngineStudio.StudioSetHeader( m_pStudioHeader ); IEngineStudio.SetRenderModel( m_pRenderModel ); StudioSetUpTransform( 0 ); if (flags & STUDIO_RENDER) { // see if the bounding box lets us trivially reject, also sets if (!IEngineStudio.StudioCheckBBox ()) return 0; (*m_pModelsDrawn)++; (*m_pStudioModelCount)++; // render data cache cookie if (m_pStudioHeader->numbodyparts == 0) return 1; } if (m_pCurrentEntity->curstate.movetype == MOVETYPE_FOLLOW) { StudioMergeBones( m_pRenderModel ); } else { StudioSetupBones( ); } StudioSaveBones( ); if (flags & STUDIO_EVENTS) { StudioCalcAttachments( ); IEngineStudio.StudioClientEvents( ); // copy attachments into global entity array if ( m_pCurrentEntity->index > 0 ) { cl_entity_t *ent = gEngfuncs.GetEntityByIndex( m_pCurrentEntity->index ); memcpy( ent->attachment, m_pCurrentEntity->attachment, sizeof( vec3_t ) * 4 ); } } if (flags & STUDIO_RENDER) { lighting.plightvec = dir; IEngineStudio.StudioDynamicLight(m_pCurrentEntity, &lighting ); IEngineStudio.StudioEntityLight( &lighting ); // model and frame independant IEngineStudio.StudioSetupLighting (&lighting); // get remap colors m_nTopColor = m_pCurrentEntity->curstate.colormap & 0xFF; m_nBottomColor = (m_pCurrentEntity->curstate.colormap & 0xFF00) >> 8; IEngineStudio.StudioSetRemapColors( m_nTopColor, m_nBottomColor ); StudioRenderModel( ); }
int CGameStudioModelRenderer::_StudioDrawPlayer(int flags, entity_state_t *pplayer) { m_pCurrentEntity = IEngineStudio.GetCurrentEntity(); IEngineStudio.GetTimes(&m_nFrameCount, &m_clTime, &m_clOldTime); IEngineStudio.GetViewInfo(m_vRenderOrigin, m_vUp, m_vRight, m_vNormal); IEngineStudio.GetAliasScale(&m_fSoftwareXScale, &m_fSoftwareYScale); m_nPlayerIndex = pplayer->number - 1; if (m_nPlayerIndex < 0 || m_nPlayerIndex >= gEngfuncs.GetMaxClients()) return 0; m_pRenderModel = IEngineStudio.SetupPlayerModel(m_nPlayerIndex); if (m_pRenderModel == NULL) return 0; m_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata(m_pRenderModel); IEngineStudio.StudioSetHeader(m_pStudioHeader); IEngineStudio.SetRenderModel(m_pRenderModel); if (m_pCurrentEntity->curstate.sequence >= m_pStudioHeader->numseq) m_pCurrentEntity->curstate.sequence = 0; if (pplayer->sequence >= m_pStudioHeader->numseq) pplayer->sequence = 0; if (m_pCurrentEntity->curstate.gaitsequence >= m_pStudioHeader->numseq) m_pCurrentEntity->curstate.gaitsequence = 0; if (pplayer->gaitsequence >= m_pStudioHeader->numseq) pplayer->gaitsequence = 0; if (pplayer->gaitsequence) { vec3_t orig_angles; m_pPlayerInfo = IEngineStudio.PlayerInfo(m_nPlayerIndex); VectorCopy(m_pCurrentEntity->angles, orig_angles); StudioProcessGait(pplayer); m_pPlayerInfo->gaitsequence = pplayer->gaitsequence; m_pPlayerInfo = NULL; StudioSetUpTransform(0); VectorCopy(orig_angles, m_pCurrentEntity->angles); } else { m_pCurrentEntity->curstate.controller[0] = 127; m_pCurrentEntity->curstate.controller[1] = 127; m_pCurrentEntity->curstate.controller[2] = 127; m_pCurrentEntity->curstate.controller[3] = 127; m_pCurrentEntity->latched.prevcontroller[0] = m_pCurrentEntity->curstate.controller[0]; m_pCurrentEntity->latched.prevcontroller[1] = m_pCurrentEntity->curstate.controller[1]; m_pCurrentEntity->latched.prevcontroller[2] = m_pCurrentEntity->curstate.controller[2]; m_pCurrentEntity->latched.prevcontroller[3] = m_pCurrentEntity->curstate.controller[3]; m_pPlayerInfo = IEngineStudio.PlayerInfo(m_nPlayerIndex); CalculatePitchBlend(pplayer); CalculateYawBlend(pplayer); m_pPlayerInfo->gaitsequence = 0; StudioSetUpTransform(0); } if (flags & STUDIO_RENDER) { (*m_pModelsDrawn)++; (*m_pStudioModelCount)++; if (m_pStudioHeader->numbodyparts == 0) return 1; } m_pPlayerInfo = IEngineStudio.PlayerInfo(m_nPlayerIndex); StudioSetupBones(); StudioSaveBones(); m_pPlayerInfo->renderframe = m_nFrameCount; m_pPlayerInfo = NULL; if (flags & STUDIO_EVENTS && (!(flags & STUDIO_RENDER) || !pplayer->weaponmodel || !WeaponHasAttachments(pplayer))) { StudioCalcAttachments(); IEngineStudio.StudioClientEvents(); if (m_pCurrentEntity->index > 0) { cl_entity_t *ent = gEngfuncs.GetEntityByIndex(m_pCurrentEntity->index); memcpy(ent->attachment, m_pCurrentEntity->attachment, sizeof(vec3_t) * 4); } } if (flags & STUDIO_RENDER) { alight_t lighting; vec3_t dir; lighting.plightvec = dir; IEngineStudio.StudioDynamicLight(m_pCurrentEntity, &lighting); IEngineStudio.StudioEntityLight(&lighting); IEngineStudio.StudioSetupLighting(&lighting); m_pPlayerInfo = IEngineStudio.PlayerInfo(m_nPlayerIndex); m_nTopColor = m_pPlayerInfo->topcolor; if (m_nTopColor < 0) m_nTopColor = 0; if (m_nTopColor > 360) m_nTopColor = 360; m_nBottomColor = m_pPlayerInfo->bottomcolor; if (m_nBottomColor < 0) m_nBottomColor = 0; if (m_nBottomColor > 360) m_nBottomColor = 360; IEngineStudio.StudioSetRemapColors(m_nTopColor, m_nBottomColor); StudioRenderModel(dir); m_pPlayerInfo = NULL; if (pplayer->weaponmodel) { studiohdr_t *saveheader = m_pStudioHeader; cl_entity_t saveent = *m_pCurrentEntity; model_t *pweaponmodel = IEngineStudio.GetModelByIndex(pplayer->weaponmodel); m_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata(pweaponmodel); IEngineStudio.StudioSetHeader(m_pStudioHeader); StudioMergeBones(pweaponmodel); IEngineStudio.StudioSetupLighting(&lighting); StudioRenderModel(dir); StudioCalcAttachments(); if (m_pCurrentEntity->index > 0) memcpy(saveent.attachment, m_pCurrentEntity->attachment, sizeof(vec3_t) * m_pStudioHeader->numattachments); *m_pCurrentEntity = saveent; m_pStudioHeader = saveheader; IEngineStudio.StudioSetHeader(m_pStudioHeader); if (flags & STUDIO_EVENTS) IEngineStudio.StudioClientEvents(); } } if( cl_shadows->value != 0.0f ) { StudioDrawShadow(m_pCurrentEntity->origin, 20.0f); } return 1; }
/* ==================== _StudioDrawPlayer ==================== */ int CGameStudioModelRenderer::_StudioDrawPlayer(int flags, entity_state_t *pplayer) { alight_t lighting; vec3_t dir; m_pCurrentEntity = IEngineStudio.GetCurrentEntity(); IEngineStudio.GetTimes(&m_nFrameCount, &m_clTime, &m_clOldTime); IEngineStudio.GetViewInfo(m_vRenderOrigin, m_vUp, m_vRight, m_vNormal); IEngineStudio.GetAliasScale(&m_fSoftwareXScale, &m_fSoftwareYScale); m_nPlayerIndex = pplayer->number - 1; if(m_nPlayerIndex < 0 || m_nPlayerIndex >= gEngfuncs.GetMaxClients()) return 0; m_pRenderModel = IEngineStudio.SetupPlayerModel(m_nPlayerIndex); if(m_pRenderModel == NULL) return 0; m_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata(m_pRenderModel); IEngineStudio.StudioSetHeader(m_pStudioHeader); IEngineStudio.SetRenderModel(m_pRenderModel); if(pplayer->gaitsequence) { vec3_t orig_angles; m_pPlayerInfo = IEngineStudio.PlayerInfo(m_nPlayerIndex); VectorCopy(m_pCurrentEntity->angles, orig_angles); StudioProcessGait(pplayer); m_pPlayerInfo->gaitsequence = pplayer->gaitsequence; m_pPlayerInfo = NULL; StudioSetUpTransform(0); VectorCopy(orig_angles, m_pCurrentEntity->angles); } else { m_pCurrentEntity->curstate.controller[0] = 127; m_pCurrentEntity->curstate.controller[1] = 127; m_pCurrentEntity->curstate.controller[2] = 127; m_pCurrentEntity->curstate.controller[3] = 127; m_pCurrentEntity->latched.prevcontroller[0] = m_pCurrentEntity->curstate.controller[0]; m_pCurrentEntity->latched.prevcontroller[1] = m_pCurrentEntity->curstate.controller[1]; m_pCurrentEntity->latched.prevcontroller[2] = m_pCurrentEntity->curstate.controller[2]; m_pCurrentEntity->latched.prevcontroller[3] = m_pCurrentEntity->curstate.controller[3]; m_pPlayerInfo = IEngineStudio.PlayerInfo(m_nPlayerIndex); m_pPlayerInfo->gaitsequence = 0; StudioSetUpTransform(0); } if(flags & STUDIO_RENDER) { // see if the bounding box lets us trivially reject, also sets if(!IEngineStudio.StudioCheckBBox()) return 0; (*m_pModelsDrawn)++; (*m_pStudioModelCount)++; // render data cache cookie if(m_pStudioHeader->numbodyparts == 0) return 1; } m_pPlayerInfo = IEngineStudio.PlayerInfo(m_nPlayerIndex); StudioSetupBones(); StudioSaveBones(); m_pPlayerInfo->renderframe = m_nFrameCount; m_pPlayerInfo = NULL; if(flags & STUDIO_EVENTS) { StudioCalcAttachments(); IEngineStudio.StudioClientEvents(); // copy attachments into global entity array if(m_pCurrentEntity->index > 0) { cl_entity_t *ent = gEngfuncs.GetEntityByIndex(m_pCurrentEntity->index); memcpy(ent->attachment, m_pCurrentEntity->attachment, sizeof(vec3_t) * 4); } } if(flags & STUDIO_RENDER) { /* if (m_pCvarHiModels->value && m_pRenderModel != m_pCurrentEntity->model ) { // show highest resolution multiplayer model m_pCurrentEntity->curstate.body = 255; } if (!(m_pCvarDeveloper->value == 0 && gEngfuncs.GetMaxClients() == 1 ) && ( m_pRenderModel == m_pCurrentEntity->model ) ) { m_pCurrentEntity->curstate.body = 1; // force helmet } */ lighting.plightvec = dir; IEngineStudio.StudioDynamicLight(m_pCurrentEntity, &lighting); IEngineStudio.StudioEntityLight(&lighting); // model and frame independant IEngineStudio.StudioSetupLighting(&lighting); m_pPlayerInfo = IEngineStudio.PlayerInfo(m_nPlayerIndex); // get remap colors m_nTopColor = m_pPlayerInfo->topcolor; if(m_nTopColor < 0) m_nTopColor = 0; if(m_nTopColor > 360) m_nTopColor = 360; m_nBottomColor = m_pPlayerInfo->bottomcolor; if(m_nBottomColor < 0) m_nBottomColor = 0; if(m_nBottomColor > 360) m_nBottomColor = 360; IEngineStudio.StudioSetRemapColors(m_nTopColor, m_nBottomColor); StudioRenderModel(); m_pPlayerInfo = NULL; if(pplayer->weaponmodel) { cl_entity_t saveent = *m_pCurrentEntity; model_t *pweaponmodel = IEngineStudio.GetModelByIndex(pplayer->weaponmodel); m_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata(pweaponmodel); IEngineStudio.StudioSetHeader(m_pStudioHeader); StudioMergeBones(pweaponmodel); IEngineStudio.StudioSetupLighting(&lighting); StudioRenderModel(); StudioCalcAttachments(); *m_pCurrentEntity = saveent; } } return 1; }
int CStudioModelRenderer::StudioDrawModel(int flags) { m_pCurrentEntity = IEngineStudio.GetCurrentEntity(); IEngineStudio.GetTimes(&m_nFrameCount, &m_clTime, &m_clOldTime); IEngineStudio.GetViewInfo(m_vRenderOrigin, m_vUp, m_vRight, m_vNormal); IEngineStudio.GetAliasScale(&m_fSoftwareXScale, &m_fSoftwareYScale); if (m_pCurrentEntity->curstate.renderfx == kRenderFxDeadPlayer) { entity_state_t deadplayer; int result; int save_interp; if (m_pCurrentEntity->curstate.renderamt <= 0 || m_pCurrentEntity->curstate.renderamt > gEngfuncs.GetMaxClients()) return 0; deadplayer = *(IEngineStudio.GetPlayerState(m_pCurrentEntity->curstate.renderamt - 1)); deadplayer.number = m_pCurrentEntity->curstate.renderamt; deadplayer.weaponmodel = 0; deadplayer.gaitsequence = 0; deadplayer.movetype = MOVETYPE_NONE; VectorCopy(m_pCurrentEntity->curstate.angles, deadplayer.angles); VectorCopy(m_pCurrentEntity->curstate.origin, deadplayer.origin); save_interp = m_fDoInterp; m_fDoInterp = 0; result = StudioDrawPlayer(flags, &deadplayer); m_fDoInterp = save_interp; return result; } m_pRenderModel = m_pCurrentEntity->model; m_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata(m_pRenderModel); IEngineStudio.StudioSetHeader(m_pStudioHeader); IEngineStudio.SetRenderModel(m_pRenderModel); StudioSetUpTransform(0); if(m_pCurrentEntity == gEngfuncs.GetViewModel() && (gHUD.cl_righthand->value)) { (*m_protationmatrix)[0][1] *= -1; (*m_protationmatrix)[1][1] *= -1; (*m_protationmatrix)[2][1] *= -1; //IEngineStudio.StudioSetCullState(true); } if (flags & STUDIO_RENDER) { if (!IEngineStudio.StudioCheckBBox()) return 0; (*m_pModelsDrawn)++; (*m_pStudioModelCount)++; if (m_pStudioHeader->numbodyparts == 0) return 1; } if (m_pCurrentEntity->curstate.movetype == MOVETYPE_FOLLOW) StudioMergeBones(m_pRenderModel); else StudioSetupBones(); StudioSaveBones(); if (flags & STUDIO_EVENTS) { StudioCalcAttachments(); IEngineStudio.StudioClientEvents(); if (m_pCurrentEntity->index > 0) { cl_entity_t *ent = gEngfuncs.GetEntityByIndex(m_pCurrentEntity->index); memcpy(ent->attachment, m_pCurrentEntity->attachment, sizeof(vec3_t) * 4); } } if (flags & STUDIO_RENDER) { alight_t lighting; vec3_t dir; lighting.plightvec = dir; IEngineStudio.StudioDynamicLight(m_pCurrentEntity, &lighting); IEngineStudio.StudioEntityLight(&lighting); IEngineStudio.StudioSetupLighting(&lighting); m_nTopColor = m_pCurrentEntity->curstate.colormap & 0xFF; m_nBottomColor = (m_pCurrentEntity->curstate.colormap & 0xFF00) >> 8; IEngineStudio.StudioSetRemapColors(m_nTopColor, m_nBottomColor); StudioRenderModel(dir); }