Bone Getters Part 2/3, plus fixed warnings for MSVC
* add getters for frame poses * fix missing joint in GetJointPose * clean up models_iqm.cpp * clean up usage of I_GetTimeFrac, split out matrix calculation into its own function * clean up SetModelBoneRotationInternal * clean up a few float <-> double and unsigned <-> signed warnings * fix more warnings * further clean up warnings * split mode ObjectToWorldMatrix stuff * initial work on bone getters, matrix hell (the matrix/vec3 multiplications are probably wrong af, just gotta add more stuff 'till i can test it) * clean up matrix math * GetBone/TransformByBone * fix GetBoneFramePose * fix ObjectToWorldMatrix * fix missing array resize * raw matrix getters (for use with gutamatics/etc) * reverse matrix mult order * replace GetBoneLength/GetBoneDir with GetBoneBaseTRS * fix GetBonePosition, remove GetBoneWorldMatrix as it's useless * GetBonePosition * deduplicate code * rename GetBonePosition to GetBoneBasePosition to avoid confusion * GetBoneBaseRotation * GetBonePosition helper function * forgot include_offsets
This commit is contained in:
parent
9eaf472071
commit
9e2b1f9c4c
37 changed files with 1109 additions and 261 deletions
|
|
@ -289,7 +289,7 @@ bool Wiper_Crossfade::Run(int ticks)
|
|||
|
||||
bool Wiper_Crossfade::RunInterpolated(double ticks)
|
||||
{
|
||||
Clock += ticks;
|
||||
Clock += float(ticks);
|
||||
DrawTexture(twod, startScreen, 0, 0, DTA_FlipY, screen->RenderTextureIsFlipped(), DTA_Masked, false, TAG_DONE);
|
||||
DrawTexture(twod, endScreen, 0, 0, DTA_FlipY, screen->RenderTextureIsFlipped(), DTA_Masked, false, DTA_Alpha, clamp(Clock / 32.f, 0.f, 1.f), TAG_DONE);
|
||||
return Clock >= 32.;
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ FClientStack NetworkClients = {};
|
|||
|
||||
uint32_t GameID = DEFAULT_GAME_ID;
|
||||
uint8_t TicDup = 1u;
|
||||
uint8_t MaxClients = 1u;
|
||||
int MaxClients = 1;
|
||||
int RemoteClient = -1;
|
||||
size_t NetBufferLength = 0u;
|
||||
uint8_t NetBuffer[MAX_MSGLEN] = {};
|
||||
|
|
@ -187,10 +187,10 @@ CUSTOM_CVAR(String, net_password, "", CVAR_IGNORE)
|
|||
|
||||
void Net_SetupUserInfo();
|
||||
const char* Net_GetClientName(int client, unsigned int charLimit);
|
||||
int Net_SetUserInfo(int client, uint8_t*& stream);
|
||||
int Net_ReadUserInfo(int client, uint8_t*& stream);
|
||||
int Net_ReadGameInfo(uint8_t*& stream);
|
||||
int Net_SetGameInfo(uint8_t*& stream);
|
||||
size_t Net_SetUserInfo(int client, uint8_t*& stream);
|
||||
size_t Net_ReadUserInfo(int client, uint8_t*& stream);
|
||||
size_t Net_ReadGameInfo(uint8_t*& stream);
|
||||
size_t Net_SetGameInfo(uint8_t*& stream);
|
||||
|
||||
static SOCKET CreateUDPSocket()
|
||||
{
|
||||
|
|
@ -320,7 +320,7 @@ static int PrivateNetOf(const in_addr& in)
|
|||
// private network, since that means we (probably) are too.
|
||||
static bool ClientsOnSameNetwork()
|
||||
{
|
||||
size_t start = 1u;
|
||||
int start = 1;
|
||||
for (; start < MaxClients; ++start)
|
||||
{
|
||||
if (Connected[start].Status != CSTAT_NONE)
|
||||
|
|
@ -334,7 +334,7 @@ static bool ClientsOnSameNetwork()
|
|||
if (!firstClient)
|
||||
return false;
|
||||
|
||||
for (size_t i = 1u; i < MaxClients; ++i)
|
||||
for (int i = 1; i < MaxClients; ++i)
|
||||
{
|
||||
if (i == start)
|
||||
continue;
|
||||
|
|
@ -395,7 +395,7 @@ static bool I_NetLoop(bool (*loopCallback)(void*), void* data)
|
|||
}
|
||||
|
||||
// A new client has just entered the game, so add them to the player list.
|
||||
static void I_NetClientConnected(size_t client, unsigned int charLimit = 0u)
|
||||
static void I_NetClientConnected(int client, unsigned int charLimit = 0u)
|
||||
{
|
||||
const char* name = Net_GetClientName(client, charLimit);
|
||||
unsigned int flags = CFL_NONE;
|
||||
|
|
@ -408,17 +408,17 @@ static void I_NetClientConnected(size_t client, unsigned int charLimit = 0u)
|
|||
}
|
||||
|
||||
// A client changed ready state.
|
||||
static void I_NetClientUpdated(size_t client)
|
||||
static void I_NetClientUpdated(int client)
|
||||
{
|
||||
StartWindow->NetUpdate(client, Connected[client].Status);
|
||||
}
|
||||
|
||||
static void I_NetClientDisconnected(size_t client)
|
||||
static void I_NetClientDisconnected(int client)
|
||||
{
|
||||
StartWindow->NetDisconnect(client);
|
||||
}
|
||||
|
||||
static void I_NetUpdatePlayers(size_t current, size_t limit)
|
||||
static void I_NetUpdatePlayers(int current, int limit)
|
||||
{
|
||||
StartWindow->NetProgress(current, limit);
|
||||
}
|
||||
|
|
@ -488,16 +488,17 @@ static void SendPacket(const sockaddr_in& to)
|
|||
if (NetBufferLength >= MinCompressionSize)
|
||||
{
|
||||
TransmitBuffer[0] = NetBuffer[0] | NCMD_COMPRESSED;
|
||||
res = compress2(TransmitBuffer + 1, &size, NetBuffer + 1, NetBufferLength - 1u, 9);
|
||||
|
||||
res = compress2(TransmitBuffer + 1, &size, NetBuffer + 1, uint32_t(NetBufferLength - 1u), 9);
|
||||
++size;
|
||||
}
|
||||
|
||||
if (res == Z_OK && size < static_cast<uLong>(NetBufferLength))
|
||||
res = sendto(MySocket, (const char*)TransmitBuffer, size, 0, (const sockaddr*)&to, sizeof(to));
|
||||
res = sendto(MySocket, (const char*)TransmitBuffer, (int)size, 0, (const sockaddr*)&to, sizeof(to));
|
||||
else if (NetBufferLength > MaxTransmitSize)
|
||||
I_Error("Net compression failed (zlib error %d)", res);
|
||||
else
|
||||
res = sendto(MySocket, (const char*)NetBuffer, NetBufferLength, 0, (const sockaddr*)&to, sizeof(to));
|
||||
res = sendto(MySocket, (const char*)NetBuffer, (int)NetBufferLength, 0, (const sockaddr*)&to, sizeof(to));
|
||||
}
|
||||
|
||||
static void GetPacket(sockaddr_in* const from = nullptr)
|
||||
|
|
@ -632,7 +633,7 @@ static void RejectConnection(const sockaddr_in& to, ENetConnectType reason)
|
|||
SendPacket(to);
|
||||
}
|
||||
|
||||
static void AddClientConnection(const sockaddr_in& from, size_t client)
|
||||
static void AddClientConnection(const sockaddr_in& from, int client)
|
||||
{
|
||||
Connected[client].Status = CSTAT_CONNECTING;
|
||||
Connected[client].Address = from;
|
||||
|
|
@ -641,7 +642,7 @@ static void AddClientConnection(const sockaddr_in& from, size_t client)
|
|||
I_NetClientUpdated(client);
|
||||
|
||||
// Make sure any ready clients are marked as needing the new client's info.
|
||||
for (size_t i = 1u; i < MaxClients; ++i)
|
||||
for (int i = 1; i < MaxClients; ++i)
|
||||
{
|
||||
if (Connected[i].Status == CSTAT_READY)
|
||||
{
|
||||
|
|
@ -651,7 +652,7 @@ static void AddClientConnection(const sockaddr_in& from, size_t client)
|
|||
}
|
||||
}
|
||||
|
||||
static void RemoveClientConnection(size_t client)
|
||||
static void RemoveClientConnection(int client)
|
||||
{
|
||||
I_NetClientDisconnected(client);
|
||||
I_ClearClient(client);
|
||||
|
|
@ -664,7 +665,7 @@ static void RemoveClientConnection(size_t client)
|
|||
NetBuffer[2] = client;
|
||||
NetBufferLength = 3u;
|
||||
|
||||
for (size_t i = 1u; i < MaxClients; ++i)
|
||||
for (int i = 1; i < MaxClients; ++i)
|
||||
{
|
||||
if (Connected[i].Status == CSTAT_NONE)
|
||||
continue;
|
||||
|
|
@ -694,7 +695,7 @@ static bool Host_CheckForConnections(void* connected)
|
|||
{
|
||||
const bool forceStarting = I_ShouldStartNetGame();
|
||||
const bool hasPassword = strlen(net_password) > 0;
|
||||
size_t* connectedPlayers = (size_t*)connected;
|
||||
int* connectedPlayers = (int*)connected;
|
||||
|
||||
TArray<int> toBoot = {};
|
||||
I_GetKickClients(toBoot);
|
||||
|
|
@ -780,7 +781,7 @@ static bool Host_CheckForConnections(void* connected)
|
|||
}
|
||||
else
|
||||
{
|
||||
size_t free = 1u;
|
||||
int free = 1;
|
||||
for (; free < MaxClients; ++free)
|
||||
{
|
||||
if (Connected[free].Status == CSTAT_NONE)
|
||||
|
|
@ -815,7 +816,7 @@ static bool Host_CheckForConnections(void* connected)
|
|||
const size_t addrSize = sizeof(sockaddr_in);
|
||||
bool ready = true;
|
||||
NetBuffer[0] = NCMD_SETUP;
|
||||
for (size_t client = 1u; client < MaxClients; ++client)
|
||||
for (int client = 1; client < MaxClients; ++client)
|
||||
{
|
||||
auto& con = Connected[client];
|
||||
// If we're starting before the lobby is full, only check against connected clients.
|
||||
|
|
@ -855,7 +856,7 @@ static bool Host_CheckForConnections(void* connected)
|
|||
}
|
||||
|
||||
NetBuffer[1] = PRE_USER_INFO;
|
||||
for (size_t i = 0u; i < MaxClients; ++i)
|
||||
for (int i = 0; i < MaxClients; ++i)
|
||||
{
|
||||
if (i == client || Connected[i].Status == CSTAT_NONE)
|
||||
continue;
|
||||
|
|
@ -864,7 +865,7 @@ static bool Host_CheckForConnections(void* connected)
|
|||
{
|
||||
if (Connected[i].Status >= CSTAT_WAITING)
|
||||
{
|
||||
NetBuffer[2] = i;
|
||||
NetBuffer[2] = uint8_t(i);
|
||||
NetBufferLength = 3u;
|
||||
// Client will already have the host connection information.
|
||||
if (i > 0)
|
||||
|
|
@ -908,7 +909,7 @@ static void SendAbort()
|
|||
|
||||
if (consoleplayer == 0)
|
||||
{
|
||||
for (size_t client = 1u; client < MaxClients; ++client)
|
||||
for (int client = 1; client < MaxClients; ++client)
|
||||
{
|
||||
if (Connected[client].Status != CSTAT_NONE)
|
||||
SendPacket(Connected[client].Address);
|
||||
|
|
@ -935,7 +936,7 @@ static bool HostGame(int arg, bool forcedNetMode)
|
|||
Net_SetupUserInfo();
|
||||
|
||||
// If only 1 player, don't bother starting the network
|
||||
if (MaxClients == 1u)
|
||||
if (MaxClients == 1)
|
||||
{
|
||||
TicDup = 1u;
|
||||
multiplayer = true;
|
||||
|
|
@ -944,11 +945,11 @@ static bool HostGame(int arg, bool forcedNetMode)
|
|||
|
||||
StartNetwork(false);
|
||||
I_NetInit("Waiting for other players...", true);
|
||||
I_NetUpdatePlayers(1u, MaxClients);
|
||||
I_NetUpdatePlayers(1, MaxClients);
|
||||
I_NetClientConnected(0u, 16u);
|
||||
|
||||
// Wait for the lobby to be full.
|
||||
size_t connectedPlayers = 1u;
|
||||
int connectedPlayers = 1;
|
||||
if (!I_NetLoop(Host_CheckForConnections, (void*)&connectedPlayers))
|
||||
{
|
||||
SendAbort();
|
||||
|
|
@ -961,10 +962,11 @@ static bool HostGame(int arg, bool forcedNetMode)
|
|||
|
||||
// If the player force started with only themselves in the lobby, start the game
|
||||
// immediately.
|
||||
if (connectedPlayers == 1u)
|
||||
if (connectedPlayers == 1)
|
||||
{
|
||||
CloseNetwork();
|
||||
MaxClients = TicDup = 1u;
|
||||
MaxClients = 1;
|
||||
TicDup = 1u;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1102,7 +1104,7 @@ static bool Guest_ContactHost(void* unused)
|
|||
}
|
||||
else if (NetBuffer[1] == PRE_USER_INFO)
|
||||
{
|
||||
const size_t c = NetBuffer[2];
|
||||
const int c = NetBuffer[2];
|
||||
if (!ClientGotAck(consoleplayer, c))
|
||||
{
|
||||
NetworkClients += c;
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ extern uint8_t NetBuffer[MAX_MSGLEN];
|
|||
extern size_t NetBufferLength;
|
||||
extern uint8_t TicDup;
|
||||
extern int RemoteClient;
|
||||
extern uint8_t MaxClients;
|
||||
extern int MaxClients;
|
||||
extern uint32_t GameID;
|
||||
|
||||
bool I_InitNetwork();
|
||||
|
|
|
|||
|
|
@ -156,6 +156,7 @@ public:
|
|||
const char* GetHash() const { return Hash; }
|
||||
|
||||
int EntryCount() const { return NumLumps; }
|
||||
uint32_t EntryCountU() const { return NumLumps; }
|
||||
int FindEntry(const char* name);
|
||||
|
||||
size_t Length(uint32_t entry)
|
||||
|
|
|
|||
|
|
@ -67,13 +67,13 @@ struct BoneOverrideComponent
|
|||
void Modify(T &value, double tic) const
|
||||
{
|
||||
|
||||
double lerp_amt = interplen > 0.0 ? std::clamp(((tic - switchtic) / interplen), 0.0, 1.0) : 1.0;
|
||||
float lerp_amt = interplen > 0.0f ? std::clamp(float((tic - switchtic) / interplen), 0.0f, 1.0f) : 1.0f;
|
||||
|
||||
if(mode > 0 || (prev_mode > 0 && lerp_amt < 1.0))
|
||||
{
|
||||
T from = ModifyValue(value, prev, prev_mode);
|
||||
T to = ModifyValue(value, cur, mode);
|
||||
value = Lerp(from, to, lerp_amt, 1.0 - lerp_amt);
|
||||
value = Lerp(from, to, lerp_amt, 1.0f - lerp_amt);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -126,9 +126,10 @@ struct BoneOverride
|
|||
|
||||
struct BoneInfo
|
||||
{
|
||||
TArray<TRS> bones_anim_only;
|
||||
TArray<TRS> bones;
|
||||
TArray<TRS> bones_with_override;
|
||||
TArray<VSMatrix> positions;
|
||||
TArray<VSMatrix> positions_with_override;
|
||||
};
|
||||
|
||||
struct ModelAnim
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@ class FGameTexture;
|
|||
class IModelVertexBuffer;
|
||||
class FModel;
|
||||
class PClass;
|
||||
class AActor;
|
||||
struct FSpriteModelFrame;
|
||||
struct FLevelLocals;
|
||||
|
||||
FTextureID LoadSkin(const char* path, const char* fn);
|
||||
void FlushModels();
|
||||
|
|
@ -59,6 +61,9 @@ public:
|
|||
unsigned int getFlags(class DActorModelData * defs) const;
|
||||
friend void InitModels();
|
||||
friend void ParseModelDefLump(int Lump);
|
||||
|
||||
VSMatrix ObjectToWorldMatrix(AActor * actor, float x, float y, float z, double ticFrac);
|
||||
VSMatrix ObjectToWorldMatrix(FLevelLocals *Level, DVector3 translation, DRotator rotation, DVector2 scaling, unsigned int flags, double tic);
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -92,9 +97,12 @@ public:
|
|||
virtual int FindJoint(FName name) { return -1; }
|
||||
|
||||
virtual int GetJointParent(int joint) { return -1; }
|
||||
virtual double GetJointLength(int joint) { return 0.0; }
|
||||
virtual FName GetJointName(int joint) { return NAME_None; }
|
||||
virtual FVector3 GetJointDir(int joint) { return FVector3(0.0f,0.0f,0.0f); }
|
||||
virtual FQuaternion GetJointRotation(int joint) { return FQuaternion(0.0f,0.0f,0.0f,1.0f); }
|
||||
virtual FVector3 GetJointPosition(int joint) { return FVector3(0.0f,0.0f,0.0f); }
|
||||
virtual TRS GetJointBaseTRS(int joint) { return {}; }
|
||||
virtual TRS GetJointPose(int joint, int frame) { return {}; }
|
||||
virtual int NumFrames() { return -1; }
|
||||
|
||||
virtual void GetJointChildren(int joint, TArray<int> &out) {}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,9 @@ struct IQMJoint
|
|||
FVector3 Translate;
|
||||
FQuaternion Quaternion;
|
||||
FVector3 Scale;
|
||||
FVector3 Position;
|
||||
FQuaternion Rotation;
|
||||
FVector3 Scaling;
|
||||
};
|
||||
|
||||
struct IQMPose
|
||||
|
|
@ -164,7 +167,7 @@ private:
|
|||
TArray<VSMatrix> inversebaseframe;
|
||||
TArray<TRS> TRSData;
|
||||
public:
|
||||
int NumJoints() override { return Joints.Size(); }
|
||||
int NumJoints() override { return Joints.SSize(); }
|
||||
int FindJoint(FName name) override
|
||||
{
|
||||
int *j = NamedJoints.CheckKey(name);
|
||||
|
|
@ -174,12 +177,12 @@ public:
|
|||
|
||||
int GetJointParent(int joint) override
|
||||
{
|
||||
return (joint >= 0 && joint < Joints.Size()) ? Joints[joint].Parent : -1;
|
||||
return (joint >= 0 && joint < Joints.SSize()) ? Joints[joint].Parent : -1;
|
||||
}
|
||||
|
||||
FName GetJointName(int joint) override
|
||||
{
|
||||
return (joint >= 0 && joint < Joints.Size()) ? Joints[joint].Name : FName(NAME_None);
|
||||
return (joint >= 0 && joint < Joints.SSize()) ? Joints[joint].Name : FName(NAME_None);
|
||||
}
|
||||
|
||||
void GetRootJoints(TArray<int> &out) override
|
||||
|
|
@ -189,20 +192,34 @@ public:
|
|||
|
||||
void GetJointChildren(int joint, TArray<int> &out) override
|
||||
{
|
||||
if(joint >= 0 && joint < Joints.Size())
|
||||
if(joint >= 0 && joint < Joints.SSize())
|
||||
{
|
||||
out = Joints[joint].Children;
|
||||
}
|
||||
}
|
||||
|
||||
double GetJointLength(int joint) override
|
||||
FQuaternion GetJointRotation(int joint) override
|
||||
{
|
||||
return (joint >= 0 && joint < Joints.Size()) ? Joints[joint].Translate.Length() : 0.0;
|
||||
return (joint >= 0 && joint < Joints.SSize()) ? Joints[joint].Rotation : FQuaternion(0.0f,0.0f,0.0f,1.0f);
|
||||
}
|
||||
|
||||
FVector3 GetJointDir(int joint) override
|
||||
FVector3 GetJointPosition(int joint) override
|
||||
{
|
||||
return (joint >= 0 && joint < Joints.Size()) ? Joints[joint].Translate.Unit() : FVector3(0.0f,0.0f,0.0f);
|
||||
return (joint >= 0 && joint < Joints.SSize()) ? Joints[joint].Position : FVector3(0.0f,0.0f,0.0f);
|
||||
}
|
||||
|
||||
TRS GetJointBaseTRS(int joint) override
|
||||
{
|
||||
return (joint >= 0 && joint < Joints.SSize()) ? TRS{Joints[joint].Translate, Joints[joint].Quaternion, Joints[joint].Scale} : TRS{};
|
||||
}
|
||||
|
||||
TRS GetJointPose(int joint, int frame) override
|
||||
{
|
||||
return (joint >= 0 && joint < Joints.SSize() && frame >= 0 && ((frame * Joints.SSize()) + joint) < TRSData.SSize()) ? TRSData[(frame * Joints.SSize()) + joint] : TRS{} ;
|
||||
}
|
||||
virtual int NumFrames()
|
||||
{
|
||||
return Joints.SSize() > 0 ? (TRSData.SSize() / Joints.SSize()) : 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ bool IQMModel::Load(const char* path, int lumpnum, const char* buffer, int lengt
|
|||
}
|
||||
|
||||
reader.SeekTo(ofs_joints);
|
||||
for (int i = 0; i < Joints.Size(); i++)
|
||||
for (int i = 0; i < Joints.SSize(); i++)
|
||||
{
|
||||
IQMJoint& joint = Joints[i];
|
||||
|
||||
|
|
@ -127,8 +127,6 @@ bool IQMModel::Load(const char* path, int lumpnum, const char* buffer, int lengt
|
|||
joint.Translate.Y = reader.ReadFloat();
|
||||
joint.Translate.Z = reader.ReadFloat();
|
||||
|
||||
int len = joint.Translate.Length();
|
||||
|
||||
joint.Quaternion.X = reader.ReadFloat();
|
||||
joint.Quaternion.Y = reader.ReadFloat();
|
||||
joint.Quaternion.Z = reader.ReadFloat();
|
||||
|
|
@ -140,14 +138,24 @@ bool IQMModel::Load(const char* path, int lumpnum, const char* buffer, int lengt
|
|||
|
||||
if(joint.Parent < 0)
|
||||
{
|
||||
joint.Rotation = joint.Quaternion;
|
||||
joint.Scaling = joint.Scale;
|
||||
joint.Position = joint.Translate.ScaleXYZ(joint.Scaling);
|
||||
RootJoints.Push(i);
|
||||
}
|
||||
else if(joint.Parent >= Joints.Size())
|
||||
else if(joint.Parent >= i)
|
||||
{
|
||||
I_FatalError("Joint child comes before parent in IQM Model");
|
||||
}
|
||||
else if(joint.Parent >= Joints.SSize())
|
||||
{
|
||||
I_FatalError("Joint parent index out of bounds in IQM Model");
|
||||
}
|
||||
else
|
||||
{
|
||||
joint.Rotation = (Joints[joint.Parent].Rotation * joint.Quaternion).Unit();
|
||||
joint.Scaling = joint.Scale.ScaleXYZ(Joints[joint.Parent].Scaling);
|
||||
joint.Position = (Joints[joint.Parent].Rotation * joint.Translate.ScaleXYZ(joint.Scaling)) + Joints[joint.Parent].Position;
|
||||
Joints[joint.Parent].Children.Push(i);
|
||||
}
|
||||
}
|
||||
|
|
@ -619,11 +627,6 @@ const TArray<VSMatrix>* IQMModel::CalculateBones(const ModelAnimFrame &from, con
|
|||
}
|
||||
}
|
||||
|
||||
inline void ModifyBone(const BoneOverride& mod, TRS &bone, double time)
|
||||
{
|
||||
mod.Modify(bone, time);
|
||||
}
|
||||
|
||||
// explicitly don't pass modelBoneOverrides when precalculating animation for interpolation, as it's applied _after_ animation
|
||||
ModelAnimFramePrecalculatedIQM IQMModel::CalculateFrameIQM(int frame1, int frame2, float inter, int frame1_prev, float inter1_prev, int frame2_prev, float inter2_prev, const ModelAnimFramePrecalculatedIQM* precalculated, const TArray<TRS>* animationData)
|
||||
{
|
||||
|
|
@ -683,15 +686,16 @@ const TArray<VSMatrix>* IQMModel::CalculateBonesIQM(int frame1, int frame2, floa
|
|||
{
|
||||
const TArray<TRS>& animationFrames = animationData ? *animationData : TRSData;
|
||||
|
||||
TArray<VSMatrix>* outMatrix = out ? &out->positions : &boneData;
|
||||
TArray<VSMatrix>* outMatrix = out ? &out->positions_with_override : &boneData;
|
||||
|
||||
int numbones = Joints.SSize();
|
||||
outMatrix->Resize(numbones);
|
||||
|
||||
if(out)
|
||||
{
|
||||
out->bones_anim_only.Resize(numbones);
|
||||
out->bones.Resize(numbones);
|
||||
out->bones_with_override.Resize(numbones);
|
||||
out->positions.Resize(numbones);
|
||||
}
|
||||
|
||||
if(in && in->size() != Joints.Size()) in = nullptr;
|
||||
|
|
@ -702,11 +706,11 @@ const TArray<VSMatrix>* IQMModel::CalculateBonesIQM(int frame1, int frame2, floa
|
|||
frame1 = clamp(frame1, 0, (animationFrames.SSize() - 1) / numbones);
|
||||
frame2 = clamp(frame2, 0, (animationFrames.SSize() - 1) / numbones);
|
||||
|
||||
int offset1 = frame1 * numbones;
|
||||
int offset2 = frame2 * numbones;
|
||||
unsigned int offset1 = frame1 * numbones;
|
||||
unsigned int offset2 = frame2 * numbones;
|
||||
|
||||
int offset1_1 = frame1_prev * numbones;
|
||||
int offset2_1 = frame2_prev * numbones;
|
||||
unsigned int offset1_1 = frame1_prev * numbones;
|
||||
unsigned int offset2_1 = frame2_prev * numbones;
|
||||
|
||||
float invt = 1.0f - inter;
|
||||
float invt1 = 1.0f - inter1_prev;
|
||||
|
|
@ -752,7 +756,7 @@ const TArray<VSMatrix>* IQMModel::CalculateBonesIQM(int frame1, int frame2, floa
|
|||
|
||||
if(out)
|
||||
{
|
||||
out->bones_anim_only[i] = bone;
|
||||
out->bones[i] = bone;
|
||||
|
||||
if(in)
|
||||
{
|
||||
|
|
@ -775,7 +779,6 @@ const TArray<VSMatrix>* IQMModel::CalculateBonesIQM(int frame1, int frame2, floa
|
|||
VSMatrix& result = (*outMatrix)[i];
|
||||
if (Joints[i].Parent >= 0)
|
||||
{
|
||||
assert(Joints[i].Parent < i);
|
||||
result = (*outMatrix)[Joints[i].Parent];
|
||||
result.multMatrix(swapYZ);
|
||||
result.multMatrix(baseframe[Joints[i].Parent]);
|
||||
|
|
@ -789,6 +792,32 @@ const TArray<VSMatrix>* IQMModel::CalculateBonesIQM(int frame1, int frame2, floa
|
|||
result.multMatrix(inversebaseframe[i]);
|
||||
}
|
||||
result.multMatrix(swapYZ);
|
||||
|
||||
if(out)
|
||||
{
|
||||
VSMatrix m;
|
||||
m.loadIdentity();
|
||||
m.translate(out->bones[i].translation.X, out->bones[i].translation.Y, out->bones[i].translation.Z);
|
||||
m.multQuaternion(out->bones[i].rotation);
|
||||
m.scale(out->bones[i].scaling.X, out->bones[i].scaling.Y, out->bones[i].scaling.Z);
|
||||
|
||||
VSMatrix& result = out->positions[i];
|
||||
if (Joints[i].Parent >= 0)
|
||||
{
|
||||
result = out->positions[Joints[i].Parent];
|
||||
result.multMatrix(swapYZ);
|
||||
result.multMatrix(baseframe[Joints[i].Parent]);
|
||||
result.multMatrix(m);
|
||||
result.multMatrix(inversebaseframe[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.loadMatrix(swapYZ);
|
||||
result.multMatrix(m);
|
||||
result.multMatrix(inversebaseframe[i]);
|
||||
}
|
||||
result.multMatrix(swapYZ);
|
||||
}
|
||||
}
|
||||
|
||||
return &boneData;
|
||||
|
|
|
|||
|
|
@ -680,14 +680,14 @@ int PClass::FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction
|
|||
auto vproto = Virtuals[i]->Proto;
|
||||
auto &vflags = Virtuals[i]->ArgFlags;
|
||||
|
||||
int n = flags.size();
|
||||
int n = flags.SSize();
|
||||
|
||||
bool flagsOk = true;
|
||||
|
||||
for(int i = 0; i < n; i++)
|
||||
{
|
||||
int argA = i >= vflags.size() ? 0 : vflags[i];
|
||||
int argB = i >= flags.size() ? 0 : flags[i];
|
||||
int argA = i >= vflags.SSize() ? 0 : vflags[i];
|
||||
int argB = i >= flags.SSize() ? 0 : flags[i];
|
||||
|
||||
bool AisRef = argA & (VARF_Out | VARF_Ref);
|
||||
bool BisRef = argB & (VARF_Out | VARF_Ref);
|
||||
|
|
|
|||
|
|
@ -102,14 +102,14 @@ namespace
|
|||
float v_MinimumToFill2(uint32_t inwidth, uint32_t inheight)
|
||||
{
|
||||
// sx = screen x dimension, sy = same for y
|
||||
float sx = (float)inwidth * 1.2, sy = (float)inheight;
|
||||
float sx = (float)inwidth * 1.2f, sy = (float)inheight;
|
||||
static float lastsx = 0., lastsy = 0., result = 0.;
|
||||
if (lastsx != sx || lastsy != sy)
|
||||
{
|
||||
if (sx <= 0. || sy <= 0.)
|
||||
return 1.; // prevent x/0 error
|
||||
// set absolute minimum scale to fill the entire screen but get as close to 640x400 as possible
|
||||
float ssx = (float)(VID_MIN_UI_WIDTH) / 1.2 / sx, ssy = (float)(VID_MIN_UI_HEIGHT) / sy;
|
||||
float ssx = (float)(VID_MIN_UI_WIDTH) / 1.2f / sx, ssy = (float)(VID_MIN_UI_HEIGHT) / sy;
|
||||
result = (ssx < ssy) ? ssy : ssx;
|
||||
lastsx = sx;
|
||||
lastsy = sy;
|
||||
|
|
@ -165,7 +165,7 @@ namespace
|
|||
{ true, [](uint32_t Width, uint32_t Height)->uint32_t { return 1280; }, [](uint32_t Width, uint32_t Height)->uint32_t { return 800; }, 1.2f, false }, // 4 - 1280x800
|
||||
{ true, [](uint32_t Width, uint32_t Height)->uint32_t { return vid_scale_customwidth; }, [](uint32_t Width, uint32_t Height)->uint32_t { return vid_scale_customheight; }, 1.0f, true }, // 5 - Custom
|
||||
{ true, [](uint32_t Width, uint32_t Height)->uint32_t { return 320; }, [](uint32_t Width, uint32_t Height)->uint32_t { return 200; }, 1.2f, false }, // 6 - 320x200
|
||||
{ true, [](uint32_t Width, uint32_t Height)->uint32_t { return v_mfillX2(Width, Height) * 1.2; }, [](uint32_t Width, uint32_t Height)->uint32_t { return v_mfillY2(Width, Height); }, 1.2f, false }, // 7 - Minimum Scale to Fill Entire Screen (1.2)
|
||||
{ true, [](uint32_t Width, uint32_t Height)->uint32_t { return uint32_t(v_mfillX2(Width, Height) * 1.2); }, [](uint32_t Width, uint32_t Height)->uint32_t { return v_mfillY2(Width, Height); }, 1.2f, false }, // 7 - Minimum Scale to Fill Entire Screen (1.2)
|
||||
};
|
||||
bool isOutOfBounds(int x)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#endif
|
||||
#include "m_png.h"
|
||||
#include "basics.h"
|
||||
#include "printf.h"
|
||||
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
|
@ -944,7 +945,13 @@ bool M_SaveBitmap(const uint8_t *from, ESSType color_type, int width, int height
|
|||
|
||||
y = height;
|
||||
stream.next_out = buffer.data();
|
||||
stream.avail_out = buffer.size();
|
||||
|
||||
if(buffer.size() > UINT_MAX)
|
||||
{
|
||||
I_Error("save png buffer too large");
|
||||
}
|
||||
|
||||
stream.avail_out = (unsigned int) buffer.size();
|
||||
|
||||
temprow[0][0] = 0;
|
||||
#if USE_FILTER_HEURISTIC
|
||||
|
|
@ -1006,12 +1013,24 @@ bool M_SaveBitmap(const uint8_t *from, ESSType color_type, int width, int height
|
|||
}
|
||||
while (stream.avail_out == 0)
|
||||
{
|
||||
if (!WriteIDAT (file, buffer.data(), buffer.size()))
|
||||
|
||||
if(buffer.size() > INT_MAX)
|
||||
{
|
||||
I_Error("save png buffer too large");
|
||||
}
|
||||
int sz = (int) buffer.size();
|
||||
if (!WriteIDAT (file, buffer.data(), sz))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
stream.next_out = buffer.data();
|
||||
stream.avail_out = buffer.size();
|
||||
|
||||
if(buffer.size() > UINT_MAX)
|
||||
{
|
||||
I_Error("save png buffer too large");
|
||||
}
|
||||
|
||||
stream.avail_out = (unsigned int) buffer.size();
|
||||
if (stream.avail_in != 0)
|
||||
{
|
||||
err = deflate (&stream, (y == 0) ? Z_FINISH : 0);
|
||||
|
|
@ -1032,12 +1051,23 @@ bool M_SaveBitmap(const uint8_t *from, ESSType color_type, int width, int height
|
|||
}
|
||||
if (stream.avail_out == 0)
|
||||
{
|
||||
if (!WriteIDAT (file, buffer.data(), buffer.size()))
|
||||
if(buffer.size() > INT_MAX)
|
||||
{
|
||||
I_Error("save png buffer too large");
|
||||
}
|
||||
int sz = (int) buffer.size();
|
||||
if (!WriteIDAT (file, buffer.data(), sz))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
stream.next_out = buffer.data();
|
||||
stream.avail_out = buffer.size();
|
||||
|
||||
if(buffer.size() > UINT_MAX)
|
||||
{
|
||||
I_Error("save png buffer too large");
|
||||
}
|
||||
|
||||
stream.avail_out = (unsigned int) buffer.size();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1047,7 +1077,15 @@ bool M_SaveBitmap(const uint8_t *from, ESSType color_type, int width, int height
|
|||
{
|
||||
return false;
|
||||
}
|
||||
return WriteIDAT (file, buffer.data(), buffer.size() - stream.avail_out);
|
||||
|
||||
|
||||
if((buffer.size() - stream.avail_out) > INT_MAX)
|
||||
{
|
||||
I_Error("save png buffer too large");
|
||||
}
|
||||
int sz = (int) (buffer.size() - stream.avail_out);
|
||||
|
||||
return WriteIDAT (file, buffer.data(), sz);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ class VSMatrix {
|
|||
static void multMatrix(FLOATTYPE *resMatrix, const FLOATTYPE *aMatrix);
|
||||
|
||||
static void setIdentityMatrix(FLOATTYPE *mat, int size = 4);
|
||||
|
||||
public:
|
||||
/// The storage for matrices
|
||||
FLOATTYPE mMatrix[16];
|
||||
|
||||
|
|
|
|||
|
|
@ -82,25 +82,15 @@ public:
|
|||
}
|
||||
|
||||
// returns the XY fields as a 2D-vector.
|
||||
const Vector2& XY() const
|
||||
Vector2 XY() const
|
||||
{
|
||||
return *reinterpret_cast<const Vector2*>(this);
|
||||
return Vector2(X, Y);
|
||||
}
|
||||
|
||||
Vector2& XY()
|
||||
// returns the XYZ fields as a 3D-vector.
|
||||
Vector3 XYZ() const
|
||||
{
|
||||
return *reinterpret_cast<Vector2*>(this);
|
||||
}
|
||||
|
||||
// returns the XY fields as a 2D-vector.
|
||||
const Vector3& XYZ() const
|
||||
{
|
||||
return *reinterpret_cast<const Vector3*>(this);
|
||||
}
|
||||
|
||||
Vector3& XYZ()
|
||||
{
|
||||
return *reinterpret_cast<Vector3*>(this);
|
||||
return Vector3(X, Y, Z);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -320,7 +310,10 @@ public:
|
|||
auto factor = sinTheta / g_sqrt(lengthSquared);
|
||||
TQuaternion<vec_t> ret;
|
||||
ret.W = cosTheta;
|
||||
ret.XYZ() = factor * axis;
|
||||
auto xyz = vec_t(factor) * axis;
|
||||
ret.X = vec_t(xyz.X);
|
||||
ret.Y = vec_t(xyz.Y);
|
||||
ret.Z = vec_t(xyz.Z);
|
||||
return ret;
|
||||
}
|
||||
static TQuaternion<vec_t> FromAngles(TAngle<vec_t> yaw, TAngle<vec_t> pitch, TAngle<vec_t> roll)
|
||||
|
|
|
|||
|
|
@ -704,6 +704,11 @@ struct TVector3
|
|||
*this = *this ^ other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr TVector3 ScaleXYZ (const TVector3 &scaling)
|
||||
{
|
||||
return TVector3(X * scaling.X, Y * scaling.Y, Z * scaling.Z);
|
||||
}
|
||||
};
|
||||
|
||||
template<class vec_t>
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ void NetStartWindow::NetDisconnect(int client)
|
|||
if (Instance)
|
||||
{
|
||||
for (size_t i = 1u; i < Instance->LobbyWindow->GetColumnAmount(); ++i)
|
||||
Instance->LobbyWindow->UpdateItem("", client, i);
|
||||
Instance->LobbyWindow->UpdateItem("", client, int(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1785,12 +1785,15 @@ FExecList *D_MultiExec (FArgs *list, FExecList *exec)
|
|||
static void GetCmdLineFiles(std::vector<std::string>& wadfiles)
|
||||
{
|
||||
FString *args;
|
||||
int i, argc;
|
||||
int i;
|
||||
int argc;
|
||||
|
||||
argc = Args->CheckParmList("-file", &args);
|
||||
|
||||
assert(wadfiles.size() < INT_MAX);
|
||||
|
||||
// [RL0] Check for array size to only add new wads
|
||||
for (i = wadfiles.size(); i < argc; ++i)
|
||||
for (i = int(wadfiles.size()); i < argc; ++i)
|
||||
{
|
||||
D_AddWildFile(wadfiles, args[i].GetChars(), ".wad", GameConfig);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -418,7 +418,7 @@ void Net_SetWaiting()
|
|||
|
||||
// [RH] Rewritten to properly calculate the packet size
|
||||
// with our variable length Command.
|
||||
static int GetNetBufferSize()
|
||||
static size_t GetNetBufferSize()
|
||||
{
|
||||
if (NetBuffer[0] & NCMD_EXIT)
|
||||
return 1 + (NetMode == NET_PacketServer && RemoteClient == Net_Arbitrator);
|
||||
|
|
@ -528,7 +528,7 @@ static bool HGetPacket()
|
|||
if (RemoteClient == -1)
|
||||
return false;
|
||||
|
||||
int sizeCheck = GetNetBufferSize();
|
||||
size_t sizeCheck = GetNetBufferSize();
|
||||
if (NetBufferLength != sizeCheck)
|
||||
{
|
||||
Printf("Incorrect packet size %d (expected %d)\n", NetBufferLength, sizeCheck);
|
||||
|
|
@ -826,7 +826,7 @@ static void GetPackets()
|
|||
|
||||
for (size_t i = 0u; i < consistencies.Size(); ++i)
|
||||
{
|
||||
const int cTic = baseConsistency + i;
|
||||
const int cTic = baseConsistency + int(i);
|
||||
if (cTic <= pState.CurrentNetConsistency)
|
||||
continue;
|
||||
|
||||
|
|
@ -859,7 +859,7 @@ static void GetPackets()
|
|||
|
||||
for (size_t i = 0u; i < data.Size(); ++i)
|
||||
{
|
||||
const int seq = baseSequence + i;
|
||||
const int seq = baseSequence + int(i);
|
||||
// Duplicate command, ignore it.
|
||||
if (seq <= pState.CurrentSequence)
|
||||
continue;
|
||||
|
|
@ -1346,13 +1346,13 @@ void NetUpdate(int tics)
|
|||
return;
|
||||
}
|
||||
|
||||
constexpr size_t MaxPlayersPerPacket = 16u;
|
||||
constexpr int MaxPlayersPerPacket = 16;
|
||||
|
||||
int startSequence = startTic / TicDup;
|
||||
int endSequence = newestTic;
|
||||
int quitters = 0;
|
||||
int quitNums[MAXPLAYERS];
|
||||
size_t players = 1u;
|
||||
int players = 1u;
|
||||
int maxCommands = MAXSENDTICS;
|
||||
if (NetMode == NET_PacketServer && consoleplayer == Net_Arbitrator)
|
||||
{
|
||||
|
|
@ -1656,7 +1656,7 @@ const char* Net_GetClientName(int client, unsigned int charLimit = 0u)
|
|||
return players[client].userinfo.GetName(charLimit);
|
||||
}
|
||||
|
||||
int Net_SetUserInfo(int client, uint8_t*& stream)
|
||||
size_t Net_SetUserInfo(int client, uint8_t*& stream)
|
||||
{
|
||||
auto str = D_GetUserInfoStrings(client, true);
|
||||
const size_t userSize = str.Len() + 1;
|
||||
|
|
@ -1664,29 +1664,29 @@ int Net_SetUserInfo(int client, uint8_t*& stream)
|
|||
return userSize;
|
||||
}
|
||||
|
||||
int Net_ReadUserInfo(int client, uint8_t*& stream)
|
||||
size_t Net_ReadUserInfo(int client, uint8_t*& stream)
|
||||
{
|
||||
const uint8_t* start = stream;
|
||||
D_ReadUserInfoStrings(client, &stream, false);
|
||||
return int(stream - start);
|
||||
return stream - start;
|
||||
}
|
||||
|
||||
int Net_SetGameInfo(uint8_t*& stream)
|
||||
size_t Net_SetGameInfo(uint8_t*& stream)
|
||||
{
|
||||
const uint8_t* start = stream;
|
||||
WriteString(startmap.GetChars(), &stream);
|
||||
WriteInt32(rngseed, &stream);
|
||||
C_WriteCVars(&stream, CVAR_SERVERINFO, true);
|
||||
return int(stream - start);
|
||||
return stream - start;
|
||||
}
|
||||
|
||||
int Net_ReadGameInfo(uint8_t*& stream)
|
||||
size_t Net_ReadGameInfo(uint8_t*& stream)
|
||||
{
|
||||
const uint8_t* start = stream;
|
||||
startmap = ReadStringConst(&stream);
|
||||
rngseed = ReadInt32(&stream);
|
||||
C_ReadCVars(&stream);
|
||||
return int(stream - start);
|
||||
return stream - start;
|
||||
}
|
||||
|
||||
// Connects players to each other if needed.
|
||||
|
|
|
|||
|
|
@ -123,7 +123,12 @@ void DNetworkBuffer::AddDouble(double msg)
|
|||
|
||||
void DNetworkBuffer::AddString(const FString& msg)
|
||||
{
|
||||
_size += msg.Len() + 1u;
|
||||
if(msg.Len() >= UINT_MAX)
|
||||
{
|
||||
I_Error("network buffer string too large");
|
||||
}
|
||||
|
||||
_size += ((unsigned int)msg.Len()) + 1u;
|
||||
_buffer.Push({ NET_STRING, msg });
|
||||
}
|
||||
|
||||
|
|
@ -427,8 +432,14 @@ bool EventManager::SendNetworkCommand(const FName& cmd, VMVa_List& args)
|
|||
{
|
||||
++bytes; // Strings will always consume at least one byte.
|
||||
const FString* str = ListGetString(args);
|
||||
|
||||
if(str->Len() >= UINT_MAX || (bytes + (unsigned int)str->Len()) >= UINT_MAX)
|
||||
{
|
||||
I_Error("network buffer string too large");
|
||||
}
|
||||
|
||||
if (str != nullptr)
|
||||
bytes += str->Len();
|
||||
bytes += (unsigned int)str->Len();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2034,7 +2034,7 @@ void G_ReadSnapshots(FResourceFile *resf)
|
|||
|
||||
G_ClearSnapshots();
|
||||
|
||||
for (unsigned j = 0; j < resf->EntryCount(); j++)
|
||||
for (unsigned j = 0; j < resf->EntryCountU(); j++)
|
||||
{
|
||||
auto name = resf->getName(j);
|
||||
auto ptr = strstr(name, ".map.json");
|
||||
|
|
|
|||
|
|
@ -1033,7 +1033,7 @@ public:
|
|||
|
||||
void SetPlaneReflectivity(int pos, double val)
|
||||
{
|
||||
reflect[pos] = val;
|
||||
reflect[pos] = float(val);
|
||||
}
|
||||
|
||||
double GetPlaneReflectivity(int pos)
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ void FTextureAnimator::InitAnimated (void)
|
|||
if (lumpnum != -1)
|
||||
{
|
||||
auto animatedlump = fileSystem.ReadFile (lumpnum);
|
||||
int animatedlen = fileSystem.FileLength(lumpnum);
|
||||
ptrdiff_t animatedlen = fileSystem.FileLength(lumpnum);
|
||||
auto animdefs = animatedlump.bytes();
|
||||
const uint8_t *anim_p;
|
||||
FTextureID pic1, pic2;
|
||||
|
|
|
|||
|
|
@ -283,7 +283,12 @@ void InitBuildTiles()
|
|||
}
|
||||
|
||||
auto& artdata = TexMan.GetNewBuildTileData();
|
||||
artdata.Resize(fileSystem.FileLength(lumpnum));
|
||||
|
||||
ptrdiff_t len = fileSystem.FileLength(lumpnum);
|
||||
|
||||
assert(len >= 0 && len < UINT_MAX);
|
||||
|
||||
artdata.Resize((unsigned int)len);
|
||||
fileSystem.ReadFile(lumpnum, &artdata[0]);
|
||||
|
||||
if ((numtiles = CountTiles(&artdata[0])) > 0)
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ SettingsPage::SettingsPage(LauncherWindow* launcher, int* autoloadflags) : Widge
|
|||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
catch (const std::exception&)
|
||||
{
|
||||
hideLanguage = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -283,7 +283,7 @@ MapData *P_OpenMapData(const char * mapname, bool justcheck)
|
|||
map->MapLumps[0].Reader = map->resource->GetEntryReader(0, FileSys::READER_SHARED);
|
||||
uppercopy(map->MapLumps[0].Name, map->resource->getName(0));
|
||||
|
||||
for(uint32_t i = 1; i < map->resource->EntryCount(); i++)
|
||||
for(uint32_t i = 1; i < map->resource->EntryCountU(); i++)
|
||||
{
|
||||
const char* lumpname = map->resource->getName(i);
|
||||
|
||||
|
|
|
|||
|
|
@ -725,8 +725,19 @@ struct AnimModelOverride
|
|||
|
||||
enum EModelDataFlags
|
||||
{
|
||||
MODELDATA_HADMODEL = 1 << 0,
|
||||
MODELDATA_OVERRIDE_FLAGS = 1 << 1,
|
||||
MODELDATA_HADMODEL = 1 << 0,
|
||||
MODELDATA_OVERRIDE_FLAGS = 1 << 1,
|
||||
MODELDATA_GET_BONE_INFO = 1 << 2,
|
||||
MODELDATA_GET_BONE_INFO_RECALC = 1 << 3, // RECALCULATE BONE INFO INSTANTLY WHEN STATE/ANIMATION CHANGES, MIGHT GET EXPENSIVE
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
MODELDATA_IQMFLAGS = MODELDATA_GET_BONE_INFO | MODELDATA_GET_BONE_INFO_RECALC,
|
||||
};
|
||||
|
||||
class DActorModelData : public DObject
|
||||
|
|
@ -739,6 +750,7 @@ public:
|
|||
TArray<AnimModelOverride> animationIDs;
|
||||
TArray<int> modelFrameGenerators;
|
||||
TArray<TArray<BoneOverride>> modelBoneOverrides;
|
||||
TArray<BoneInfo> modelBoneInfo;
|
||||
int flags;
|
||||
int overrideFlagsSet;
|
||||
int overrideFlagsClear;
|
||||
|
|
@ -813,6 +825,15 @@ public:
|
|||
virtual void Tick() override;
|
||||
void EnableNetworking(const bool enable) override;
|
||||
|
||||
void CalcBones(bool recalc);
|
||||
TRS GetBoneTRS(int model_index, int bone_index, bool with_override);
|
||||
|
||||
//outmat must be double[16]
|
||||
void GetBoneMatrix(int model_index, int bone_index, bool with_override, double *outMat);
|
||||
|
||||
void GetBonePosition(int model_index, int bone_index, bool with_override, DVector3 &pos, DVector3 &normal);
|
||||
void GetObjectToWorldMatrix(double *outMat);
|
||||
|
||||
static AActor *StaticSpawn (FLevelLocals *Level, PClassActor *type, const DVector3 &pos, replace_t allowreplacement, bool SpawningMapThing = false);
|
||||
|
||||
inline AActor *GetDefault () const
|
||||
|
|
|
|||
|
|
@ -5125,15 +5125,6 @@ static void CleanupModelData(AActor * mobj)
|
|||
|
||||
FQuaternion InterpolateQuat(const FQuaternion &from, const FQuaternion &to, float t, float invt);
|
||||
|
||||
static void SetModelBoneRotationInternal(AActor * self, FModel * mdl, int model_index, int index, FQuaternion rotation, int mode, double interpolation_duration, double switchTic)
|
||||
{
|
||||
if(self->modelData->modelBoneOverrides.Size() <= model_index) self->modelData->modelBoneOverrides.Resize(model_index + 1);
|
||||
|
||||
self->modelData->modelBoneOverrides[model_index].Resize(mdl->NumJoints());
|
||||
|
||||
self->modelData->modelBoneOverrides[model_index][index].rotation.Set(rotation, switchTic, interpolation_duration, mode);
|
||||
}
|
||||
|
||||
template<bool isSet, bool isOffset>
|
||||
FModel * SetGetBoneShared(AActor * self, int model_index)
|
||||
{
|
||||
|
|
@ -5149,11 +5140,11 @@ FModel * SetGetBoneShared(AActor * self, int model_index)
|
|||
|
||||
EnsureModelData(self);
|
||||
|
||||
if(self->modelData->models.Size() > model_index && self->modelData->models[model_index].modelID >= 0 && self->modelData->models[model_index].modelID < Models.Size())
|
||||
if(self->modelData->models.SSize() > model_index && self->modelData->models[model_index].modelID >= 0 && self->modelData->models[model_index].modelID < Models.SSize())
|
||||
{
|
||||
return Models[self->modelData->models[model_index].modelID];
|
||||
}
|
||||
else if(BaseSpriteModelFrames[self->GetClass()].modelIDs.Size() > model_index)
|
||||
else if(BaseSpriteModelFrames[self->GetClass()].modelIDs.SSize() > model_index)
|
||||
{
|
||||
return Models[BaseSpriteModelFrames[self->GetClass()].modelIDs[model_index]];
|
||||
}
|
||||
|
|
@ -5182,7 +5173,7 @@ FModel * SetGetBoneSharedIndex(AActor * self, int model_index, int &bone_index,
|
|||
ThrowAbortException(X_OTHER, "bone index out of range");
|
||||
}
|
||||
|
||||
if(self->modelData->modelBoneOverrides.Size() <= model_index) self->modelData->modelBoneOverrides.Resize(model_index + 1);
|
||||
if(self->modelData->modelBoneOverrides.SSize() <= model_index) self->modelData->modelBoneOverrides.Resize(model_index + 1);
|
||||
|
||||
self->modelData->modelBoneOverrides[model_index].Resize(mdl->NumJoints());
|
||||
|
||||
|
|
@ -5224,6 +5215,8 @@ static void SetModelBoneRotationNative(AActor * self, int model_index, int bone_
|
|||
if(!mdl) return;
|
||||
|
||||
self->modelData->modelBoneOverrides[model_index][bone_index].rotation.Set(FQuaternion(rot_x, rot_y, rot_z, rot_w), self->Level->totaltime + ticFrac, interpolation_duration, mode);
|
||||
|
||||
self->CalcBones(true);
|
||||
}
|
||||
|
||||
static void SetBoneRotationNative(AActor * self, int bone_index, double rot_x, double rot_y, double rot_z, double rot_w, int mode, double interpolation_duration, double ticFrac)
|
||||
|
|
@ -5242,6 +5235,8 @@ static void SetModelNamedBoneRotationNative(AActor * self, int model_index, int
|
|||
if(!mdl) return;
|
||||
|
||||
self->modelData->modelBoneOverrides[model_index][bone_index].rotation.Set(FQuaternion(rot_x, rot_y, rot_z, rot_w), self->Level->totaltime + ticFrac, interpolation_duration, mode);
|
||||
|
||||
self->CalcBones(true);
|
||||
}
|
||||
|
||||
static void SetNamedBoneRotationNative(AActor * self, int boneName_i, double rot_x, double rot_y, double rot_z, double rot_w, int mode, double interpolation_duration, double ticFrac)
|
||||
|
|
@ -5294,6 +5289,8 @@ static void SetModelBoneTranslationNative(AActor * self, int model_index, int bo
|
|||
if(!mdl) return;
|
||||
|
||||
self->modelData->modelBoneOverrides[model_index][bone_index].translation.Set(FVector3(rot_x, rot_y, rot_z), self->Level->totaltime + ticFrac, interpolation_duration, mode);
|
||||
|
||||
self->CalcBones(true);
|
||||
}
|
||||
|
||||
static void SetBoneTranslationNative(AActor * self, int bone_index, double rot_x, double rot_y, double rot_z, int mode, double interpolation_duration, double ticFrac)
|
||||
|
|
@ -5312,6 +5309,8 @@ static void SetModelNamedBoneTranslationNative(AActor * self, int model_index, i
|
|||
if(!mdl) return;
|
||||
|
||||
self->modelData->modelBoneOverrides[model_index][bone_index].translation.Set(FVector3(rot_x, rot_y, rot_z), self->Level->totaltime + ticFrac, interpolation_duration, mode);
|
||||
|
||||
self->CalcBones(true);
|
||||
}
|
||||
|
||||
static void SetNamedBoneTranslationNative(AActor * self, int boneName_i, double rot_x, double rot_y, double rot_z, int mode, double interpolation_duration, double ticFrac)
|
||||
|
|
@ -5362,6 +5361,8 @@ static void SetModelBoneScalingNative(AActor * self, int model_index, int bone_i
|
|||
if(!mdl) return;
|
||||
|
||||
self->modelData->modelBoneOverrides[model_index][bone_index].scaling.Set(FVector3(rot_x, rot_y, rot_z), self->Level->totaltime + ticFrac, interpolation_duration, mode);
|
||||
|
||||
self->CalcBones(true);
|
||||
}
|
||||
|
||||
static void SetBoneScalingNative(AActor * self, int bone_index, double rot_x, double rot_y, double rot_z, int mode, double interpolation_duration, double ticFrac)
|
||||
|
|
@ -5380,6 +5381,8 @@ static void SetModelNamedBoneScalingNative(AActor * self, int model_index, int b
|
|||
if(!mdl) return;
|
||||
|
||||
self->modelData->modelBoneOverrides[model_index][bone_index].scaling.Set(FVector3(rot_x, rot_y, rot_z), self->Level->totaltime + ticFrac, interpolation_duration, mode);
|
||||
|
||||
self->CalcBones(true);
|
||||
}
|
||||
|
||||
static void SetNamedBoneScalingNative(AActor * self, int boneName_i, double rot_x, double rot_y, double rot_z, int mode, double interpolation_duration, double ticFrac)
|
||||
|
|
@ -5665,51 +5668,46 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetNamedBoneChildren, GetNamedBoneChildren
|
|||
return 0;
|
||||
}
|
||||
|
||||
static double GetBoneLengthNative(AActor * self, int bone_index)
|
||||
{
|
||||
FModel * mdl = GetBoneShared(self, 0, bone_index, nullptr);
|
||||
|
||||
return mdl->GetJointLength(bone_index);
|
||||
}
|
||||
|
||||
static double GetNamedBoneLengthNative(AActor * self, int boneName_i)
|
||||
{
|
||||
FName bone_name {ENamedName(boneName_i)};
|
||||
|
||||
int bone_index;
|
||||
|
||||
FModel * mdl = GetBoneShared(self, 0, bone_index, &bone_name);
|
||||
|
||||
return mdl->GetJointLength(bone_index);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetBoneLength, GetBoneLengthNative)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_INT(boneindex);
|
||||
|
||||
ACTION_RETURN_FLOAT(GetBoneLengthNative(self, boneindex));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetNamedBoneLength, GetNamedBoneLengthNative)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_NAME(bonename);
|
||||
|
||||
ACTION_RETURN_FLOAT(GetNamedBoneLengthNative(self, bonename.GetIndex()));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, GetBoneDir)
|
||||
DEFINE_ACTION_FUNCTION(AActor, GetBoneBaseTRS)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_INT(bone_index);
|
||||
|
||||
FModel * mdl = GetBoneShared(self, 0, bone_index, nullptr);
|
||||
|
||||
ACTION_RETURN_VEC3(DVector3(mdl->GetJointDir(bone_index)));
|
||||
DVector3 translation(0,0,0);
|
||||
DVector4 rotation(0,0,0,1);
|
||||
DVector3 scaling(0,0,0);
|
||||
|
||||
if(mdl)
|
||||
{
|
||||
TRS pose = mdl->GetJointBaseTRS(bone_index);
|
||||
|
||||
translation = DVector3(pose.translation);
|
||||
rotation = DVector4(pose.rotation);
|
||||
scaling = DVector3(pose.scaling);
|
||||
}
|
||||
|
||||
if(numret > 2)
|
||||
{
|
||||
ret[2].SetVector(scaling);
|
||||
numret = 3;
|
||||
}
|
||||
|
||||
if(numret > 1)
|
||||
{
|
||||
ret[1].SetVector(translation);
|
||||
}
|
||||
|
||||
if(numret > 0)
|
||||
{
|
||||
ret[0].SetVector4(rotation);
|
||||
}
|
||||
|
||||
return numret;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, GetNamedBoneDir)
|
||||
DEFINE_ACTION_FUNCTION(AActor, GetNamedBoneBaseTRS)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_NAME(bone_name);
|
||||
|
|
@ -5718,7 +5716,36 @@ DEFINE_ACTION_FUNCTION(AActor, GetNamedBoneDir)
|
|||
|
||||
FModel * mdl = GetBoneShared(self, 0, bone_index, &bone_name);
|
||||
|
||||
ACTION_RETURN_VEC3(DVector3(mdl->GetJointDir(bone_index)));
|
||||
DVector3 translation(0,0,0);
|
||||
DVector4 rotation(0,0,0,1);
|
||||
DVector3 scaling(0,0,0);
|
||||
|
||||
if(mdl)
|
||||
{
|
||||
TRS pose = mdl->GetJointBaseTRS(bone_index);
|
||||
|
||||
translation = DVector3(pose.translation);
|
||||
rotation = DVector4(pose.rotation);
|
||||
scaling = DVector3(pose.scaling);
|
||||
}
|
||||
|
||||
if(numret > 2)
|
||||
{
|
||||
ret[2].SetVector(scaling);
|
||||
numret = 3;
|
||||
}
|
||||
|
||||
if(numret > 1)
|
||||
{
|
||||
ret[1].SetVector(translation);
|
||||
}
|
||||
|
||||
if(numret > 0)
|
||||
{
|
||||
ret[0].SetVector4(rotation);
|
||||
}
|
||||
|
||||
return numret;
|
||||
}
|
||||
|
||||
static int GetBoneCountNative(AActor * self)
|
||||
|
|
@ -5735,9 +5762,415 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetBoneCount, GetBoneCountNative)
|
|||
ACTION_RETURN_INT(GetBoneCountNative(self));
|
||||
}
|
||||
|
||||
//================================================
|
||||
//
|
||||
// Bone Pose Getters
|
||||
//
|
||||
//================================================
|
||||
|
||||
static int GetAnimStartFrameNative(AActor * self, int animName_i)
|
||||
{
|
||||
FName anim_name {ENamedName(animName_i)};
|
||||
FModel * mdl = SetGetBoneShared<false, false>(self, 0);
|
||||
return mdl->FindFirstFrame(anim_name);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetAnimStartFrame, GetAnimStartFrameNative)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_NAME(animName);
|
||||
|
||||
ACTION_RETURN_INT(GetAnimStartFrameNative(self, animName.GetIndex()));
|
||||
}
|
||||
|
||||
static int GetAnimEndFrameNative(AActor * self, int animName_i)
|
||||
{
|
||||
FName anim_name {ENamedName(animName_i)};
|
||||
FModel * mdl = SetGetBoneShared<false, false>(self, 0);
|
||||
return mdl->FindLastFrame(anim_name);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetAnimEndFrame, GetAnimEndFrameNative)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_NAME(animName);
|
||||
|
||||
ACTION_RETURN_INT(GetAnimEndFrameNative(self, animName.GetIndex()));
|
||||
}
|
||||
|
||||
static double GetAnimFramerateNative(AActor * self, int animName_i)
|
||||
{
|
||||
FName anim_name {ENamedName(animName_i)};
|
||||
FModel * mdl = SetGetBoneShared<false, false>(self, 0);
|
||||
return mdl->FindFramerate(anim_name);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetAnimFramerate, GetAnimFramerateNative)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_NAME(animName);
|
||||
|
||||
ACTION_RETURN_FLOAT(GetAnimFramerateNative(self, animName.GetIndex()));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, GetBoneFramePose)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_INT(bone_index);
|
||||
PARAM_INT(frame_index);
|
||||
|
||||
FModel * mdl = GetBoneShared(self, 0, bone_index, nullptr);
|
||||
|
||||
DVector3 translation(0,0,0);
|
||||
DVector4 rotation(0,0,0,1);
|
||||
DVector3 scaling(0,0,0);
|
||||
|
||||
if(mdl && frame_index < mdl->NumFrames())
|
||||
{
|
||||
TRS pose = mdl->GetJointPose(bone_index, frame_index);
|
||||
|
||||
translation = DVector3(pose.translation);
|
||||
rotation = DVector4(pose.rotation);
|
||||
scaling = DVector3(pose.scaling);
|
||||
}
|
||||
|
||||
if(numret > 2)
|
||||
{
|
||||
ret[2].SetVector(scaling);
|
||||
numret = 3;
|
||||
}
|
||||
|
||||
if(numret > 1)
|
||||
{
|
||||
ret[1].SetVector(translation);
|
||||
}
|
||||
|
||||
if(numret > 0)
|
||||
{
|
||||
ret[0].SetVector4(rotation);
|
||||
}
|
||||
|
||||
return numret;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, GetNamedBoneFramePose)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_NAME(bone_name);
|
||||
PARAM_INT(frame_index);
|
||||
|
||||
int bone_index;
|
||||
|
||||
FModel * mdl = GetBoneShared(self, 0, bone_index, &bone_name);
|
||||
|
||||
DVector3 translation(0,0,0);
|
||||
DVector4 rotation(0,0,0,1);
|
||||
DVector3 scaling(0,0,0);
|
||||
|
||||
if(mdl && frame_index < mdl->NumFrames())
|
||||
{
|
||||
TRS pose = mdl->GetJointPose(bone_index, frame_index);
|
||||
|
||||
translation = DVector3(pose.translation);
|
||||
rotation = DVector4(pose.rotation);
|
||||
scaling = DVector3(pose.scaling);
|
||||
}
|
||||
|
||||
if(numret > 2)
|
||||
{
|
||||
ret[2].SetVector(scaling);
|
||||
numret = 3;
|
||||
}
|
||||
|
||||
if(numret > 1)
|
||||
{
|
||||
ret[1].SetVector(translation);
|
||||
}
|
||||
|
||||
if(numret > 0)
|
||||
{
|
||||
ret[0].SetVector4(rotation);
|
||||
}
|
||||
|
||||
return numret;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, GetBoneBasePosition)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_INT(bone_index);
|
||||
|
||||
FModel * mdl = GetBoneShared(self, 0, bone_index, nullptr);
|
||||
|
||||
ACTION_RETURN_VEC3(DVector3(mdl->GetJointPosition(bone_index)));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, GetNamedBoneBasePosition)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_NAME(bone_name);
|
||||
|
||||
int bone_index;
|
||||
|
||||
FModel * mdl = GetBoneShared(self, 0, bone_index, &bone_name);
|
||||
|
||||
ACTION_RETURN_VEC3(DVector3(mdl->GetJointPosition(bone_index)));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, GetBoneBaseRotation)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_INT(bone_index);
|
||||
|
||||
FModel * mdl = GetBoneShared(self, 0, bone_index, nullptr);
|
||||
|
||||
ACTION_RETURN_VEC4(DVector4(mdl->GetJointRotation(bone_index)));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, GetNamedBoneBaseRotation)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_NAME(bone_name);
|
||||
|
||||
int bone_index;
|
||||
|
||||
FModel * mdl = GetBoneShared(self, 0, bone_index, &bone_name);
|
||||
|
||||
ACTION_RETURN_VEC4(DVector4(mdl->GetJointRotation(bone_index)));
|
||||
}
|
||||
|
||||
//================================================
|
||||
//
|
||||
// Bone TRS Getters
|
||||
//
|
||||
//================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, GetBone)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_INT(bone_index);
|
||||
PARAM_BOOL(with_override);
|
||||
|
||||
FModel * mdl = GetBoneShared(self, 0, bone_index, nullptr);
|
||||
|
||||
DVector3 translation(0,0,0);
|
||||
DVector4 rotation(0,0,0,1);
|
||||
DVector3 scaling(0,0,0);
|
||||
|
||||
if(mdl)
|
||||
{
|
||||
TRS trs = self->GetBoneTRS(0, bone_index, with_override);
|
||||
|
||||
translation = DVector3(trs.translation);
|
||||
rotation = DVector4(trs.rotation);
|
||||
scaling = DVector3(trs.scaling);
|
||||
}
|
||||
|
||||
if(numret > 2)
|
||||
{
|
||||
ret[2].SetVector(scaling);
|
||||
numret = 3;
|
||||
}
|
||||
|
||||
if(numret > 1)
|
||||
{
|
||||
ret[1].SetVector(translation);
|
||||
}
|
||||
|
||||
if(numret > 0)
|
||||
{
|
||||
ret[0].SetVector4(rotation);
|
||||
}
|
||||
|
||||
return numret;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, GetNamedBone)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_NAME(bone_name);
|
||||
PARAM_BOOL(with_override);
|
||||
|
||||
int bone_index;
|
||||
|
||||
FModel * mdl = GetBoneShared(self, 0, bone_index, &bone_name);
|
||||
|
||||
DVector3 translation(0,0,0);
|
||||
DVector4 rotation(0,0,0,1);
|
||||
DVector3 scaling(0,0,0);
|
||||
|
||||
if(mdl)
|
||||
{
|
||||
TRS trs = self->GetBoneTRS(0, bone_index, with_override);
|
||||
|
||||
translation = DVector3(trs.translation);
|
||||
rotation = DVector4(trs.rotation);
|
||||
scaling = DVector3(trs.scaling);
|
||||
}
|
||||
|
||||
if(numret > 2)
|
||||
{
|
||||
ret[2].SetVector(scaling);
|
||||
numret = 3;
|
||||
}
|
||||
|
||||
if(numret > 1)
|
||||
{
|
||||
ret[1].SetVector(translation);
|
||||
}
|
||||
|
||||
if(numret > 0)
|
||||
{
|
||||
ret[0].SetVector4(rotation);
|
||||
}
|
||||
|
||||
return numret;
|
||||
}
|
||||
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, TransformByBone)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_INT(bone_index);
|
||||
PARAM_FLOAT(pos_x);
|
||||
PARAM_FLOAT(pos_y);
|
||||
PARAM_FLOAT(pos_z);
|
||||
PARAM_FLOAT(dir_x);
|
||||
PARAM_FLOAT(dir_y);
|
||||
PARAM_FLOAT(dir_z);
|
||||
PARAM_BOOL(with_override);
|
||||
|
||||
FModel * mdl = GetBoneShared(self, 0, bone_index, nullptr);
|
||||
|
||||
DVector3 position(pos_x, pos_y, pos_z);
|
||||
DVector3 direction(dir_x, dir_y, dir_z);
|
||||
|
||||
if(mdl)
|
||||
{
|
||||
self->GetBonePosition(0, bone_index, with_override, position, direction);
|
||||
}
|
||||
|
||||
if(numret > 1)
|
||||
{
|
||||
ret[1].SetVector(direction);
|
||||
}
|
||||
|
||||
if(numret > 0)
|
||||
{
|
||||
ret[0].SetVector(position);
|
||||
}
|
||||
|
||||
return numret;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, TransformByNamedBone)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_NAME(bone_name);
|
||||
PARAM_FLOAT(pos_x);
|
||||
PARAM_FLOAT(pos_y);
|
||||
PARAM_FLOAT(pos_z);
|
||||
PARAM_FLOAT(dir_x);
|
||||
PARAM_FLOAT(dir_y);
|
||||
PARAM_FLOAT(dir_z);
|
||||
PARAM_BOOL(with_override);
|
||||
|
||||
int bone_index;
|
||||
|
||||
FModel * mdl = GetBoneShared(self, 0, bone_index, &bone_name);
|
||||
|
||||
DVector3 position(pos_x, pos_y, pos_z);
|
||||
DVector3 direction(dir_x, dir_y, dir_z);
|
||||
|
||||
if(mdl)
|
||||
{
|
||||
self->GetBonePosition(0, bone_index, with_override, position, direction);
|
||||
}
|
||||
|
||||
if(numret > 1)
|
||||
{
|
||||
ret[1].SetVector(direction);
|
||||
}
|
||||
|
||||
if(numret > 0)
|
||||
{
|
||||
ret[0].SetVector(position);
|
||||
}
|
||||
|
||||
return numret;
|
||||
}
|
||||
|
||||
//================================================
|
||||
//
|
||||
// Bone Matrix Getters
|
||||
//
|
||||
//================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, GetBoneMatrixRaw)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_INT(bone_index);
|
||||
PARAM_POINTER(outMatrix, TArray<double>);
|
||||
PARAM_BOOL(with_override);
|
||||
|
||||
if(outMatrix)
|
||||
{
|
||||
FModel * mdl = GetBoneShared(self, 0, bone_index, nullptr);
|
||||
|
||||
outMatrix->Clear();
|
||||
outMatrix->Resize(16);
|
||||
|
||||
if(mdl)
|
||||
{
|
||||
self->GetBoneMatrix(0, bone_index, with_override, outMatrix->Data());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, GetNamedBoneMatrixRaw)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_NAME(bone_name);
|
||||
PARAM_POINTER(outMatrix, TArray<double>);
|
||||
PARAM_BOOL(with_override);
|
||||
|
||||
if(outMatrix)
|
||||
{
|
||||
int bone_index;
|
||||
|
||||
FModel * mdl = GetBoneShared(self, 0, bone_index, &bone_name);
|
||||
|
||||
outMatrix->Clear();
|
||||
outMatrix->Resize(16);
|
||||
|
||||
if(mdl)
|
||||
{
|
||||
self->GetBoneMatrix(0, bone_index, with_override, outMatrix->Data());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, GetObjectToWorldMatrixRaw)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_POINTER(outMatrix, TArray<double>);
|
||||
|
||||
if(outMatrix)
|
||||
{
|
||||
FModel * mdl = SetGetBoneShared<false, false>(self, 0);
|
||||
|
||||
outMatrix->Clear();
|
||||
outMatrix->Resize(16);
|
||||
|
||||
if(mdl)
|
||||
{
|
||||
self->GetObjectToWorldMatrix(outMatrix->Data());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//================================================
|
||||
// SetAnimation
|
||||
|
|
@ -5771,7 +6204,11 @@ void SetAnimationInternal(AActor * self, FName animName, double framerate, int s
|
|||
|
||||
if(animName == NAME_None)
|
||||
{
|
||||
if(self->modelData->curAnim.flags & MODELANIM_NONE) return;
|
||||
|
||||
self->modelData->curAnim.flags = MODELANIM_NONE;
|
||||
self->CalcBones(true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -5794,11 +6231,11 @@ void SetAnimationInternal(AActor * self, FName animName, double framerate, int s
|
|||
}
|
||||
|
||||
FModel * animation = nullptr;
|
||||
if (animID >= 0 && animID < Models.Size())
|
||||
if (animID >= 0 && animID < Models.SSize())
|
||||
{
|
||||
animation = Models[animID];
|
||||
}
|
||||
else if(self->modelData->models.Size() && self->modelData->models[0].modelID >= 0 && self->modelData->models[0].modelID < Models.Size())
|
||||
else if(self->modelData->models.Size() > 0 && self->modelData->models[0].modelID >= 0 && self->modelData->models[0].modelID < Models.SSize())
|
||||
{
|
||||
animation = Models[self->modelData->models[0].modelID];
|
||||
}
|
||||
|
|
@ -5811,8 +6248,12 @@ void SetAnimationInternal(AActor * self, FName animName, double framerate, int s
|
|||
|
||||
if(animStart == FErr_NotFound)
|
||||
{
|
||||
self->modelData->curAnim.flags = MODELANIM_NONE;
|
||||
Printf("Could not find animation %s\n", animName.GetChars());
|
||||
if(self->modelData->curAnim.flags & MODELANIM_NONE) return;
|
||||
|
||||
self->modelData->curAnim.flags = MODELANIM_NONE;
|
||||
self->CalcBones(true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -5861,20 +6302,32 @@ void SetAnimationInternal(AActor * self, FName animName, double framerate, int s
|
|||
|
||||
if(startFrame >= len)
|
||||
{
|
||||
self->modelData->curAnim.flags = MODELANIM_NONE;
|
||||
Printf("frame %d (startFrame) is past the end of animation %s\n", startFrame, animName.GetChars());
|
||||
if(self->modelData->curAnim.flags & MODELANIM_NONE) return;
|
||||
|
||||
self->modelData->curAnim.flags = MODELANIM_NONE;
|
||||
self->CalcBones(true);
|
||||
|
||||
return;
|
||||
}
|
||||
else if(loopFrame >= len)
|
||||
{
|
||||
self->modelData->curAnim.flags = MODELANIM_NONE;
|
||||
Printf("frame %d (loopFrame) is past the end of animation %s\n", startFrame, animName.GetChars());
|
||||
if(self->modelData->curAnim.flags & MODELANIM_NONE) return;
|
||||
|
||||
self->modelData->curAnim.flags = MODELANIM_NONE;
|
||||
self->CalcBones(true);
|
||||
|
||||
return;
|
||||
}
|
||||
else if(endFrame >= len)
|
||||
{
|
||||
self->modelData->curAnim.flags = MODELANIM_NONE;
|
||||
Printf("frame %d (endFrame) is past the end of animation %s\n", endFrame, animName.GetChars());
|
||||
if(self->modelData->curAnim.flags & MODELANIM_NONE) return;
|
||||
|
||||
self->modelData->curAnim.flags = MODELANIM_NONE;
|
||||
self->CalcBones(true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -5896,6 +6349,8 @@ void SetAnimationInternal(AActor * self, FName animName, double framerate, int s
|
|||
self->modelData->curAnim.startTic = tic;
|
||||
self->modelData->curAnim.switchOffset = 0;
|
||||
}
|
||||
|
||||
self->CalcBones(true);
|
||||
}
|
||||
|
||||
void SetAnimationNative(AActor * self, int i_animName, double framerate, int startFrame, int loopFrame, int endFrame, int interpolateTics, int flags)
|
||||
|
|
@ -5957,29 +6412,60 @@ void SetAnimationFrameRateUINative(AActor * self, double framerate)
|
|||
SetAnimationFrameRateInternal(self, framerate, I_GetTimeFrac());
|
||||
}
|
||||
|
||||
void SetModelFlag(AActor * self, int flag)
|
||||
void SetModelFlag(AActor * self, int flag, int iqmFlag)
|
||||
{
|
||||
EnsureModelData(self);
|
||||
self->modelData->flags |= MODELDATA_OVERRIDE_FLAGS;
|
||||
self->modelData->overrideFlagsSet |= flag;
|
||||
self->modelData->overrideFlagsClear &= ~flag;
|
||||
|
||||
iqmFlag &= MODELDATA_IQMFLAGS;
|
||||
|
||||
if(flag)
|
||||
{
|
||||
self->modelData->flags |= MODELDATA_OVERRIDE_FLAGS;
|
||||
self->modelData->overrideFlagsSet |= flag;
|
||||
self->modelData->overrideFlagsClear &= ~flag;
|
||||
}
|
||||
|
||||
if(iqmFlag)
|
||||
{
|
||||
self->modelData->flags |= iqmFlag;
|
||||
}
|
||||
}
|
||||
|
||||
void ClearModelFlag(AActor * self, int flag)
|
||||
void ClearModelFlag(AActor * self, int flag, int iqmFlag)
|
||||
{
|
||||
EnsureModelData(self);
|
||||
self->modelData->flags |= MODELDATA_OVERRIDE_FLAGS;
|
||||
self->modelData->overrideFlagsClear |= flag;
|
||||
self->modelData->overrideFlagsSet &= ~flag;
|
||||
|
||||
iqmFlag &= MODELDATA_IQMFLAGS;
|
||||
|
||||
if(flag)
|
||||
{
|
||||
self->modelData->flags |= MODELDATA_OVERRIDE_FLAGS;
|
||||
self->modelData->overrideFlagsClear |= flag;
|
||||
self->modelData->overrideFlagsSet &= ~flag;
|
||||
}
|
||||
|
||||
if(iqmFlag)
|
||||
{
|
||||
self->modelData->flags &= ~iqmFlag;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ResetModelFlags(AActor * self)
|
||||
void ResetModelFlags(AActor * self, int resetModel, int resetIqm)
|
||||
{
|
||||
if(self->modelData)
|
||||
{
|
||||
self->modelData->overrideFlagsClear = 0;
|
||||
self->modelData->overrideFlagsSet = 0;
|
||||
self->modelData->flags &= ~MODELDATA_OVERRIDE_FLAGS;
|
||||
if(resetModel)
|
||||
{
|
||||
self->modelData->overrideFlagsClear = 0;
|
||||
self->modelData->overrideFlagsSet = 0;
|
||||
self->modelData->flags &= ~MODELDATA_OVERRIDE_FLAGS;
|
||||
}
|
||||
|
||||
if(resetIqm)
|
||||
{
|
||||
self->modelData->flags &= ~MODELDATA_IQMFLAGS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6148,6 +6634,11 @@ void ChangeModelNative(
|
|||
|
||||
CleanupModelData(mobj);
|
||||
|
||||
if(animation != NAME_None || modeldef != nullptr)
|
||||
{
|
||||
mobj->CalcBones(true);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -6228,8 +6719,9 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, SetModelFlag, SetModelFlag)
|
|||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_INT(flag);
|
||||
PARAM_INT(flagIqm);
|
||||
|
||||
SetModelFlag(self, flag);
|
||||
SetModelFlag(self, flag, flagIqm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -6238,8 +6730,9 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, ClearModelFlag, ClearModelFlag)
|
|||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_INT(flag);
|
||||
PARAM_INT(flagIqm);
|
||||
|
||||
ClearModelFlag(self, flag);
|
||||
ClearModelFlag(self, flag, flagIqm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -6247,8 +6740,10 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, ClearModelFlag, ClearModelFlag)
|
|||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, ResetModelFlags, ResetModelFlags)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_BOOL(resetModel);
|
||||
PARAM_BOOL(resetIqm);
|
||||
|
||||
ResetModelFlags(self);
|
||||
ResetModelFlags(self, resetModel, resetIqm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1701,8 +1701,6 @@ int P_LookForTID (AActor *actor, INTBOOL allaround, FLookExParams *params)
|
|||
AActor *LookForEnemiesInBlock (AActor *lookee, int index, void *extparam)
|
||||
{
|
||||
FBlockNode *block;
|
||||
AActor *link;
|
||||
AActor *other;
|
||||
FLookExParams *params = (FLookExParams *)extparam;
|
||||
|
||||
for (block = lookee->Level->blockmap.blocklinks[index]; block != NULL; block = block->NextActor)
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@
|
|||
#include "fragglescript/t_fs.h"
|
||||
#include "shadowinlines.h"
|
||||
#include "model.h"
|
||||
#include "models.h"
|
||||
#include "d_net.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
|
@ -4244,6 +4245,122 @@ DEFINE_ACTION_FUNCTION(AActor, CheckPortalTransition)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void AActor::CalcBones(bool recalc)
|
||||
{
|
||||
if(modelData && (!recalc || (modelData->flags & MODELDATA_GET_BONE_INFO_RECALC)) && modelData->flags & MODELDATA_GET_BONE_INFO)
|
||||
{
|
||||
if(picnum.isValid()) return; // picnum overrides don't render models
|
||||
|
||||
FSpriteModelFrame *smf = FindModelFrame(this, sprite, frame, false); // dropped flag is for voxels
|
||||
|
||||
if(!smf) return;
|
||||
|
||||
bool is_decoupled = flags9 & MF9_DECOUPLEDANIMATIONS;
|
||||
double tic = Level->totaltime + 1;
|
||||
|
||||
CalcModelFrameInfo frameinfo = CalcModelFrame(Level, smf, state, tics, modelData, this, is_decoupled, tic, 1.0);
|
||||
|
||||
ModelDrawInfo drawinfo;
|
||||
|
||||
int boneStartingPosition = -1;
|
||||
bool evaluatedSingle = false;
|
||||
|
||||
modelData->modelBoneInfo.Resize(frameinfo.modelsamount);
|
||||
|
||||
for (unsigned i = 0; i < frameinfo.modelsamount; i++)
|
||||
{
|
||||
if (CalcModelOverrides(i, smf, modelData, frameinfo, drawinfo, is_decoupled))
|
||||
{
|
||||
if(!evaluatedSingle)
|
||||
{ // [Jay] TODO per-model decoupled animations
|
||||
FModel * mdl = Models[drawinfo.modelid];
|
||||
bool nextFrame = frameinfo.smfNext && drawinfo.modelframe != drawinfo.modelframenext;
|
||||
ProcessModelFrame(mdl, nextFrame, i, smf, modelData, frameinfo, drawinfo, is_decoupled, tic, &modelData->modelBoneInfo[i]);
|
||||
|
||||
if(frameinfo.smf_flags & MDL_MODELSAREATTACHMENTS || is_decoupled)
|
||||
{
|
||||
evaluatedSingle = true;
|
||||
//if(!is_decoupled) break;
|
||||
|
||||
break; // TODO remove this break when per-model decoupled animations are in
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TRS AActor::GetBoneTRS(int model_index, int bone_index, bool with_override)
|
||||
{
|
||||
if(modelData && (modelData->flags & MODELDATA_GET_BONE_INFO) && model_index > 0 && bone_index > 0 && modelData->modelBoneInfo.SSize() < model_index && modelData->modelBoneInfo[model_index].bones.SSize() < bone_index)
|
||||
{
|
||||
return with_override ? modelData->modelBoneInfo[model_index].bones_with_override[bone_index] : modelData->modelBoneInfo[model_index].bones[bone_index];
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void AActor::GetBoneMatrix(int model_index, int bone_index, bool with_override, double *outMat)
|
||||
{
|
||||
VSMatrix boneMatrix = (with_override ? modelData->modelBoneInfo[model_index].positions_with_override : modelData->modelBoneInfo[model_index].positions)[bone_index];
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
outMat[i] = boneMatrix.mMatrix[i];
|
||||
}
|
||||
}
|
||||
|
||||
void AActor::GetBonePosition(int model_index, int bone_index, bool with_override, DVector3 &pos, DVector3 &normal)
|
||||
{
|
||||
if(modelData && modelData->flags & MODELDATA_GET_BONE_INFO)
|
||||
{
|
||||
if(picnum.isValid()) return; // picnum overrides don't render models
|
||||
|
||||
FSpriteModelFrame *smf = FindModelFrame(this, sprite, frame, false); // dropped flag is for voxels
|
||||
|
||||
FVector3 objPos = FVector3(Pos() + WorldOffset);
|
||||
|
||||
VSMatrix boneMatrix = (with_override ? modelData->modelBoneInfo[model_index].positions_with_override : modelData->modelBoneInfo[model_index].positions)[bone_index];
|
||||
VSMatrix worldMatrix = smf->ObjectToWorldMatrix(this, objPos.X, objPos.Y, objPos.Z, 1.0);
|
||||
|
||||
FVector4 oldPos(pos.X, pos.Z, pos.Y, 1.0);
|
||||
FVector4 newPos;
|
||||
FVector4 oldNormal(normal.X, normal.Z, normal.Y, 0.0);
|
||||
FVector4 newNormal;
|
||||
|
||||
boneMatrix.multMatrixPoint(&oldPos.X, &newPos.X);
|
||||
boneMatrix.multMatrixPoint(&oldNormal.X, &newNormal.X);
|
||||
|
||||
oldPos = FVector4(FVector3(newPos.X, newPos.Y, newPos.Z) / newPos.W, 1.0);
|
||||
oldNormal = FVector4(FVector3(newNormal.X, newNormal.Y, newNormal.Z) / newNormal.W, 0.0);
|
||||
|
||||
worldMatrix.multMatrixPoint(&oldPos.X, &newPos.X);
|
||||
worldMatrix.multMatrixPoint(&oldNormal.X, &newNormal.X);
|
||||
|
||||
pos = DVector3(newPos.X, newPos.Z, newPos.Y);
|
||||
normal = DVector3(newNormal.X, newNormal.Z, newNormal.Y);
|
||||
}
|
||||
}
|
||||
|
||||
void AActor::GetObjectToWorldMatrix(double *outMat)
|
||||
{
|
||||
if(modelData && modelData->flags & MODELDATA_GET_BONE_INFO)
|
||||
{
|
||||
if(picnum.isValid()) return; // picnum overrides don't render models
|
||||
|
||||
FSpriteModelFrame *smf = FindModelFrame(this, sprite, frame, false); // dropped flag is for voxels
|
||||
|
||||
FVector3 pos = FVector3(Pos() + WorldOffset);
|
||||
|
||||
VSMatrix outMatrix = smf->ObjectToWorldMatrix(this, pos.X, pos.Y, pos.Z, 1.0);
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
outMat[i] = outMatrix.mMatrix[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// P_MobjThinker
|
||||
//
|
||||
|
|
@ -4291,6 +4408,11 @@ void AActor::Tick ()
|
|||
return;
|
||||
}
|
||||
|
||||
if(flags9 & MF9_DECOUPLEDANIMATIONS)
|
||||
{
|
||||
CalcBones(false);
|
||||
}
|
||||
|
||||
AActor *onmo;
|
||||
|
||||
//assert (state != NULL);
|
||||
|
|
@ -4852,6 +4974,11 @@ void AActor::Tick ()
|
|||
}
|
||||
}
|
||||
|
||||
if(!(flags9 & MF9_DECOUPLEDANIMATIONS) && modelData && !(modelData->flags & MODELDATA_GET_BONE_INFO_RECALC))
|
||||
{
|
||||
CalcBones(false);
|
||||
}
|
||||
|
||||
if (tics == -1 || state->GetCanRaise())
|
||||
{
|
||||
int respawn_monsters = G_SkillProperty(SKILLP_Respawn);
|
||||
|
|
|
|||
|
|
@ -792,7 +792,7 @@ DEFINE_ACTION_FUNCTION(_PlayerInfo, GetSkin)
|
|||
DEFINE_ACTION_FUNCTION(_PlayerInfo, GetSkinCount)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(player_t);
|
||||
ACTION_RETURN_INT(Skins.size());
|
||||
ACTION_RETURN_INT(Skins.SSize());
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_PlayerInfo, GetGender)
|
||||
|
|
|
|||
|
|
@ -59,32 +59,42 @@ EXTERN_CVAR (Bool, r_drawvoxels)
|
|||
extern TDeletingArray<FVoxel *> Voxels;
|
||||
extern TDeletingArray<FVoxelDef *> VoxelDefs;
|
||||
|
||||
void RenderFrameModels(FModelRenderer* renderer, FLevelLocals* Level, const FSpriteModelFrame *smf, const FState* curState, const int curTics, FTranslationID translation, AActor* actor);
|
||||
|
||||
void RenderFrameModels(FModelRenderer* renderer, FLevelLocals* Level, const FSpriteModelFrame *smf, const FState* curState, int curTics, double tic, FTranslationID translation, AActor* actor);
|
||||
|
||||
void RenderModel(FModelRenderer *renderer, float x, float y, float z, FSpriteModelFrame *smf, AActor *actor, double ticFrac)
|
||||
{
|
||||
// Setup transformation.
|
||||
|
||||
int smf_flags = smf->getFlags(actor->modelData);
|
||||
|
||||
FTranslationID translation = NO_TRANSLATION;
|
||||
if (!(smf_flags & MDL_IGNORETRANSLATION))
|
||||
translation = actor->Translation;
|
||||
|
||||
// y scale for a sprite means height, i.e. z in the world!
|
||||
VSMatrix objectToWorldMatrix = smf->ObjectToWorldMatrix(actor, x, y, z, ticFrac);
|
||||
|
||||
float scaleFactorX = actor->Scale.X * smf->xscale;
|
||||
float scaleFactorY = actor->Scale.X * smf->yscale;
|
||||
float scaleFactorZ = actor->Scale.Y * smf->zscale;
|
||||
float pitch = 0;
|
||||
float roll = 0;
|
||||
double rotateOffset = 0;
|
||||
float orientation = scaleFactorX * scaleFactorY * scaleFactorZ;
|
||||
|
||||
renderer->BeginDrawModel(actor->RenderStyle, smf_flags, objectToWorldMatrix, orientation < 0);
|
||||
RenderFrameModels(renderer, actor->Level, smf, actor->state, actor->tics, ticFrac, translation, actor);
|
||||
renderer->EndDrawModel(actor->RenderStyle, smf_flags);
|
||||
}
|
||||
|
||||
VSMatrix FSpriteModelFrame::ObjectToWorldMatrix(AActor * actor, float x, float y, float z, double ticFrac)
|
||||
{
|
||||
int smf_flags = getFlags(actor->modelData);
|
||||
|
||||
// Setup transformation.
|
||||
DRotator angles;
|
||||
|
||||
if (actor->renderflags & RF_INTERPOLATEANGLES) // [Nash] use interpolated angles
|
||||
angles = actor->InterpolatedAngles(ticFrac);
|
||||
else
|
||||
angles = actor->Angles;
|
||||
|
||||
float angle = angles.Yaw.Degrees();
|
||||
float pitch = 0;
|
||||
float roll = 0;
|
||||
|
||||
// [BB] Workaround for the missing pitch information.
|
||||
if ((smf_flags & MDL_PITCHFROMMOMENTUM))
|
||||
|
|
@ -107,20 +117,6 @@ void RenderModel(FModelRenderer *renderer, float x, float y, float z, FSpriteMod
|
|||
}
|
||||
}
|
||||
|
||||
if (smf_flags & MDL_ROTATING)
|
||||
{
|
||||
if (smf->rotationSpeed > 0.0000000001 || smf->rotationSpeed < -0.0000000001)
|
||||
{
|
||||
double turns = (I_GetTime() + I_GetTimeFrac()) / (200.0 / smf->rotationSpeed);
|
||||
turns -= floor(turns);
|
||||
rotateOffset = turns * 360.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rotateOffset = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
|
@ -131,75 +127,116 @@ void RenderModel(FModelRenderer *renderer, float x, float y, float z, FSpriteMod
|
|||
}
|
||||
if (smf_flags & MDL_USEACTORROLL) roll += angles.Roll.Degrees();
|
||||
|
||||
// [Nash] take SpriteRotation into account
|
||||
angle += actor->SpriteRotation.Degrees();
|
||||
|
||||
double tic = actor->Level->totaltime;
|
||||
|
||||
if ((ConsoleState == c_up || ConsoleState == c_rising) && (menuactive == MENU_Off || menuactive == MENU_OnNoPause) && !actor->isFrozen())
|
||||
{
|
||||
tic += ticFrac;
|
||||
}
|
||||
|
||||
return ObjectToWorldMatrix(actor->Level, DVector3(x, y, z), DRotator(DAngle::fromDeg(pitch), DAngle::fromDeg(angle), DAngle::fromDeg(roll)), actor->Scale, smf_flags, tic);
|
||||
}
|
||||
|
||||
VSMatrix FSpriteModelFrame::ObjectToWorldMatrix(FLevelLocals *Level, DVector3 translation, DRotator rotation, DVector2 scaling, unsigned int flags, double tic)
|
||||
{
|
||||
double rotateOffset = 0;
|
||||
|
||||
if (flags & MDL_ROTATING)
|
||||
{
|
||||
if (rotationSpeed > 0.0000000001 || rotationSpeed < -0.0000000001)
|
||||
{
|
||||
double turns = (tic) / (200.0 / rotationSpeed);
|
||||
turns -= floor(turns);
|
||||
rotateOffset = turns * 360.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rotateOffset = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
// y scale for a sprite means height, i.e. z in the world!
|
||||
float scaleFactorX = scaling.X * xscale;
|
||||
float scaleFactorY = scaling.X * yscale;
|
||||
float scaleFactorZ = scaling.Y * zscale;
|
||||
|
||||
VSMatrix objectToWorldMatrix;
|
||||
objectToWorldMatrix.loadIdentity();
|
||||
|
||||
// Model space => World space
|
||||
objectToWorldMatrix.translate(x, z, y);
|
||||
|
||||
// [Nash] take SpriteRotation into account
|
||||
angle += actor->SpriteRotation.Degrees();
|
||||
objectToWorldMatrix.translate(translation.X, translation.Z, translation.Y);
|
||||
|
||||
// consider the pixel stretching. For non-voxels this must be factored out here
|
||||
float stretch = 1.f;
|
||||
|
||||
// [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) && smf->modelIDs.Size() > 0)
|
||||
if ((flags & MDL_CORRECTPIXELSTRETCH) && modelIDs.Size() > 0)
|
||||
{
|
||||
stretch = (smf->modelIDs[0] >= 0 ? Models[smf->modelIDs[0]]->getAspectFactor(actor->Level->info->pixelstretch) : 1.f) / actor->Level->info->pixelstretch;
|
||||
stretch = (modelIDs[0] >= 0 ? Models[modelIDs[0]]->getAspectFactor(Level->info->pixelstretch) : 1.f) / Level->info->pixelstretch;
|
||||
objectToWorldMatrix.scale(1, stretch, 1);
|
||||
}
|
||||
|
||||
// Applying model transformations:
|
||||
// 1) Applying actor angle, pitch and roll to the model
|
||||
if (smf_flags & MDL_USEROTATIONCENTER)
|
||||
if (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)
|
||||
{
|
||||
objectToWorldMatrix.translate(-smf->rotationCenterX, -smf->rotationCenterZ/stretch, -smf->rotationCenterY);
|
||||
}
|
||||
objectToWorldMatrix.translate(rotationCenterX, rotationCenterY/stretch, rotationCenterZ);
|
||||
|
||||
// 2) Applying Doomsday like rotation of the weapon pickup models
|
||||
// The rotation angle is based on the elapsed time.
|
||||
objectToWorldMatrix.rotate(-rotation.Yaw.Degrees(), 0, 1, 0);
|
||||
objectToWorldMatrix.rotate(rotation.Pitch.Degrees(), 0, 0, 1);
|
||||
objectToWorldMatrix.rotate(-rotation.Roll.Degrees(), 1, 0, 0);
|
||||
|
||||
if (smf_flags & MDL_ROTATING)
|
||||
// 2) Applying Doomsday like rotation of the weapon pickup models
|
||||
// The rotation angle is based on the elapsed time.
|
||||
if(flags & MDL_ROTATING)
|
||||
{
|
||||
objectToWorldMatrix.rotate(rotateOffset, xrotate, yrotate, zrotate);
|
||||
}
|
||||
|
||||
objectToWorldMatrix.translate(-rotationCenterX, -rotationCenterY/stretch, -rotationCenterZ);
|
||||
}
|
||||
else
|
||||
{
|
||||
objectToWorldMatrix.translate(smf->rotationCenterX, smf->rotationCenterY/stretch, smf->rotationCenterZ);
|
||||
objectToWorldMatrix.rotate(rotateOffset, smf->xrotate, smf->yrotate, smf->zrotate);
|
||||
objectToWorldMatrix.translate(-smf->rotationCenterX, -smf->rotationCenterY/stretch, -smf->rotationCenterZ);
|
||||
objectToWorldMatrix.rotate(-rotation.Yaw.Degrees(), 0, 1, 0);
|
||||
objectToWorldMatrix.rotate(rotation.Pitch.Degrees(), 0, 0, 1);
|
||||
objectToWorldMatrix.rotate(-rotation.Roll.Degrees(), 1, 0, 0);
|
||||
|
||||
|
||||
// 2) Applying Doomsday like rotation of the weapon pickup models
|
||||
// The rotation angle is based on the elapsed time.
|
||||
if(flags & MDL_ROTATING)
|
||||
{
|
||||
objectToWorldMatrix.translate(rotationCenterX, rotationCenterY/stretch, rotationCenterZ);
|
||||
objectToWorldMatrix.rotate(rotateOffset, xrotate, yrotate, zrotate);
|
||||
objectToWorldMatrix.translate(-rotationCenterX, -rotationCenterY/stretch, -rotationCenterZ);
|
||||
}
|
||||
}
|
||||
|
||||
// 3) Scaling model.
|
||||
objectToWorldMatrix.scale(scaleFactorX, scaleFactorZ, scaleFactorY);
|
||||
|
||||
// 4) Aplying model offsets (model offsets do not depend on model scalings).
|
||||
objectToWorldMatrix.translate(smf->xoffset / smf->xscale, smf->zoffset / (smf->zscale*stretch), smf->yoffset / smf->yscale);
|
||||
objectToWorldMatrix.translate(xoffset / xscale, zoffset / (zscale*stretch), yoffset / yscale);
|
||||
|
||||
// 5) Applying model rotations.
|
||||
objectToWorldMatrix.rotate(-smf->angleoffset, 0, 1, 0);
|
||||
objectToWorldMatrix.rotate(smf->pitchoffset, 0, 0, 1);
|
||||
objectToWorldMatrix.rotate(-smf->rolloffset, 1, 0, 0);
|
||||
objectToWorldMatrix.rotate(-angleoffset, 0, 1, 0);
|
||||
objectToWorldMatrix.rotate(pitchoffset, 0, 0, 1);
|
||||
objectToWorldMatrix.rotate(-rolloffset, 1, 0, 0);
|
||||
|
||||
if (!(smf_flags & MDL_CORRECTPIXELSTRETCH) && smf->modelIDs.Size() > 0)
|
||||
if (!(flags & MDL_CORRECTPIXELSTRETCH) && modelIDs.Size() > 0)
|
||||
{
|
||||
stretch = (smf->modelIDs[0] >= 0 ? Models[smf->modelIDs[0]]->getAspectFactor(actor->Level->info->pixelstretch) : 1.f) / actor->Level->info->pixelstretch;
|
||||
stretch = (modelIDs[0] >= 0 ? Models[modelIDs[0]]->getAspectFactor(Level->info->pixelstretch) : 1.f) / Level->info->pixelstretch;
|
||||
objectToWorldMatrix.scale(1, stretch, 1);
|
||||
}
|
||||
|
||||
float orientation = scaleFactorX * scaleFactorY * scaleFactorZ;
|
||||
|
||||
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_flags);
|
||||
return objectToWorldMatrix;
|
||||
}
|
||||
|
||||
void RenderHUDModel(FModelRenderer *renderer, DPSprite *psp, FVector3 translation, FVector3 rotation, FVector3 rotation_pivot, FSpriteModelFrame *smf)
|
||||
void RenderHUDModel(FModelRenderer *renderer, DPSprite *psp, FVector3 translation, FVector3 rotation, FVector3 rotation_pivot, FSpriteModelFrame *smf, double ticFrac)
|
||||
{
|
||||
AActor * playermo = players[consoleplayer].camera;
|
||||
|
||||
|
|
@ -256,7 +293,7 @@ void RenderHUDModel(FModelRenderer *renderer, DPSprite *psp, FVector3 translatio
|
|||
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);
|
||||
RenderFrameModels(renderer, playermo->Level, smf, psp->GetState(), psp->GetTics(), ticFrac, trans, psp->Caller);
|
||||
renderer->EndDrawHUDModel(playermo->RenderStyle, smf_flags);
|
||||
}
|
||||
|
||||
|
|
@ -313,7 +350,7 @@ void calcFrames(const ModelAnim &curAnim, double tic, ModelAnimFrameInterp &to,
|
|||
}
|
||||
}
|
||||
|
||||
CalcModelFrameInfo CalcModelFrame(FLevelLocals *Level, const FSpriteModelFrame *smf, const FState *curState, const int curTics, DActorModelData* data, AActor* actor, bool is_decoupled, double tic)
|
||||
CalcModelFrameInfo CalcModelFrame(FLevelLocals *Level, const FSpriteModelFrame *smf, const FState *curState, const int curTics, DActorModelData* data, AActor* actor, bool is_decoupled, double tic, double ticFrac)
|
||||
{
|
||||
// [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.
|
||||
|
|
@ -348,8 +385,9 @@ CalcModelFrameInfo CalcModelFrame(FLevelLocals *Level, const FSpriteModelFrame *
|
|||
// [BB] In case the tic counter is frozen we have to leave ticFraction at zero.
|
||||
if ((ConsoleState == c_up || ConsoleState == c_rising) && (menuactive == MENU_Off || menuactive == MENU_OnNoPause) && !Level->isFrozen())
|
||||
{
|
||||
ticFraction = I_GetTimeFrac();
|
||||
ticFraction = ticFrac;
|
||||
}
|
||||
|
||||
inter = static_cast<double>(curState->Tics - curTics + ticFraction) / static_cast<double>(curState->Tics);
|
||||
|
||||
// [BB] For some actors (e.g. ZPoisonShroom) spr->actor->tics can be bigger than curState->Tics.
|
||||
|
|
@ -413,11 +451,11 @@ bool CalcModelOverrides(int i, const FSpriteModelFrame *smf, DActorModelData* da
|
|||
if (data)
|
||||
{
|
||||
//modelID
|
||||
if (data->models.Size() > i && data->models[i].modelID >= 0)
|
||||
if (data->models.SSize() > i && data->models[i].modelID >= 0)
|
||||
{
|
||||
out.modelid = data->models[i].modelID;
|
||||
}
|
||||
else if(data->models.Size() > i && data->models[i].modelID == -2)
|
||||
else if(data->models.SSize() > i && data->models[i].modelID == -2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -427,7 +465,7 @@ bool CalcModelOverrides(int i, const FSpriteModelFrame *smf, DActorModelData* da
|
|||
}
|
||||
|
||||
//animationID
|
||||
if (data->animationIDs.Size() > i && data->animationIDs[i] >= 0)
|
||||
if (data->animationIDs.SSize() > i && data->animationIDs[i] >= 0)
|
||||
{
|
||||
out.animationid = data->animationIDs[i];
|
||||
}
|
||||
|
|
@ -438,7 +476,7 @@ bool CalcModelOverrides(int i, const FSpriteModelFrame *smf, DActorModelData* da
|
|||
if(!is_decoupled)
|
||||
{
|
||||
//modelFrame
|
||||
if (data->modelFrameGenerators.Size() > i
|
||||
if (data->modelFrameGenerators.SSize() > i
|
||||
&& (unsigned)data->modelFrameGenerators[i] < info.modelsamount
|
||||
&& smf->modelframes[data->modelFrameGenerators[i]] >= 0
|
||||
) {
|
||||
|
|
@ -464,7 +502,7 @@ bool CalcModelOverrides(int i, const FSpriteModelFrame *smf, DActorModelData* da
|
|||
}
|
||||
|
||||
//skinID
|
||||
if (data->skinIDs.Size() > i && data->skinIDs[i].isValid())
|
||||
if (data->skinIDs.SSize() > i && data->skinIDs[i].isValid())
|
||||
{
|
||||
out.skinid = data->skinIDs[i];
|
||||
}
|
||||
|
|
@ -474,7 +512,7 @@ bool CalcModelOverrides(int i, const FSpriteModelFrame *smf, DActorModelData* da
|
|||
}
|
||||
|
||||
//surfaceSkinIDs
|
||||
if(data->models.Size() > i && data->models[i].surfaceSkinIDs.Size() > 0)
|
||||
if(data->models.SSize() > i && data->models[i].surfaceSkinIDs.SSize() > 0)
|
||||
{
|
||||
unsigned sz1 = smf->surfaceskinIDs.Size();
|
||||
unsigned sz2 = data->models[i].surfaceSkinIDs.Size();
|
||||
|
|
@ -534,7 +572,7 @@ const TArray<VSMatrix> * ProcessModelFrame(FModel * animation, bool nextFrame, i
|
|||
frameinfo.decoupled_frame,
|
||||
frameinfo.inter,
|
||||
animationData,
|
||||
modelData->modelBoneOverrides.Size() > i
|
||||
modelData->modelBoneOverrides.SSize() > i
|
||||
? &modelData->modelBoneOverrides[i]
|
||||
: nullptr,
|
||||
out,
|
||||
|
|
@ -552,7 +590,7 @@ const TArray<VSMatrix> * ProcessModelFrame(FModel * animation, bool nextFrame, i
|
|||
},
|
||||
-1.0f,
|
||||
animationData,
|
||||
(modelData && modelData->modelBoneOverrides.Size() > i)
|
||||
(modelData && modelData->modelBoneOverrides.SSize() > i)
|
||||
? &modelData->modelBoneOverrides[i]
|
||||
: nullptr,
|
||||
out,
|
||||
|
|
@ -570,7 +608,7 @@ static inline void RenderModelFrame(FModelRenderer *renderer, int i, const FSpri
|
|||
|
||||
auto ssidp = drawinfo.surfaceskinids.Size() > 0
|
||||
? drawinfo.surfaceskinids.Data()
|
||||
: (((i * MD3_MAX_SURFACES) < smf->surfaceskinIDs.Size()) ? &smf->surfaceskinIDs[i * MD3_MAX_SURFACES] : nullptr);
|
||||
: (((i * MD3_MAX_SURFACES) < smf->surfaceskinIDs.SSize()) ? &smf->surfaceskinIDs[i * MD3_MAX_SURFACES] : nullptr);
|
||||
|
||||
bool nextFrame = frameinfo.smfNext && drawinfo.modelframe != drawinfo.modelframenext;
|
||||
|
||||
|
|
@ -589,19 +627,19 @@ static inline void RenderModelFrame(FModelRenderer *renderer, int i, const FSpri
|
|||
mdl->RenderFrame(renderer, tex, drawinfo.modelframe, nextFrame ? drawinfo.modelframenext : drawinfo.modelframe, nextFrame ? frameinfo.inter : -1.f, translation, ssidp, boneStartingPosition);
|
||||
}
|
||||
|
||||
void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpriteModelFrame *smf, const FState *curState, const int curTics, FTranslationID translation, AActor* actor)
|
||||
void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpriteModelFrame *smf, const FState *curState, int curTics, double ticFrac, FTranslationID translation, AActor* actor)
|
||||
{
|
||||
double tic = actor->Level->totaltime;
|
||||
if ((ConsoleState == c_up || ConsoleState == c_rising) && (menuactive == MENU_Off || menuactive == MENU_OnNoPause) && !actor->isFrozen())
|
||||
{
|
||||
tic += I_GetTimeFrac();
|
||||
tic += ticFrac;
|
||||
}
|
||||
|
||||
bool is_decoupled = (actor->flags9 & MF9_DECOUPLEDANIMATIONS);
|
||||
|
||||
DActorModelData* modelData = actor ? actor->modelData.ForceGet() : nullptr;
|
||||
|
||||
CalcModelFrameInfo frameinfo = CalcModelFrame(Level, smf, curState, curTics, modelData, actor, is_decoupled, tic);
|
||||
CalcModelFrameInfo frameinfo = CalcModelFrame(Level, smf, curState, curTics, modelData, actor, is_decoupled, tic, ticFrac);
|
||||
ModelDrawInfo drawinfo;
|
||||
|
||||
int boneStartingPosition = -1;
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ void BSPWalkCircle(FLevelLocals *Level, float x, float y, float radiusSquared, c
|
|||
}
|
||||
|
||||
void RenderModel(FModelRenderer* renderer, float x, float y, float z, FSpriteModelFrame* smf, AActor* actor, double ticFrac);
|
||||
void RenderHUDModel(FModelRenderer* renderer, DPSprite* psp, FVector3 translation, FVector3 rotation, FVector3 rotation_pivot, FSpriteModelFrame *smf);
|
||||
void RenderHUDModel(FModelRenderer* renderer, DPSprite* psp, FVector3 translation, FVector3 rotation, FVector3 rotation_pivot, FSpriteModelFrame *smf, double ticFrac);
|
||||
|
||||
struct CalcModelFrameInfo
|
||||
{
|
||||
|
|
@ -140,7 +140,7 @@ struct ModelDrawInfo
|
|||
|
||||
class DActorModelData;
|
||||
|
||||
CalcModelFrameInfo CalcModelFrame(FLevelLocals *Level, const FSpriteModelFrame *smf, const FState *curState, const int curTics, DActorModelData* modelData, AActor* actor, bool is_decoupled, double tic);
|
||||
CalcModelFrameInfo CalcModelFrame(FLevelLocals *Level, const FSpriteModelFrame *smf, const FState *curState, int curTics, DActorModelData* modelData, AActor* actor, bool is_decoupled, double tic, double ticFrac);
|
||||
|
||||
// returns true if the model isn't removed
|
||||
bool CalcModelOverrides(int modelindex, const FSpriteModelFrame *smf, DActorModelData* modelData, const CalcModelFrameInfo &frameinfo, ModelDrawInfo &drawinfo, bool is_decoupled);
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ void HWDrawInfo::DrawPSprite(HUDSprite *huds, FRenderState &state)
|
|||
state.AlphaFunc(Alpha_GEqual, 0);
|
||||
|
||||
FHWModelRenderer renderer(this, state, huds->lightindex);
|
||||
RenderHUDModel(&renderer, huds->weapon, huds->translation, huds->rotation + FVector3(huds->mx / 4., (huds->my - WEAPONTOP) / -4., 0), huds->pivot, huds->mframe);
|
||||
RenderHUDModel(&renderer, huds->weapon, huds->translation, huds->rotation + FVector3(huds->mx / 4., (huds->my - WEAPONTOP) / -4., 0), huds->pivot, huds->mframe, Viewpoint.TicFrac);
|
||||
state.SetVertexBuffer(screen->mVertexData);
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
#include "i_interface.h"
|
||||
#include "d_main.h"
|
||||
|
||||
const float MY_SQRT2 = 1.41421356237309504880; // sqrt(2)
|
||||
const float MY_SQRT2 = float(1.41421356237309504880); // sqrt(2)
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
extern bool DrawFSHUD; // [RH] Defined in d_main.cpp
|
||||
|
|
|
|||
|
|
@ -339,7 +339,7 @@ TArray<FString> I_GetSteamPath()
|
|||
}
|
||||
}
|
||||
}
|
||||
catch (const CRecoverableError& err)
|
||||
catch (const CRecoverableError&)
|
||||
{
|
||||
// don't abort on errors in here. Just return an empty path.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -416,7 +416,7 @@ static int actioncmp(void *_ap1,void *_ap2)
|
|||
rc = ap1->x.rp->index - ap2->x.rp->index;
|
||||
}
|
||||
if( rc==0 ){
|
||||
rc = ap2 - ap1;
|
||||
rc = (int)(ap2 - ap1);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -1957,7 +1957,7 @@ static int handleswitch(int i, FILE *err)
|
|||
if( err ){
|
||||
fprintf(err,
|
||||
"%sillegal character in floating-point argument.\n",emsg);
|
||||
errline(i,((size_t)end)-(size_t)argv[i],err);
|
||||
errline(i,(int)(((size_t)end)-(size_t)argv[i]),err);
|
||||
}
|
||||
errcnt++;
|
||||
}
|
||||
|
|
@ -1968,7 +1968,7 @@ static int handleswitch(int i, FILE *err)
|
|||
if( *end ){
|
||||
if( err ){
|
||||
fprintf(err,"%sillegal character in integer argument.\n",emsg);
|
||||
errline(i,((size_t)end)-(size_t)argv[i],err);
|
||||
errline(i,(int)(((size_t)end)-(size_t)argv[i]),err);
|
||||
}
|
||||
errcnt++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1442,17 +1442,67 @@ class Actor : Thinker native
|
|||
|
||||
native version("4.15.1") void GetBoneChildren(int boneIndex, out Array<int> children);
|
||||
native version("4.15.1") void GetNamedBoneChildren(Name boneName, out Array<int> children);
|
||||
|
||||
// this is the length in model units, not in world units, and does not take model scale in MODELDEF, world, etc, or current animation or offset into account at all
|
||||
native version("4.15.1") double GetBoneLength(int boneIndex);
|
||||
native version("4.15.1") double GetNamedBoneLength(Name boneName);
|
||||
|
||||
// this is the direction of the bone in the armature, does not take the current animation or offset into account at all
|
||||
native version("4.15.1") Vector3 GetBoneDir(int boneIndex);
|
||||
native version("4.15.1") Vector3 GetNamedBoneDir(Name boneName);
|
||||
|
||||
/* rotation, translation, scaling */
|
||||
native version("4.15.1") Quat, Vector3, Vector3 GetBoneBaseTRS(int boneIndex);
|
||||
native version("4.15.1") Quat, Vector3, Vector3 GetNamedBoneBaseTRS(Name boneName);
|
||||
|
||||
native version("4.15.1") Vector3 GetBoneBasePosition(int boneIndex);
|
||||
native version("4.15.1") Vector3 GetNamedBoneBasePosition(Name boneName);
|
||||
|
||||
native version("4.15.1") Quat GetBoneBaseRotation(int boneIndex);
|
||||
native version("4.15.1") Quat GetNamedBoneBaseRotation(Name boneName);
|
||||
|
||||
native version("4.15.1") int GetBoneCount();
|
||||
|
||||
//================================================
|
||||
//
|
||||
// Bone Pose Getters
|
||||
//
|
||||
//================================================
|
||||
|
||||
native version("4.15.1") int GetAnimStartFrame(Name animName);
|
||||
native version("4.15.1") int GetAnimEndFrame(Name animName);
|
||||
native version("4.15.1") double GetAnimFramerate(Name animName);
|
||||
|
||||
/* rotation, translation, scaling */
|
||||
native version("4.15.1") Quat, Vector3, Vector3 GetBoneFramePose(int boneIndex, int frame);
|
||||
native version("4.15.1") Quat, Vector3, Vector3 GetNamedBoneFramePose(Name boneName, int frame);
|
||||
|
||||
//================================================
|
||||
//
|
||||
// Bone TRS Getters
|
||||
//
|
||||
//================================================
|
||||
|
||||
/* rotation, translation, scaling */
|
||||
native version("4.15.1") Quat, Vector3, Vector3 GetBone(int boneIndex, bool include_offsets = true);
|
||||
native version("4.15.1") Quat, Vector3, Vector3 GetNamedBone(Name boneName, bool include_offsets = true);
|
||||
|
||||
native version("4.15.1") Vector3, Vector3 TransformByBone(int boneIndex, Vector3 position, Vector3 direction = (0,0,0), bool include_offsets = true);
|
||||
native version("4.15.1") Vector3, Vector3 TransformByNamedBone(Name boneName, Vector3 position, Vector3 direction = (0,0,0), bool include_offsets = true);
|
||||
|
||||
version("4.15.1") Vector3 GetBonePosition(int boneIndex, bool include_offsets = true)
|
||||
{
|
||||
return TransformByBone(boneIndex, GetBoneBasePosition(boneIndex), include_offsets:include_offsets);
|
||||
}
|
||||
|
||||
version("4.15.1") Vector3 GetNamedBonePosition(name boneName, bool include_offsets = true)
|
||||
{
|
||||
return GetBonePosition(GetBoneIndex(boneName), include_offsets);
|
||||
}
|
||||
|
||||
//================================================
|
||||
//
|
||||
// Bone Matrix Getters
|
||||
//
|
||||
//================================================
|
||||
|
||||
//outMatrix will be a 16-length array containing the raw matrix data
|
||||
native version("4.15.1") void GetBoneMatrixRaw(int boneIndex, out Array<double> outMatrix, bool include_offsets = true);
|
||||
native version("4.15.1") void GetNamedBoneMatrixRaw(Name boneName, out Array<double> outMatrix, bool include_offsets = true);
|
||||
|
||||
native version("4.15.1") void GetObjectToWorldMatrixRaw(out Array<double> outMatrix);
|
||||
|
||||
//================================================
|
||||
//
|
||||
|
|
@ -1460,16 +1510,15 @@ class Actor : Thinker native
|
|||
//
|
||||
//================================================
|
||||
|
||||
|
||||
native version("4.12") void SetAnimation(Name animName, double framerate = -1, int startFrame = -1, int loopFrame = -1, int endFrame = -1, int interpolateTics = -1, int flags = 0);
|
||||
native version("4.12") ui void SetAnimationUI(Name animName, double framerate = -1, int startFrame = -1, int loopFrame = -1, int endFrame = -1, int interpolateTics = -1, int flags = 0);
|
||||
|
||||
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();
|
||||
native version("4.12") void SetModelFlag(int flag, int iqmFlags = 0);
|
||||
native version("4.12") void ClearModelFlag(int flag, int iqmFlags = 0);
|
||||
native version("4.12") void ResetModelFlags(bool resetModel = true, bool resetIqm = false);
|
||||
|
||||
|
||||
action version("4.12") void A_SetAnimation(Name animName, double framerate = -1, int startFrame = -1, int loopFrame = -1, int endFrame = -1, int interpolateTics = -1, int flags = 0)
|
||||
|
|
|
|||
|
|
@ -1554,3 +1554,10 @@ enum ESetBoneMode
|
|||
SB_ADD = 1,
|
||||
SB_REPLACE = 2,
|
||||
};
|
||||
|
||||
enum EIQMFlags
|
||||
{
|
||||
IQM_GET_BONE_INFO = 1 << 2,
|
||||
IQM_GET_BONE_INFO_RECALC = 1 << 3, // RECALCULATE BONE INFO INSTANTLY WHEN STATE/ANIMATION CHANGES, MIGHT GET EXPENSIVE
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue