Jump to content

Inbuild GR2 Animation


Recommended Posts

  • Bronze

M2 Download Center

This is the hidden content, please
( Internal )

Hello together,

today i want to share something with you for christmas.
But before we start let me tell you, this system isn't in is final form! I will update this thread (if metin2dev will still exist in the new year) to
complete this system. Anyways let's get startet.

What kind of System is it?
You can use inbuilt animations on objects (map objects) and weapons (currently not working, just if the weapon is a ground item instance! I'm working on it).
Here is a preview: https://metin2.download/picture/JeG1pGK2WEyY5aY0CUwSk9N8WPoTjdr9/.gif
First you can see a placed object on the map with inbuilt animation (sorry it is really far away :O)
Later you can see a weapon (thanks to @Tatsumaru) which has an inbuilt animation. But this is currently just working as ground instance and not in the player hands itself.

How to implement it

Spoiler

Open up your client source (c++)

eterGrbLib

Spoiler

 

1. struct FSetMotionPointer, struct FChangeMotionPointer and struct FEndStopMotionPointer in eterGrbLib/LODController.h








//Change
const CGrannyMotion *	m_pMotion;
//With
std::shared_ptr<CGrannyMotion>	m_pMotion;


2. eterGrbLib/LODController.h








//Search for this
		void	SetMotionPointer(const CGrannyMotion * c_pMotion, float fBlendTime, int iLoopCount, float speedRatio);
		void	ChangeMotionPointer(const CGrannyMotion * c_pMotion, int iLoopCount, float speedRatio);
//Replace with
		void	SetMotionPointer(const std::shared_ptr<CGrannyMotion> c_pMotion, float fBlendTime, int iLoopCount, float speedRatio);
		void	ChangeMotionPointer(const std::shared_ptr<CGrannyMotion> c_pMotion, int iLoopCount, float speedRatio);


3. eterGrbLib/LODController.cpp








//Search for
void CGrannyLODController::SetMotionPointer(const CGrannyMotion * c_pMotion, float fBlendTime, int iLoopCount, float speedRatio)
//Replace with
void CGrannyLODController::SetMotionPointer(const std::shared_ptr<CGrannyMotion> c_pMotion, float fBlendTime, int iLoopCount, float speedRatio)


//Search for
void CGrannyLODController::ChangeMotionPointer(const CGrannyMotion * c_pMotion, int iLoopCount, float speedRatio)
//Replace with
void CGrannyLODController::ChangeMotionPointer(const std::shared_ptr<CGrannyMotion> c_pMotion, int iLoopCount, float speedRatio)


4. eterGrnLib/Mesh.cpp








//Search for
m_pgrnMeshDeformer = GrannyNewMeshDeformer(pgrnInputType, pgrnOutputType, GrannyDeformPositionNormal, GrannyDontAllowUncopiedTail);
//Replace with
m_pgrnMeshDeformer = GrannyNewMeshDeformer(pgrnInputType, pgrnOutputType, GrannyDeformPositionNormal, GrannyAllowUncopiedTail);

 

5. eterGrnLib/ModelInstance.h








//Search for
		void	SetMotionPointer(const CGrannyMotion* pMotion, float blendTime=0.0f, int loopCount=0, float speedRatio=1.0f);
		void	ChangeMotionPointer(const CGrannyMotion* pMotion, int loopCount=0, float speedRatio=1.0f);
//Replace with
		void	SetMotionPointer(const std::shared_ptr<CGrannyMotion> pMotion, float blendTime = 0.0f, int loopCount = 0, float speedRatio = 1.0f);
		void	ChangeMotionPointer(const std::shared_ptr<CGrannyMotion> pMotion, int loopCount = 0, float speedRatio = 1.0f);

 

6. eterGrnLib/ModelInstanceMotion.cpp








//Search for
void CGrannyModelInstance::SetMotionPointer(const CGrannyMotion * pMotion, float blendTime, int loopCount, float speedRatio)
//Replace with
void CGrannyModelInstance::SetMotionPointer(const std::shared_ptr<CGrannyMotion> pMotion, float blendTime, int loopCount, float speedRatio)

//Search for (it is in the SetMotionPointer function!)
	m_pgrnCtrl = GrannyPlayControlledAnimation(localTime, m_pgrnAni, pgrnModelInstance);
//Replace with
	granny_model_instance* InstanceOfModel = pgrnModelInstance;
	granny_animation* Animation = m_pgrnAni;
	granny_real32 StartTime = localTime;

	granny_controlled_animation_builder* Builder =
		GrannyBeginControlledAnimation(StartTime, Animation);
	if (Builder)
	{
		granny_int32x TrackGroupIndex;
		if (GrannyFindTrackGroupForModel(Animation,
			GrannyGetSourceModel(InstanceOfModel)->Name,
			&TrackGroupIndex))
		{
			GrannySetTrackGroupLOD(Builder, TrackGroupIndex, true, 1.0f);
			GrannySetTrackGroupTarget(Builder, TrackGroupIndex, InstanceOfModel);
		}
		else {
			GrannySetTrackGroupLOD(Builder, 1.0f, true, 1.0f);

			GrannySetTrackGroupTarget(Builder, 0, InstanceOfModel);
		}
		m_pgrnCtrl = GrannyEndControlledAnimation(Builder);

	}

//Search for
void CGrannyModelInstance::ChangeMotionPointer(const CGrannyMotion* pMotion, int loopCount, float speedRatio)
//Replace with
void CGrannyModelInstance::ChangeMotionPointer(const std::shared_ptr<CGrannyMotion> pMotion, int loopCount, float speedRatio)

 

7. eterGrnLib/Thing.h








//Search for
CGrannyMotion *			GetMotionPointer(int iMotion);
//Replace with
std::shared_ptr<CGrannyMotion> GetMotionPointer(int iMotion);

//Search for
CGrannyMotion *			m_motions;
//Replace with
std::vector<std::shared_ptr<CGrannyMotion>>			m_motions;

 

8. eterGrnLib/Thing.cpp








//Search for
void CGraphicThing::Initialize()
{
	...
}
//Replace with
void CGraphicThing::Initialize()
{
	m_pgrnFile = NULL;
	m_pgrnFileInfo = NULL;
	m_pgrnAni = NULL;

	m_models = NULL;
}


//Search for
void CGraphicThing::OnClear()
{
	...
}
//Replace with
void CGraphicThing::OnClear()
{
	if (!m_motions.empty())
		m_motions.clear();

	if (m_models)
		delete [] m_models;

	if (m_pgrnFile)
		GrannyFreeFile(m_pgrnFile);

	Initialize();
}


//Search for
CGrannyMotion * CGraphicThing::GetMotionPointer(int iMotion)
{
	...
}
//Replace with
std::shared_ptr<CGrannyMotion> CGraphicThing::GetMotionPointer(int iMotion)
{
	assert(CheckMotionIndex(iMotion));

	if (iMotion >= m_pgrnFileInfo->AnimationCount)
		return NULL;

	if (m_motions.empty())
		return NULL;

	return m_motions.at(iMotion);
}


//Search for
bool CGraphicThing::LoadMotions()
{
	...
}
//Replace with
bool CGraphicThing::LoadMotions()
{
	assert(m_pgrnFile != NULL);
	assert(m_motions->empty());

	if (m_pgrnFileInfo->AnimationCount <= 0)
		return false;

	int motionCount = m_pgrnFileInfo->AnimationCount;

	for (int m = 0; m < motionCount; ++m)
	{
		auto motion = std::make_shared<CGrannyMotion>();

		if (!motion->BindGrannyAnimation(m_pgrnFileInfo->Animations[m]))
			return false;

		m_motions.push_back(motion);
	}

	return true;
}

 


gameLib

Spoiler

 

1. gameLib/ActorInstanceMotion.cpp








//Search for
	CGrannyMotion * pGrannyMotion = pMotion->GetMotionPointer(0);
//Replace with
	std::shared_ptr<CGrannyMotion> pGrannyMotion = pMotion->GetMotionPointer(0);


2. gameLib/Area.cpp








//Search for
pkThingInst->Update();
//Add BEFORE!!!!
pkThingInst->Deform();

 


userInterface

Spoiler

 

1. userInterface/PythonItem.cpp








//Search for
itor->second->Update();
//Add BEFORE!!!
itor->second->ThingInstance.Deform();
itor->second->ThingInstance.Update();


//Search for
pGroundItemInstance->ThingInstance.Show();
//Add below
if (pGroundItemInstance->ThingInstance.GetBaseThingPtr()->GetMotionCount() > 0) {
	pGroundItemInstance->ThingInstance.RegisterMotionThing(0, pGroundItemInstance->ThingInstance.GetBaseThingPtr());
	pGroundItemInstance->ThingInstance.SetMotion(0);
}

 

 

 

 

Another part : by Distraught

 

Spoiler
if (CGrannyLODController* pLODController = m_LODControllerVector[dwPartIndex])
{
    if (CGrannyModelInstance* pWeaponModelInstance = pLODController->GetModelInstance())
    {
		CGraphicThing* pItemGraphicThing = pItemData->GetModelThing();
		if (CGrannyMotion* pItemMotion = pItemGraphicThing->GetMotionPointer(0))
		{
			pWeaponModelInstance->SetMotionPointer(pItemMotion);
		}
    }
}

Add the code above to the end of

void CActorInstance::AttachWeapon(DWORD dwParentPartIndex, DWORD dwPartIndex, CItemData * pItemData)

function in ActorInstanceAttach.cpp

 

and ThingInstance.cpp in the function 

bool CGraphicThingInstance::SetMotion(DWORD dwMotionKey, float blendTime, int loopCount, float speedRatio)

modify 

std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), SetMotionPointer);

