mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-16 09:11:21 +00:00
allow modeldef flags to be overriden
This commit is contained in:
parent
d789676b26
commit
98e6330eaa
11 changed files with 156 additions and 46 deletions
|
@ -41,7 +41,9 @@ struct FSpriteModelFrame
|
|||
float xrotate, yrotate, zrotate;
|
||||
float rotationCenterX, rotationCenterY, rotationCenterZ;
|
||||
float rotationSpeed;
|
||||
private:
|
||||
unsigned int flags;
|
||||
public:
|
||||
const void* type; // used for hashing, must point to something usable as identifier for the model's owner.
|
||||
short sprite;
|
||||
short frame;
|
||||
|
@ -50,6 +52,9 @@ struct FSpriteModelFrame
|
|||
// added pithoffset, rolloffset.
|
||||
float pitchoffset, rolloffset; // I don't want to bother with type transformations, so I made this variables float.
|
||||
bool isVoxel;
|
||||
unsigned int getFlags(class DActorModelData * defs) const;
|
||||
friend void InitModels();
|
||||
friend void ParseModelDefLump(int Lump);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -10,15 +10,15 @@ public:
|
|||
|
||||
virtual ModelRendererType GetType() const = 0;
|
||||
|
||||
virtual void BeginDrawModel(FRenderStyle style, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored) = 0;
|
||||
virtual void EndDrawModel(FRenderStyle style, FSpriteModelFrame *smf) = 0;
|
||||
virtual void BeginDrawModel(FRenderStyle style, int smf_flags, const VSMatrix &objectToWorldMatrix, bool mirrored) = 0;
|
||||
virtual void EndDrawModel(FRenderStyle style, int smf_flags) = 0;
|
||||
|
||||
virtual IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) = 0;
|
||||
|
||||
virtual VSMatrix GetViewToWorldMatrix() = 0;
|
||||
|
||||
virtual void BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored, FSpriteModelFrame *smf) = 0;
|
||||
virtual void EndDrawHUDModel(FRenderStyle style, FSpriteModelFrame *smf) = 0;
|
||||
virtual void BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored, int smf_flags) = 0;
|
||||
virtual void EndDrawHUDModel(FRenderStyle style, int smf_flags) = 0;
|
||||
|
||||
virtual void SetInterpolation(double interpolation) = 0;
|
||||
virtual void SetMaterial(FGameTexture *skin, bool clampNoFilter, FTranslationID translation) = 0;
|
||||
|
|
|
@ -719,18 +719,21 @@ struct ModelOverride
|
|||
enum EModelDataFlags
|
||||
{
|
||||
MODELDATA_HADMODEL = 1 << 0,
|
||||
MODELDATA_OVERRIDE_FLAGS = 1 << 1,
|
||||
};
|
||||
|
||||
class DActorModelData : public DObject
|
||||
{
|
||||
DECLARE_CLASS(DActorModelData, DObject);
|
||||
public:
|
||||
FName modelDef;
|
||||
PClass * modelDef;
|
||||
TArray<ModelOverride> models;
|
||||
TArray<FTextureID> skinIDs;
|
||||
TArray<int> animationIDs;
|
||||
TArray<int> modelFrameGenerators;
|
||||
int flags;
|
||||
int overrideFlagsSet;
|
||||
int overrideFlagsClear;
|
||||
|
||||
AnimOverride curAnim;
|
||||
AnimOverride prevAnim; // used for interpolation when switching anims
|
||||
|
|
|
@ -5096,7 +5096,7 @@ static void EnsureModelData(AActor * mobj)
|
|||
auto ptr = Create<DActorModelData>();
|
||||
|
||||
ptr->flags = (mobj->hasmodel ? MODELDATA_HADMODEL : 0);
|
||||
ptr->modelDef = NAME_None;
|
||||
ptr->modelDef = nullptr;
|
||||
|
||||
mobj->modelData = ptr;
|
||||
mobj->hasmodel = true;
|
||||
|
@ -5111,7 +5111,8 @@ static void CleanupModelData(AActor * mobj)
|
|||
&& mobj->modelData->modelFrameGenerators.Size() == 0
|
||||
&& mobj->modelData->skinIDs.Size() == 0
|
||||
&& mobj->modelData->animationIDs.Size() == 0
|
||||
&& mobj->modelData->modelDef == NAME_None)
|
||||
&& mobj->modelData->modelDef == nullptr
|
||||
&&(mobj->modelData->flags & ~MODELDATA_HADMODEL) == 0 )
|
||||
{
|
||||
mobj->hasmodel = mobj->modelData->flags & MODELDATA_HADMODEL;
|
||||
mobj->modelData->Destroy();
|
||||
|
@ -5123,6 +5124,8 @@ enum ESetAnimationFlags
|
|||
{
|
||||
SAF_INSTANT = 1 << 0,
|
||||
SAF_LOOP = 1 << 1,
|
||||
SAF_USEACTORROLL = 1 << 2,
|
||||
SAF_USEACTORPITCH = 1 << 3,
|
||||
};
|
||||
|
||||
void SetAnimationInternal(AActor * self, FName animName, double framerate, int startFrame, int loopFrame, int interpolateTics, int flags, double ticFrac)
|
||||
|
@ -5265,6 +5268,32 @@ void SetAnimationFrameRateUINative(AActor * self, double framerate)
|
|||
SetAnimationFrameRateInternal(self, framerate, I_GetTimeFrac());
|
||||
}
|
||||
|
||||
void SetModelFlag(AActor * self, int flag)
|
||||
{
|
||||
EnsureModelData(self);
|
||||
self->modelData->flags |= MODELDATA_OVERRIDE_FLAGS;
|
||||
self->modelData->overrideFlagsSet |= flag;
|
||||
self->modelData->overrideFlagsClear &= ~flag;
|
||||
}
|
||||
|
||||
void ClearModelFlag(AActor * self, int flag)
|
||||
{
|
||||
EnsureModelData(self);
|
||||
self->modelData->flags |= MODELDATA_OVERRIDE_FLAGS;
|
||||
self->modelData->overrideFlagsClear |= flag;
|
||||
self->modelData->overrideFlagsSet &= ~flag;
|
||||
}
|
||||
|
||||
void ResetModelFlags(AActor * self)
|
||||
{
|
||||
if(self->modelData)
|
||||
{
|
||||
self->modelData->overrideFlagsClear = 0;
|
||||
self->modelData->overrideFlagsSet = 0;
|
||||
self->modelData->flags &= ~MODELDATA_OVERRIDE_FLAGS;
|
||||
}
|
||||
}
|
||||
|
||||
enum ChangeModelFlags
|
||||
{
|
||||
CMDL_WEAPONTOPLAYER = 1 << 0,
|
||||
|
@ -5291,14 +5320,16 @@ void ChangeModelNative(
|
|||
) {
|
||||
if(!self) ThrowAbortException(X_READ_NIL, "In function parameter self");
|
||||
|
||||
FName modeldef { ENamedName(i_modeldef) };
|
||||
FName n_modeldef { ENamedName(i_modeldef) };
|
||||
FName model { ENamedName(i_model) };
|
||||
FName skin { ENamedName(i_skin) };
|
||||
FName animation { ENamedName(i_animation) };
|
||||
|
||||
if (modeldef != NAME_None && PClass::FindClass(modeldef.GetChars()) == nullptr)
|
||||
PClass * modeldef = nullptr;
|
||||
|
||||
if (n_modeldef != NAME_None && (modeldef = PClass::FindActor(n_modeldef.GetChars())) == nullptr)
|
||||
{
|
||||
Printf("Attempt to pass invalid modeldef name %s in %s.", modeldef.GetChars(), self->GetCharacterName());
|
||||
Printf("Attempt to pass invalid modeldef name %s in %s.", n_modeldef.GetChars(), self->GetCharacterName());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5533,6 +5564,35 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, SetAnimationFrameRateUI, SetAnimationFrame
|
|||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, SetModelFlag, SetModelFlag)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE(AActor);
|
||||
PARAM_INT(flag);
|
||||
|
||||
SetModelFlag(self, flag);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, ClearModelFlag, ClearModelFlag)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE(AActor);
|
||||
PARAM_INT(flag);
|
||||
|
||||
ClearModelFlag(self, flag);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, ResetModelFlags, ResetModelFlags)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE(AActor);
|
||||
|
||||
ResetModelFlags(self);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This needs to account for the fact that internally renderstyles are stored as a series of operations,
|
||||
// but the script side only cares about symbolic constants.
|
||||
DEFINE_ACTION_FUNCTION(AActor, GetRenderStyle)
|
||||
|
|
|
@ -63,8 +63,10 @@ void RenderModel(FModelRenderer *renderer, float x, float y, float z, FSpriteMod
|
|||
{
|
||||
// Setup transformation.
|
||||
|
||||
int smf_flags = smf->getFlags(actor->modelData);
|
||||
|
||||
FTranslationID translation = NO_TRANSLATION;
|
||||
if (!(smf->flags & MDL_IGNORETRANSLATION))
|
||||
if (!(smf_flags & MDL_IGNORETRANSLATION))
|
||||
translation = actor->Translation;
|
||||
|
||||
// y scale for a sprite means height, i.e. z in the world!
|
||||
|
@ -82,7 +84,7 @@ void RenderModel(FModelRenderer *renderer, float x, float y, float z, FSpriteMod
|
|||
float angle = angles.Yaw.Degrees();
|
||||
|
||||
// [BB] Workaround for the missing pitch information.
|
||||
if ((smf->flags & MDL_PITCHFROMMOMENTUM))
|
||||
if ((smf_flags & MDL_PITCHFROMMOMENTUM))
|
||||
{
|
||||
const double x = actor->Vel.X;
|
||||
const double y = actor->Vel.Y;
|
||||
|
@ -102,7 +104,7 @@ void RenderModel(FModelRenderer *renderer, float x, float y, float z, FSpriteMod
|
|||
}
|
||||
}
|
||||
|
||||
if (smf->flags & MDL_ROTATING)
|
||||
if (smf_flags & MDL_ROTATING)
|
||||
{
|
||||
if (smf->rotationSpeed > 0.0000000001 || smf->rotationSpeed < -0.0000000001)
|
||||
{
|
||||
|
@ -118,13 +120,13 @@ void RenderModel(FModelRenderer *renderer, float x, float y, float z, FSpriteMod
|
|||
|
||||
// Added MDL_USEACTORPITCH and MDL_USEACTORROLL flags processing.
|
||||
// If both flags MDL_USEACTORPITCH and MDL_PITCHFROMMOMENTUM are set, the pitch sums up the actor pitch and the velocity vector pitch.
|
||||
if (smf->flags & MDL_USEACTORPITCH)
|
||||
if (smf_flags & MDL_USEACTORPITCH)
|
||||
{
|
||||
double d = angles.Pitch.Degrees();
|
||||
if (smf->flags & MDL_BADROTATION) pitch += d;
|
||||
if (smf_flags & MDL_BADROTATION) pitch += d;
|
||||
else pitch -= d;
|
||||
}
|
||||
if (smf->flags & MDL_USEACTORROLL) roll += angles.Roll.Degrees();
|
||||
if (smf_flags & MDL_USEACTORROLL) roll += angles.Roll.Degrees();
|
||||
|
||||
VSMatrix objectToWorldMatrix;
|
||||
objectToWorldMatrix.loadIdentity();
|
||||
|
@ -140,7 +142,7 @@ void RenderModel(FModelRenderer *renderer, float x, float y, float z, FSpriteMod
|
|||
|
||||
// [MK] distortions might happen depending on when the pixel stretch is compensated for
|
||||
// so we make the "undistorted" behavior opt-in
|
||||
if (smf->flags & MDL_CORRECTPIXELSTRETCH)
|
||||
if (smf_flags & MDL_CORRECTPIXELSTRETCH)
|
||||
{
|
||||
stretch = (smf->modelIDs[0] != -1 ? Models[smf->modelIDs[0]]->getAspectFactor(actor->Level->info->pixelstretch) : 1.f) / actor->Level->info->pixelstretch;
|
||||
objectToWorldMatrix.scale(1, stretch, 1);
|
||||
|
@ -148,14 +150,14 @@ void RenderModel(FModelRenderer *renderer, float x, float y, float z, FSpriteMod
|
|||
|
||||
// Applying model transformations:
|
||||
// 1) Applying actor angle, pitch and roll to the model
|
||||
if (smf->flags & MDL_USEROTATIONCENTER)
|
||||
if (smf_flags & MDL_USEROTATIONCENTER)
|
||||
{
|
||||
objectToWorldMatrix.translate(smf->rotationCenterX, smf->rotationCenterZ/stretch, smf->rotationCenterY);
|
||||
}
|
||||
objectToWorldMatrix.rotate(-angle, 0, 1, 0);
|
||||
objectToWorldMatrix.rotate(pitch, 0, 0, 1);
|
||||
objectToWorldMatrix.rotate(-roll, 1, 0, 0);
|
||||
if (smf->flags & MDL_USEROTATIONCENTER)
|
||||
if (smf_flags & MDL_USEROTATIONCENTER)
|
||||
{
|
||||
objectToWorldMatrix.translate(-smf->rotationCenterX, -smf->rotationCenterZ/stretch, -smf->rotationCenterY);
|
||||
}
|
||||
|
@ -163,7 +165,7 @@ void RenderModel(FModelRenderer *renderer, float x, float y, float z, FSpriteMod
|
|||
// 2) Applying Doomsday like rotation of the weapon pickup models
|
||||
// The rotation angle is based on the elapsed time.
|
||||
|
||||
if (smf->flags & MDL_ROTATING)
|
||||
if (smf_flags & MDL_ROTATING)
|
||||
{
|
||||
objectToWorldMatrix.translate(smf->rotationCenterX, smf->rotationCenterY/stretch, smf->rotationCenterZ);
|
||||
objectToWorldMatrix.rotate(rotateOffset, smf->xrotate, smf->yrotate, smf->zrotate);
|
||||
|
@ -181,7 +183,7 @@ void RenderModel(FModelRenderer *renderer, float x, float y, float z, FSpriteMod
|
|||
objectToWorldMatrix.rotate(smf->pitchoffset, 0, 0, 1);
|
||||
objectToWorldMatrix.rotate(-smf->rolloffset, 1, 0, 0);
|
||||
|
||||
if (!(smf->flags & MDL_CORRECTPIXELSTRETCH))
|
||||
if (!(smf_flags & MDL_CORRECTPIXELSTRETCH))
|
||||
{
|
||||
stretch = (smf->modelIDs[0] != -1 ? Models[smf->modelIDs[0]]->getAspectFactor(actor->Level->info->pixelstretch) : 1.f) / actor->Level->info->pixelstretch;
|
||||
objectToWorldMatrix.scale(1, stretch, 1);
|
||||
|
@ -189,15 +191,17 @@ void RenderModel(FModelRenderer *renderer, float x, float y, float z, FSpriteMod
|
|||
|
||||
float orientation = scaleFactorX * scaleFactorY * scaleFactorZ;
|
||||
|
||||
renderer->BeginDrawModel(actor->RenderStyle, smf, objectToWorldMatrix, orientation < 0);
|
||||
renderer->BeginDrawModel(actor->RenderStyle, smf_flags, objectToWorldMatrix, orientation < 0);
|
||||
RenderFrameModels(renderer, actor->Level, smf, actor->state, actor->tics, translation, actor);
|
||||
renderer->EndDrawModel(actor->RenderStyle, smf);
|
||||
renderer->EndDrawModel(actor->RenderStyle, smf_flags);
|
||||
}
|
||||
|
||||
void RenderHUDModel(FModelRenderer *renderer, DPSprite *psp, FVector3 translation, FVector3 rotation, FVector3 rotation_pivot, FSpriteModelFrame *smf)
|
||||
{
|
||||
AActor * playermo = players[consoleplayer].camera;
|
||||
|
||||
int smf_flags = smf->getFlags(psp->Caller->modelData);
|
||||
|
||||
// [BB] No model found for this sprite, so we can't render anything.
|
||||
if (smf == nullptr)
|
||||
return;
|
||||
|
@ -208,7 +212,7 @@ void RenderHUDModel(FModelRenderer *renderer, DPSprite *psp, FVector3 translatio
|
|||
|
||||
// [Nash] Optional scale weapon FOV
|
||||
float fovscale = 1.0f;
|
||||
if (smf->flags & MDL_SCALEWEAPONFOV)
|
||||
if (smf_flags & MDL_SCALEWEAPONFOV)
|
||||
{
|
||||
fovscale = tan(players[consoleplayer].DesiredFOV * (0.5f * M_PI / 180.f));
|
||||
fovscale = 1.f + (fovscale - 1.f) * cl_scaleweaponfov;
|
||||
|
@ -245,12 +249,12 @@ void RenderHUDModel(FModelRenderer *renderer, DPSprite *psp, FVector3 translatio
|
|||
|
||||
float orientation = smf->xscale * smf->yscale * smf->zscale;
|
||||
|
||||
renderer->BeginDrawHUDModel(playermo->RenderStyle, objectToWorldMatrix, orientation < 0, smf);
|
||||
renderer->BeginDrawHUDModel(playermo->RenderStyle, objectToWorldMatrix, orientation < 0, smf_flags);
|
||||
auto trans = psp->GetTranslation();
|
||||
if ((psp->Flags & PSPF_PLAYERTRANSLATED)) trans = psp->Owner->mo->Translation;
|
||||
|
||||
RenderFrameModels(renderer, playermo->Level, smf, psp->GetState(), psp->GetTics(), trans, psp->Caller);
|
||||
renderer->EndDrawHUDModel(playermo->RenderStyle, smf);
|
||||
renderer->EndDrawHUDModel(playermo->RenderStyle, smf_flags);
|
||||
}
|
||||
|
||||
double getCurrentFrame(const AnimOverride &anim, double tic)
|
||||
|
@ -295,6 +299,9 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
|
|||
{
|
||||
// [BB] Frame interpolation: Find the FSpriteModelFrame smfNext which follows after smf in the animation
|
||||
// and the scalar value inter ( element of [0,1) ), both necessary to determine the interpolated frame.
|
||||
|
||||
int smf_flags = smf->getFlags(actor->modelData);
|
||||
|
||||
const FSpriteModelFrame * smfNext = nullptr;
|
||||
double inter = 0.;
|
||||
double inter_main = -1.f;
|
||||
|
@ -334,7 +341,7 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (gl_interpolate_model_frames && !(smf->flags & MDL_NOINTERPOLATION))
|
||||
else if (gl_interpolate_model_frames && !(smf_flags & MDL_NOINTERPOLATION))
|
||||
{
|
||||
FState *nextState = curState->GetNextState();
|
||||
if (curState != nextState && nextState)
|
||||
|
@ -356,7 +363,7 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
|
|||
{
|
||||
// [BB] Workaround for actors that use the same frame twice in a row.
|
||||
// Most of the standard Doom monsters do this in their see state.
|
||||
if ((smf->flags & MDL_INTERPOLATEDOUBLEDFRAMES))
|
||||
if ((smf_flags & MDL_INTERPOLATEDOUBLEDFRAMES))
|
||||
{
|
||||
const FState *prevState = curState - 1;
|
||||
if ((curState->sprite == prevState->sprite) && (curState->Frame == prevState->Frame))
|
||||
|
@ -522,7 +529,7 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
|
|||
}
|
||||
|
||||
// [RL0] while per-model animations aren't done, DECOUPLEDANIMATIONS does the same as MODELSAREATTACHMENTS
|
||||
if ((!(smf->flags & MDL_MODELSAREATTACHMENTS) && !is_decoupled) || !evaluatedSingle)
|
||||
if ((!(smf_flags & MDL_MODELSAREATTACHMENTS) && !is_decoupled) || !evaluatedSingle)
|
||||
{
|
||||
if (animationid >= 0)
|
||||
{
|
||||
|
@ -576,7 +583,7 @@ static TArray<int> SpriteModelHash;
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
static void ParseModelDefLump(int Lump);
|
||||
void ParseModelDefLump(int Lump);
|
||||
|
||||
void InitModels()
|
||||
{
|
||||
|
@ -658,7 +665,7 @@ void InitModels()
|
|||
}
|
||||
}
|
||||
|
||||
static void ParseModelDefLump(int Lump)
|
||||
void ParseModelDefLump(int Lump)
|
||||
{
|
||||
FScanner sc(Lump);
|
||||
while (sc.GetString())
|
||||
|
@ -1117,11 +1124,11 @@ FSpriteModelFrame * FindModelFrame(const AActor * thing, int sprite, int frame,
|
|||
|
||||
if(thing->flags9 & MF9_DECOUPLEDANIMATIONS)
|
||||
{
|
||||
return &BaseSpriteModelFrames[thing->GetClass()];
|
||||
return &BaseSpriteModelFrames[(thing->modelData != nullptr && thing->modelData->modelDef != nullptr) ? thing->modelData->modelDef : thing->GetClass()];
|
||||
}
|
||||
else
|
||||
{
|
||||
return FindModelFrameRaw((thing->modelData != nullptr && thing->modelData->modelDef != NAME_None) ? PClass::FindActor(thing->modelData->modelDef) : thing->GetClass(), sprite, frame, dropped);
|
||||
return FindModelFrameRaw((thing->modelData != nullptr && thing->modelData->modelDef != nullptr) ? thing->modelData->modelDef : thing->GetClass(), sprite, frame, dropped);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1143,3 +1150,9 @@ bool IsHUDModelForPlayerAvailable (player_t * player)
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
unsigned int FSpriteModelFrame::getFlags(class DActorModelData * defs) const
|
||||
{
|
||||
return (defs && defs->flags & MODELDATA_OVERRIDE_FLAGS)? (flags | defs->overrideFlagsSet) & ~(defs->overrideFlagsClear) : flags;
|
||||
}
|
|
@ -53,7 +53,7 @@ VSMatrix FHWModelRenderer::GetViewToWorldMatrix()
|
|||
return objectToWorldMatrix;
|
||||
}
|
||||
|
||||
void FHWModelRenderer::BeginDrawModel(FRenderStyle style, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored)
|
||||
void FHWModelRenderer::BeginDrawModel(FRenderStyle style, int smf_flags, const VSMatrix &objectToWorldMatrix, bool mirrored)
|
||||
{
|
||||
state.SetDepthFunc(DF_LEqual);
|
||||
state.EnableTexture(true);
|
||||
|
@ -61,7 +61,7 @@ void FHWModelRenderer::BeginDrawModel(FRenderStyle style, FSpriteModelFrame *smf
|
|||
// This solves a few of the problems caused by the lack of depth sorting.
|
||||
// [Nash] Don't do back face culling if explicitly specified in MODELDEF
|
||||
// TO-DO: Implement proper depth sorting.
|
||||
if ((smf->flags & MDL_FORCECULLBACKFACES) || (!(style == DefaultRenderStyle()) && !(smf->flags & MDL_DONTCULLBACKFACES)))
|
||||
if ((smf_flags & MDL_FORCECULLBACKFACES) || (!(style == DefaultRenderStyle()) && !(smf_flags & MDL_DONTCULLBACKFACES)))
|
||||
{
|
||||
state.SetCulling((mirrored ^ portalState.isMirrored()) ? Cull_CCW : Cull_CW);
|
||||
}
|
||||
|
@ -70,16 +70,16 @@ void FHWModelRenderer::BeginDrawModel(FRenderStyle style, FSpriteModelFrame *smf
|
|||
state.EnableModelMatrix(true);
|
||||
}
|
||||
|
||||
void FHWModelRenderer::EndDrawModel(FRenderStyle style, FSpriteModelFrame *smf)
|
||||
void FHWModelRenderer::EndDrawModel(FRenderStyle style, int smf_flags)
|
||||
{
|
||||
state.SetBoneIndexBase(-1);
|
||||
state.EnableModelMatrix(false);
|
||||
state.SetDepthFunc(DF_Less);
|
||||
if ((smf->flags & MDL_FORCECULLBACKFACES) || (!(style == DefaultRenderStyle()) && !(smf->flags & MDL_DONTCULLBACKFACES)))
|
||||
if ((smf_flags & MDL_FORCECULLBACKFACES) || (!(style == DefaultRenderStyle()) && !(smf_flags & MDL_DONTCULLBACKFACES)))
|
||||
state.SetCulling(Cull_None);
|
||||
}
|
||||
|
||||
void FHWModelRenderer::BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored, FSpriteModelFrame *smf)
|
||||
void FHWModelRenderer::BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored, int smf_flags)
|
||||
{
|
||||
state.SetDepthFunc(DF_LEqual);
|
||||
state.SetDepthClamp(true);
|
||||
|
@ -87,7 +87,7 @@ void FHWModelRenderer::BeginDrawHUDModel(FRenderStyle style, const VSMatrix &obj
|
|||
// [BB] In case the model should be rendered translucent, do back face culling.
|
||||
// This solves a few of the problems caused by the lack of depth sorting.
|
||||
// TO-DO: Implement proper depth sorting.
|
||||
if (!(style == DefaultRenderStyle()) || (smf->flags & MDL_FORCECULLBACKFACES))
|
||||
if (!(style == DefaultRenderStyle()) || (smf_flags & MDL_FORCECULLBACKFACES))
|
||||
{
|
||||
state.SetCulling((mirrored ^ portalState.isMirrored()) ? Cull_CW : Cull_CCW);
|
||||
}
|
||||
|
@ -96,13 +96,13 @@ void FHWModelRenderer::BeginDrawHUDModel(FRenderStyle style, const VSMatrix &obj
|
|||
state.EnableModelMatrix(true);
|
||||
}
|
||||
|
||||
void FHWModelRenderer::EndDrawHUDModel(FRenderStyle style, FSpriteModelFrame *smf)
|
||||
void FHWModelRenderer::EndDrawHUDModel(FRenderStyle style, int smf_flags)
|
||||
{
|
||||
state.SetBoneIndexBase(-1);
|
||||
state.EnableModelMatrix(false);
|
||||
|
||||
state.SetDepthFunc(DF_Less);
|
||||
if (!(style == DefaultRenderStyle()) || (smf->flags & MDL_FORCECULLBACKFACES))
|
||||
if (!(style == DefaultRenderStyle()) || (smf_flags & MDL_FORCECULLBACKFACES))
|
||||
state.SetCulling(Cull_None);
|
||||
}
|
||||
|
||||
|
|
|
@ -46,12 +46,12 @@ public:
|
|||
FHWModelRenderer(HWDrawInfo *d, FRenderState &st, int mli) : modellightindex(mli), di(d), state(st)
|
||||
{}
|
||||
ModelRendererType GetType() const override { return GLModelRendererType; }
|
||||
void BeginDrawModel(FRenderStyle style, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored) override;
|
||||
void EndDrawModel(FRenderStyle style, FSpriteModelFrame *smf) override;
|
||||
void BeginDrawModel(FRenderStyle style, int smf_flags, const VSMatrix &objectToWorldMatrix, bool mirrored) override;
|
||||
void EndDrawModel(FRenderStyle style, int smf_flags) override;
|
||||
IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) override;
|
||||
VSMatrix GetViewToWorldMatrix() override;
|
||||
void BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored, FSpriteModelFrame *smf) override;
|
||||
void EndDrawHUDModel(FRenderStyle style, FSpriteModelFrame *smf) override;
|
||||
void BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored, int smf_flags) override;
|
||||
void EndDrawHUDModel(FRenderStyle style, int smf_flags) override;
|
||||
void SetInterpolation(double interpolation) override;
|
||||
void SetMaterial(FGameTexture *skin, bool clampNoFilter, FTranslationID translation) override;
|
||||
void DrawArrays(int start, int count) override;
|
||||
|
|
|
@ -365,6 +365,7 @@ public:
|
|||
PalEntry ThingColor; // thing's own color
|
||||
FColormap Colormap;
|
||||
FSpriteModelFrame * modelframe;
|
||||
int modelframeflags;
|
||||
FRenderStyle RenderStyle;
|
||||
int OverrideShader;
|
||||
|
||||
|
|
|
@ -507,7 +507,7 @@ bool HWSprite::CalculateVertices(HWDrawInfo *di, FVector3 *v, DVector3 *vp)
|
|||
inline void HWSprite::PutSprite(HWDrawInfo *di, bool translucent)
|
||||
{
|
||||
// That's a lot of checks...
|
||||
if (modelframe && !modelframe->isVoxel && !(modelframe->flags & MDL_NOPERPIXELLIGHTING) && RenderStyle.BlendOp != STYLEOP_Shadow && gl_light_sprites && di->Level->HasDynamicLights && !di->isFullbrightScene() && !fullbright)
|
||||
if (modelframe && !modelframe->isVoxel && !(modelframeflags & MDL_NOPERPIXELLIGHTING) && RenderStyle.BlendOp != STYLEOP_Shadow && gl_light_sprites && di->Level->HasDynamicLights && !di->isFullbrightScene() && !fullbright)
|
||||
{
|
||||
hw_GetDynModelLight(actor, lightdata);
|
||||
dynlightindex = screen->mLights->UploadLights(lightdata);
|
||||
|
@ -797,6 +797,7 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
|
|||
}
|
||||
|
||||
modelframe = isPicnumOverride ? nullptr : FindModelFrame(thing, spritenum, thing->frame, !!(thing->flags & MF_DROPPED));
|
||||
modelframeflags = modelframe ? modelframe->getFlags(thing->modelData) : 0;
|
||||
|
||||
// Too close to the camera. This doesn't look good if it is a sprite.
|
||||
if (fabs(thingpos.X - vp.Pos.X) < 2 && fabs(thingpos.Y - vp.Pos.Y) < 2
|
||||
|
|
|
@ -1300,6 +1300,10 @@ class Actor : Thinker native
|
|||
native version("4.12") void SetAnimationFrameRate(double framerate);
|
||||
native version("4.12") ui void SetAnimationFrameRateUI(double framerate);
|
||||
|
||||
native version("4.12") void SetModelFlag(int flag);
|
||||
native version("4.12") void ClearModelFlag(int flag);
|
||||
native version("4.12") void ResetModelFlags();
|
||||
|
||||
int ACS_NamedExecute(name script, int mapnum=0, int arg1=0, int arg2=0, int arg3=0)
|
||||
{
|
||||
return ACS_Execute(-int(script), mapnum, arg1, arg2, arg3);
|
||||
|
|
|
@ -1470,3 +1470,26 @@ const WATER_SINK_FACTOR = 0.125;
|
|||
const WATER_SINK_SMALL_FACTOR = 0.25;
|
||||
const WATER_SINK_SPEED = 0.5;
|
||||
const WATER_JUMP_SPEED = 3.5;
|
||||
|
||||
|
||||
// for SetModelFlag/ClearModelFlag
|
||||
enum EModelFlags
|
||||
{
|
||||
// [BB] Color translations for the model skin are ignored. This is
|
||||
// useful if the skin texture is not using the game palette.
|
||||
MDL_IGNORETRANSLATION = 1<<0,
|
||||
MDL_PITCHFROMMOMENTUM = 1<<1,
|
||||
MDL_ROTATING = 1<<2,
|
||||
MDL_INTERPOLATEDOUBLEDFRAMES = 1<<3,
|
||||
MDL_NOINTERPOLATION = 1<<4,
|
||||
MDL_USEACTORPITCH = 1<<5,
|
||||
MDL_USEACTORROLL = 1<<6,
|
||||
MDL_BADROTATION = 1<<7,
|
||||
MDL_DONTCULLBACKFACES = 1<<8,
|
||||
MDL_USEROTATIONCENTER = 1<<9,
|
||||
MDL_NOPERPIXELLIGHTING = 1<<10, // forces a model to not use per-pixel lighting. useful for voxel-converted-to-model objects.
|
||||
MDL_SCALEWEAPONFOV = 1<<11, // scale weapon view model with higher user FOVs
|
||||
MDL_MODELSAREATTACHMENTS = 1<<12, // any model index after 0 is treated as an attachment, and therefore will use the bone results of index 0
|
||||
MDL_CORRECTPIXELSTRETCH = 1<<13, // ensure model does not distort with pixel stretch when pitch/roll is applied
|
||||
MDL_FORCECULLBACKFACES = 1<<14,
|
||||
};
|
Loading…
Reference in a new issue