/* * CG_RegisterModel */ struct model_s *CG_RegisterModel( const char *name ) { struct model_s *model; model = trap_R_RegisterModel( name ); // precache bones if( trap_R_SkeletalGetNumBones( model, NULL ) ) CG_SkeletonForModel( model ); return model; }
/* * CG_PModel_SpawnTeleportEffect */ void CG_PModel_SpawnTeleportEffect( centity_t *cent ) { int j; cgs_skeleton_t *skel; lentity_t *le; vec3_t teleportOrigin; vec3_t rgb; skel = CG_SkeletonForModel( cent->ent.model ); if( !skel || !cent->ent.boneposes ) return; for( j = LOCALEFFECT_EV_PLAYER_TELEPORT_IN; j <= LOCALEFFECT_EV_PLAYER_TELEPORT_OUT; j++ ) { if( cent->localEffects[j] ) { cent->localEffects[j] = 0; VectorSet( rgb, 0.5, 0.5, 0.5 ); if( j == LOCALEFFECT_EV_PLAYER_TELEPORT_OUT ) { VectorCopy( cent->teleportedFrom, teleportOrigin ); } else { VectorCopy( cent->teleportedTo, teleportOrigin ); if( ISVIEWERENTITY( cent->current.number ) ) { VectorSet( rgb, 0.1, 0.1, 0.1 ); } } // spawn a dummy model le = CG_AllocModel( LE_RGB_FADE, teleportOrigin, vec3_origin, 10, rgb[0], rgb[1], rgb[2], 1, 0, 0, 0, 0, cent->ent.model, CG_MediaShader( cgs.media.shaderTeleportShellGfx ) ); if( cent->skel ) { // use static bone pose, no animation le->skel = cent->skel; le->static_boneposes = ( bonepose_t * )CG_Malloc( sizeof( bonepose_t ) * le->skel->numBones ); memcpy( le->static_boneposes, cent->ent.boneposes, sizeof( bonepose_t ) * le->skel->numBones ); le->ent.boneposes = le->static_boneposes; le->ent.oldboneposes = le->ent.boneposes; } le->ent.frame = cent->ent.frame; le->ent.oldframe = cent->ent.oldframe; le->ent.backlerp = 1.0f; Matrix3_Copy( cent->ent.axis, le->ent.axis ); } } }
/* * CG_PModel_SpawnTeleportEffect */ void CG_PModel_SpawnTeleportEffect( centity_t *cent ) { // the thing is, we must have a built skeleton, so we // can run all bones and spawn a polygon at their origin int i, j; cgs_skeleton_t *skel; orientation_t orient, ref; float radius = 5; lentity_t *le; vec3_t vec, teleportOrigin; skel = CG_SkeletonForModel( cent->ent.model ); if( !skel || !cent->ent.boneposes ) return; for( j = LOCALEFFECT_EV_PLAYER_TELEPORT_IN; j <= LOCALEFFECT_EV_PLAYER_TELEPORT_OUT; j++ ) { if( cent->localEffects[j] ) { cent->localEffects[j] = 0; if( j == LOCALEFFECT_EV_PLAYER_TELEPORT_OUT ) VectorCopy( cent->teleportedFrom, teleportOrigin ); else VectorCopy( cent->ent.origin, teleportOrigin ); for( i = 0; i < skel->numBones; i++ ) { DualQuat_ToMatrixAndVector( cent->ent.boneposes[i].dualquat, orient.axis, orient.origin ); VectorCopy( vec3_origin, ref.origin ); Matrix_Copy( axis_identity, ref.axis ); CG_MoveToTag( ref.origin, ref.axis, teleportOrigin, cent->ent.axis, orient.origin, orient.axis ); VectorSet( vec, 0.1f, 0.1f, 0.1f ); // spawn a sprite at each bone le = CG_AllocSprite( LE_SCALE_ALPHA_FADE, ref.origin, radius, 15 + crandom()*5, 1, 1, 1, 0.5f, 0, 0, 0, 0, CG_MediaShader( cgs.media.shaderTeleporterSmokePuff ) ); VectorSet( le->velocity, -vec[0] * 5 + crandom()*5, -vec[1] * 5 + crandom()*5, -vec[2] * 5 + crandom()*5 + 3 ); le->ent.rotation = rand() % 360; // CG_ParticleEffect( ref.origin, ref.axis[2], 0.9f, 0.9f, 0.9f, 2 ); } } } }
/* * CG_SetBoneposesForTemporaryEntity * Sets up skeleton with inline boneposes based on frame/oldframe values * These boneposes will be RESET after drawing EACH FRAME. */ cgs_skeleton_t *CG_SetBoneposesForTemporaryEntity( entity_t *ent ) { cgs_skeleton_t *skel; skel = CG_SkeletonForModel( ent->model ); if( skel ) { // get space in cache, interpolate, transform, link ent->boneposes = CG_RegisterTemporaryExternalBoneposes( skel ); CG_LerpSkeletonPoses( skel, ent->frame, ent->oldframe, ent->boneposes, 1.0 - ent->backlerp ); CG_TransformBoneposes( skel, ent->boneposes, ent->boneposes ); ent->oldboneposes = ent->boneposes; } return skel; }