to

for (int i = 0; i < m_LODControllerVector.size(); ++i)
{
	switch (i)
	{
		case CRaceData::PART_WEAPON:
		case CRaceData::PART_WEAPON_LEFT:
			break;

		default:
			SetMotionPointer(m_LODControllerVector[i]);
			break;
	}
}

and add these to the includes

#include "../GameLib/GameType.h"
#include "../GameLib/RaceData.h"

to make it work when the weapon is equipped. 💁‍♂️💁‍♂️

 

anim-weap-just-flexin-its-for-next-chris

 

 


What is missing for now?
Currently the deforming for weapons holden by the player won't work. But as i said in the first few lines, i will add it later. But for now
i want to give this parts to you for christmas! (Sorry i'm currently out of time to finish it before 2019 ends... Maybe someone of you want to
complet it in his on way).

The attachments
Animated Object: 

This is the hidden content, please
 <- Thanks to KillMoves who did this sometime ago!!!
(Animated Weapon:
This is the hidden content, please
 <- Thanks to Tatsumaru!!!

Have fun with it, your B4RC0D3

Edited by Metin2 Dev
Core X - External 2 Internal
  • Metin2 Dev 399
  • kekw 2
  • Eyes 7
  • Dislove 16
  • Angry 1
  • Not Good 4
  • Sad 2
  • Cry 2
  • Smile Tear 3
  • Think 11
  • Confused 8
  • Scream 7
  • Lmao 2
  • Good 137
  • Love 14
  • Love 269
Link to comment
Share on other sites

  • Bronze
vor 2 Stunden schrieb Kori:

Wow nice I think with a little knowledge we can create a better snow or rain animation for some maps and the drop animation with effect are really nice but I think when you have a big drop with ~30 dropps is the effect so hard or? 

I didn't tested the Effect with many drops. But this is a server specific "Feature" and not part of this System. Anyways those animated drops can easy disabled by some devs which understand how this release works. (HINT: You just need to edit two lines in PythonItem.cpp) Also this System was built, because i hate those mde weapons which will have a lower Performance as inbuilt animations.

 

Anyways lets see what the future will bring to us.

  • Love 1
Link to comment
Share on other sites

  • Bronze

But thats already built into the game you can enable it by just adding  the

->Deform();

Part for buildings all you are adding seems to be LOD to the animations and that is basically GrannySampleModelAnimationsAcceleratedLOD

Some of the M2M Map Objects have Animations builtin and also some metin2 objects there is a watermill for example that has an animation in its gr2 file

Ah the rest of your code gets rid of the: "Unable to find matching track_group for Model:" messages

 

 

  • Love 3
Link to comment
Share on other sites

  • 2 weeks later...
  • 5 months later...
  • 4 months later...
  • Management
Quote

(if metin2dev will still exist in the new year)

 

We survived the year 2020.
We will live the year 2021 together!

 

Did you continue to work on this system?

It's really interesting!

  • Metin2 Dev 1
Link to comment
Share on other sites

  • Honorable Member
if (CGrannyLODController* pLODController = m_LODControllerVector[dwPartIndex])
{
    if (CGrannyModelInstance* pWeaponModelInstance = pLODController->GetModelInstance())
    {
		CGraphicThing* pItemGraphicThing = pItemData->GetModelThing();
		if (CGrannyMotion* pItemMotion = pItemGraphicThing->GetMotionPointer(0))
		{
			pWeaponModelInstance->SetMotionPointer(pItemMotion);
		}
    }
}

Add the code above to the end of

void CActorInstance::AttachWeapon(DWORD dwParentPartIndex, DWORD dwPartIndex, CItemData * pItemData)

function in ActorInstanceAttach.cpp

 

and ThingInstance.cpp in the function 

bool CGraphicThingInstance::SetMotion(DWORD dwMotionKey, float blendTime, int loopCount, float speedRatio)

modify 

std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), SetMotionPointer);

to

for (int i = 0; i < m_LODControllerVector.size(); ++i)
{
	switch (i)
	{
		case CRaceData::PART_WEAPON:
		case CRaceData::PART_WEAPON_LEFT:
			break;

		default:
			SetMotionPointer(m_LODControllerVector[i]);
			break;
	}
}

and add these to the includes

#include "../GameLib/GameType.h"
#include "../GameLib/RaceData.h"

to make it work when the weapon is equipped. 💁‍♂️💁‍♂️

 

anim-weap-just-flexin-its-for-next-chris

 

Edited by Metin2 Dev
Core X - External 2 Internal
  • Metin2 Dev 3
  • Scream 2
  • Good 1
  • Love 16

WRnRW3H.gif

Link to comment
Share on other sites

  • Management
  • 1 month later...
  • 1 month later...

Help me!!! 

Severity Code Description Project File Line Status suppressed
Error C2664 'void CGrannyModelInstance :: SetMotionPointer (const std :: shared_ptr <CGrannyMotion>, float, int, float)': Argument 1 cannot be converted from 'CGrannyMotion *' to 'const std :: shared_ptr <CGrannyMotion>' gamelib D : \ Binary \ Binary \ Client \ GameLib \ ActorInstanceAttach.cpp 253

On 12/2/2020 at 9:52 AM, TokiSan said:

Awesome System!!


Here Metin2 Acce with animation

spacer.png

 

Mega Download

This is the hidden content, please
  ( Mega )

Could you pass me your ActorInstanceAttach.cpp, to compare with mine and see what I am placing wrong?

  • Metin2 Dev 8
  • Confused 1
  • Good 2
  • Love 2
  • Love 4
Link to comment
Share on other sites

  • 4 weeks later...
On 2/22/2021 at 12:27 PM, Tiburon said:

Help me!!! 

Severity Code Description Project File Line Status suppressed
Error C2664 'void CGrannyModelInstance :: SetMotionPointer (const std :: shared_ptr <CGrannyMotion>, float, int, float)': Argument 1 cannot be converted from 'CGrannyMotion *' to 'const std :: shared_ptr <CGrannyMotion>' gamelib D : \ Binary \ Binary \ Client \ GameLib \ ActorInstanceAttach.cpp 253

Could you pass me your ActorInstanceAttach.cpp, to compare with mine and see what I am placing wrong?

Hello, I have the same problem... Anyone can help?

Link to comment
Share on other sites

Announcements



×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.