Cyclic Animation for Newbies - Page 2

Cyclic Animation for Newbies

Discuss game development here, from a distinct game project to an accessible third-party mutator, down to the interaction and design of individual units if you like.

Moderator: Moderators

User avatar
Noruas
XTA Developer
Posts: 1269
Joined: 24 Feb 2005, 02:58

Post by Noruas »

Because it already proves me that yes, you are full of crap, and behind your "I'll share my discoveries, I'll give you a lot more of my source" posture, behind your impressive sounding wording, there's nothing valuable.
I think that statement is full of bs and crap, sure maybe hes wrong, but I'd like not to be an basher, which most people are on this forum zwzsg. Opps, i just bashed somebody didnt i, but yeah, harsh words. Zwzsg is right the other 100 percent.
User avatar
rattle
Damned Developer
Posts: 8278
Joined: 01 Jun 2006, 13:15

Post by rattle »

16380
It's supposed to be 16384!
User avatar
quantum
Posts: 590
Joined: 19 Sep 2006, 22:48

Post by quantum »

I'm convinced that Argh has a sincere desire to help. He went out of his way to make the Nanoblobs code easily understandable, and many of my forum searches ended with one of his posts on how something works. I don't think he needs to be treated harshly.
Even should he make a mistake, it may start a discussion from which valuable insight could be gained.
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Post by KDR_11k »

He's trying but he doesn't understand everything and has a tendency to hold mistaken beliefs while proclaiming they are great truths. IIRC he didn't learn what precompiler statements are until some time after I joined the board here which wasn't that long ago.

One of the ancient philosophers (Socrate or Aristotle, can't tell their philosophies apart) said "I know that I don't know" which means that he knows about the limits of his knowledge. If you know where your limits are you know where to improve. Nothing is more dangerous than falsely believing you know something (popular in tech-support stories).

Just for the heck of it, here's the walkscript.h from the Lolimod:

Code: Select all

static-var moving, walking, aiming;

#define THIGH_F <-30>
#define THIGH_B <20>
#define THIGHSPEED_F <100>
#define THIGHSPEED_B <100>
#define SHIN_F <0>
#define SHIN_B <40>
#define SHINSPEED_F <160>
#define SHINSPEED_B <160>
#define PELVIS <-10>
#define PELVISSPEED <80>
#define CHEST <15>
#define CHESTSPEED <100>
#define HEAD <-5>
#define HEADSPEED <30>
#define WALKBOB [2]
#define BOBSPEED [8]
#define ARM_F <-30>
#define ARM_B <30>
#define ARMSPEED_F <120>
#define ARMSPEED_B <120>

Walk() {
	if(walking) return 0; //semaphore
	walking=1;
	
	turn lthigh to x-axis 0 now;
	turn lshin to x-axis 0 now;
	turn rthigh to x-axis <-10> now;
	turn rshin to x-axis <20> now;
	turn pelvis to z-axis PELVIS now;
	turn chest to z-axis CHEST now;
	turn lthigh to z-axis 0 - PELVIS now;
	turn rthigh to z-axis 0 - PELVIS now;
	while(moving) {
		if (moving) {
			#ifdef USE_ARMS
			if (!aiming) turn ruarm to x-axis ARM_B speed ARMSPEED_B;
			#endif
			turn rthigh to x-axis THIGH_F speed THIGHSPEED_F;
			turn rshin to x-axis SHIN_B speed SHINSPEED_B;
			move pelvis to y-axis WALKBOB speed BOBSPEED;
			wait-for-turn lthigh around x-axis;
		}
		if (moving) {
			#ifdef USE_ARMS
			if (!aiming) turn luarm to x-axis ARM_F speed ARMSPEED_F;
			#endif
			turn lthigh to x-axis THIGH_B speed THIGHSPEED_B;
			turn pelvis to z-axis 0 - PELVIS speed PELVISSPEED;
			turn chest to z-axis 0 - CHEST speed CHESTSPEED;
			turn head to z-axis 0 - HEAD speed HEADSPEED;
			turn lthigh to z-axis PELVIS speed PELVISSPEED;
			turn rthigh to z-axis PELVIS speed PELVISSPEED;
			wait-for-turn rshin around x-axis;
		}
		if (moving) {
			turn rshin to x-axis SHIN_F speed SHINSPEED_F;
			move pelvis to y-axis 0 speed BOBSPEED;
			wait-for-turn rthigh around x-axis;
		}
		if (moving) {
			#ifdef USE_ARMS
			if (!aiming) turn luarm to x-axis ARM_B speed ARMSPEED_B;
			#endif
			turn rthigh to x-axis THIGH_B speed THIGHSPEED_B;
			turn pelvis to z-axis PELVIS speed PELVISSPEED;
			turn chest to z-axis CHEST speed CHESTSPEED;
			turn head to z-axis HEAD speed HEADSPEED;
			turn lthigh to z-axis 0 - PELVIS speed PELVISSPEED;
			turn rthigh to z-axis 0 - PELVIS speed PELVISSPEED;
			wait-for-turn lthigh around x-axis;
		}
		if (moving) {
			#ifdef USE_ARMS
			if (!aiming) turn ruarm to x-axis ARM_F speed ARMSPEED_F;
			#endif
			turn lthigh to x-axis THIGH_F speed THIGHSPEED_F;
			turn lshin to x-axis SHIN_B speed SHINSPEED_B;
			move pelvis to y-axis WALKBOB speed BOBSPEED;
			wait-for-turn lshin around x-axis;
		}
		if (moving) {
			turn lshin to x-axis SHIN_F speed SHINSPEED_F;
			move pelvis to y-axis 0 speed BOBSPEED;
			wait-for-turn rthigh around x-axis;
		}
	}
	walking=0;
	turn rthigh to x-axis 0 speed THIGHSPEED_F;
	turn lthigh to x-axis 0 speed THIGHSPEED_F;
	turn rshin to x-axis 0 speed SHINSPEED_F;
	turn lshin to x-axis 0 speed SHINSPEED_F;
	turn pelvis to z-axis 0 speed PELVISSPEED;
	turn chest to z-axis 0 speed CHESTSPEED;
	turn lthigh to z-axis 0 speed PELVISSPEED;
	turn rthigh to z-axis 0 speed PELVISSPEED;
	move pelvis to y-axis 0 speed BOBSPEED;
	turn head to z-axis 0 speed HEADSPEED;
	#ifdef USE_ARMS
	if (!aiming) call-script IdleAim();
	#endif
}
Feel free to take what you like. If left unchanged you need a hierarchy starting with a pelvis object that has legs (r/l thigh, shin, foot) and a chest which again has a head and arms (r/l uarm, farm, hand). Aiming tells the script whether you need the arms for an aiming animation (set it during AimWeapon and unset during your reset aim function), moving tells it whether you're still moving. In StartMoving you should set moving to 1 and start-script Walk(), in StopMoving you just put moving back to 0. Due to the semaphore the Walk() function will only be executed by one thread at a time. IdleAim() is the function that poses the unit's upper body int he idle stance.
User avatar
Fanger
Expand & Exterminate Developer
Posts: 1509
Joined: 22 Nov 2005, 22:58

Post by Fanger »

Hah..

thats all I have to say.. HAH..
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post by Argh »

All I have to say is, my Internet access went down for the past two days, and I came back to this :lol:

First off, I whole-heartedly retract my scripting tutorial. Nevermind that I'm working on a large project, and finding ways to Get Things Done is usually more important than How. Nevermind that saving 20-30 minutes, per scripting operation, is more important than the final efficiency. Because gosh, coding quickly and functionally just can't be more important to me than pure efficiency :roll:

You wanted efficiency... well, here ya go.

Here is the most efficient turn / wait-for-turn walk script with a rest state possible, so far as I can determine, after looking at the .BASM code made with Mafia's COB assembler. If you wish to disprove it, I expect to see sourcecode. GPL'd or not, but this is GPL.

Code: Select all

//Arghs's Maximum-Efficiency Turn / Wait-for-Turn Walkscript
//Released under the terms of the GPL, v 2.0 or later.
piece	body, gun, flare, pelvis, lthigh, lleg, lcalf, lfoot, rthigh, rleg, rcalf, rfoot;

static-var  bMoving;

StartMoving()
{
	bMoving = TRUE;
}

StopMoving()
{
	bMoving = FALSE;
}

Run(RandomSeed, StillMoving)
{
	RandomSeed = rand (200, 350);
	while(TRUE)
	{
///////////////////////////////////////////////////// HALT ANIMATION
		if(!bMoving)
		{
			wait-for-turn rfoot around x-axis;
			wait-for-turn rthigh around x-axis;
			wait-for-turn lfoot around x-axis;
			wait-for-turn lthigh around x-axis;

			move body to y-axis [0] speed [3000];
			turn pelvis to y-axis <0> speed <1500>;
			turn body to z-axis <0> speed <1500>;
////////////////////////////////////////////			
			turn lthigh to x-axis <0> speed <1500>;
			turn lleg to x-axis <0> speed <1500>;
			turn lcalf to x-axis <0> speed <1500>;
			turn lfoot to x-axis <0> speed <1500>;
////////////////////////////////////////////							
			turn rthigh to x-axis <0> speed <1500>;
			turn rleg to x-axis <0> speed <1500>;
			turn rcalf to x-axis <0> speed <1500>;
			turn rfoot to x-axis <0> speed <1500>;
			StillMoving=0;
			sleep RandomSeed;
		}
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
		++StillMoving;
		If(StillMoving == 5)
		{
			StillMoving = 1;
		}
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////		
		if(bMoving)
		{
///////////////////////////////////////////////////// LEFT FOOT FULL FORWARDS
			if(StillMoving == 1)
			{
				move body to y-axis [1] speed [10];			
				turn body to z-axis <5> speed <25>;
				turn pelvis to z-axis <-5> speed <25>;
////////////////////////////////////////////
				turn lthigh to x-axis <-7> speed <185>;
				turn lleg to x-axis <-74> speed <305>;
				turn lcalf to x-axis <63> speed <645>;
				turn lfoot to x-axis <35> speed <530>;
////////////////////////////////////////////
				turn rthigh to x-axis <15> speed <75>;
				turn rleg to x-axis <13> speed <65>;
				turn rcalf to x-axis <0> speed <0>;
				turn rfoot to x-axis <-10> speed <50>;
				
				wait-for-turn lcalf around x-axis;
			}
///////////////////////////////////////////////////// LEFT FOOT LANDS, BODY TOP
			if(StillMoving == 2)
			{
				move body to y-axis [0.5] speed [10];	
				turn body to z-axis <0> speed <25>;
				turn pelvis to z-axis <0> speed <25>;
////////////////////////////////////////////
				turn lthigh to x-axis <0> speed <35>;
				turn lleg to x-axis <0> speed <370>;
				turn lcalf to x-axis <0> speed <315>;
				turn lfoot to x-axis <0> speed <175>;
////////////////////////////////////////////
				turn rthigh to x-axis <30> speed <75>;
				turn rleg to x-axis <-13> speed <130>;
				turn rcalf to x-axis <-66> speed <330>;
				turn rfoot to x-axis <71> speed <405>;
				
				wait-for-turn rfoot around x-axis;
			}
///////////////////////////////////////////////////// RIGHT FOOT FULL FORWARDS
			if(StillMoving == 3)
			{
				move body to y-axis [1] speed [10];			
				turn body to z-axis <-5> speed <25>;
				turn pelvis to z-axis <5> speed <25>;
////////////////////////////////////////////
				turn rthigh to x-axis <-7> speed <185>;
				turn rleg to x-axis <-74> speed <305>;
				turn rcalf to x-axis <63> speed <645>;
				turn rfoot to x-axis <35> speed <530>;
////////////////////////////////////////////
				turn lthigh to x-axis <15> speed <75>;
				turn lleg to x-axis <13> speed <65>;
				turn lcalf to x-axis <0> speed <0>;
				turn lfoot to x-axis <-10> speed <50>;
				
				wait-for-turn rcalf around x-axis;
			}
///////////////////////////////////////////////////// RIGHT FOOT LANDS, BODY TOP
			if(StillMoving == 4)
			{
				move body to y-axis [0.5] speed [10];	
				turn body to z-axis <0> speed <25>;
				turn pelvis to z-axis <0> speed <25>;
////////////////////////////////////////////
				turn rthigh to x-axis <0> speed <35>;
				turn rleg to x-axis <0> speed <370>;
				turn rcalf to x-axis <0> speed <315>;
				turn rfoot to x-axis <0> speed <175>;
////////////////////////////////////////////
				turn lthigh to x-axis <30> speed <75>;
				turn lleg to x-axis <-13> speed <130>;
				turn lcalf to x-axis <-66> speed <330>;
				turn lfoot to x-axis <71> speed <405>;
				
				wait-for-turn lfoot around x-axis;
			}
		}
	}
}


Create()
{
	hide flare;
	start-script Run();
	start-script SmokeUnit_SWS();
}
Note the single static-var. It's really important. Static-vars and #defines are identical in actual function within the stack. There is no difference at the machine-language level. Whereas vars, on the other hand, only require movement within the stack. Go study the resulting code, using Mafia's tools, and you will start to understand what I'm saying here. Or not. But this code is GPL, and I have a feeling that if you guys actually test it, you will find that I'm right.

Lastly, the fact that I do not understand everything does not mean I'm stupid, or that I should be treated like this. Gloat all ya want, guys, but every time you do this, the amount of helpful stuff I do for the community goes down again. It'd be one thing if you said, "Hey Argh, I like your ideas, but here's some even better SOURCECODE", but this kind of e-peen stuff is actually pretty lame, and I'm ashamed for you- your mothers would be appalled ;)
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Post by KDR_11k »

Argh wrote:Static-vars and #defines are identical in actual function within the stack. There is no difference at the machine-language level.
So all literals are static vars? Why are you using literals then if you say local vars are the most efficient?
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post by Argh »

Literals aren't static-vars, they're read by the interpreter in the order they're written in the stack. Again, go look at Mafia's assembler, you're not understanding how COB actually works, because you expect it to work like C.

And I'm using that one static-var because of the way that StartMoving() works. I've done a lot of experiments with using stuff within StartMoving(), but I have not been satisfied with the results- it just doesn't seem to report a TRUE / FALSE condition more than once every few frames in Spring.

Here, lemme show you this little chunk:

Code: Select all

    // if ( bMoving  )
    pushs bMoving;
    jnz iflabel_Run_4;
      // {
      // if ( StillMoving == 1  )
      pushl StillMoving;
      pushc 1;
      cmp;
      jnz iflabel_Run_5;
        // {
        // move body to y-axis 163840 speed 1638400 
        pushc 1638400;
        pushc 163840;
        move;
        ddw body;
        ddw y-axis;
        // turn body to z-axis 910 speed 4551 
        pushc 4551;
        pushc 910;
        turn;
        ddw body;
        ddw z-axis;
        // turn pelvis to z-axis -910 speed 4551 
        pushc 4551;
        pushc -910;
        turn;
        ddw pelvis;
        ddw z-axis;
        // turn lthigh to x-axis -1274 speed 33678 
        pushc 33678;
        pushc -1274;
        turn;
        ddw lthigh;
        ddw x-axis;
        // turn lleg to x-axis -13471 speed 55524 
        pushc 55524;
        pushc -13471;
        turn;
        ddw lleg;
        ddw x-axis;
        // turn lcalf to x-axis 11469 speed 117419 
        pushc 117419;
        pushc 11469;
        turn;
        ddw lcalf;
        ddw x-axis;
        // turn lfoot to x-axis 6372 speed 96484 
        pushc 96484;
        pushc 6372;
        turn;
        ddw lfoot;
        ddw x-axis;
        // turn rthigh to x-axis 2731 speed 13653 
        pushc 13653;
        pushc 2731;
        turn;
        ddw rthigh;
        ddw x-axis;
        // turn rleg to x-axis 2367 speed 11833 
        pushc 11833;
        pushc 2367;
        turn;
        ddw rleg;
        ddw x-axis;
        // turn rcalf to x-axis 0 speed 0 
        pushc 0;
        pushc 0;
        turn;
        ddw rcalf;
        ddw x-axis;
        // turn rfoot to x-axis -1820 speed 9102 
        pushc 9102;
        pushc -1820;
        turn;
        ddw rfoot;
        ddw x-axis;
        // wait-for-turn lcalf around x-axis 
        wait-for-turn;
        ddw lcalf;
        ddw x-axis;
        // }
      iflabel_Run_5:
As you can see, the code is actually pushing the literals into the stack instructions as they occur. If you write it with a var, then it has to go fetch the var, which requires two steps, not one. If you use a static-var, then it has to do a search to the static-vars section of the COB, return the value, and populate the memory with it.
Last edited by Argh on 03 Jun 2007, 20:48, edited 1 time in total.
User avatar
Snipawolf
Posts: 4357
Joined: 12 Dec 2005, 01:49

Post by Snipawolf »

It's all nice and interesting Argh...

I don't have mechs in my mod though :lol:
imbaczek
Posts: 3629
Joined: 22 Aug 2006, 16:19

Post by imbaczek »

smoth wrote:[...]

To me this is one of the most important points in that entire post.
Except it doesn't matter.

The rest matters, though :>
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post by Argh »

Well, I have a lot of mechs / walkers / infantry to deal with, so this problem has been a big deal to me. I expect, in 4-player games, to see maybe 200 infantry walking around all the time. So, it's kind've a big deal that I eventually get all of the efficiency I can. I wasn't really worrying about that, when I wrote the first part of this- I was worrying about, "hey, how do I get about 30 cyclic walking scripts, all unique, written in less than a month". But it does matter.

And... what if you have tanks with moving tracks, or other stuff that can't just be solved with Spin? Here's a track script:

Code: Select all

//Argh's Tank-Track Script with Deceleration Controls
//Released under the GPL, v. 2.0 or later
static-var bMoving, Counter;

TreadControl(RandomSeed, TreadSection)
{
	RandomSeed = rand (200, 350);
	While( TRUE )
	{
		if(!bMoving)
		{
		sleep RandomSeed;
		}
		
		++TreadSection;
		If(TreadSection == 7)
		{
			TreadSection = 1;
		}
		if(bMoving)
		{
			
			If(TreadSection == 1)
			{
				show tread6;
				hide tread1;
			}
			If(TreadSection == 2)
			{
				show tread5;
				hide tread6;
			}
			If(TreadSection == 3)
			{
				show tread4;
				hide tread5;
			}
			If(TreadSection == 4)
			{
				show tread3;
				hide tread4;
			}
			If(TreadSection == 5)
			{
				show tread2;
				hide tread3;
			}
			If(TreadSection == 6)
			{
				show tread1;
				hide tread2;
			}
			sleep 30;
			
		}
	}
}

StartMoving()
{
	Counter = Counter - 1;
	if (Counter < 0)
	{
	Counter = 0;
	}
	bMoving = 1;
	return (0);
}

StopMoving()
{
	//Waits a bit before allowing Treads to quit animating, because StopMoving() is signalled before decelleration occurs, in Spring, so you may need to make this lengthy, or even adjust the sleeps in TreadControl(), to adequately simulate a slowly-decelerating Unit.  Counter must be greater than 5
	++Counter;	
	If (Counter >= 5);
	{
	bMoving = 0;
	Counter = 5;
	}
	sleep 100;
	return (0);
}
User avatar
Fanger
Expand & Exterminate Developer
Posts: 1509
Joined: 22 Nov 2005, 22:58

Post by Fanger »

fah still cant use that, because youve attached legal crap to it..
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post by Argh »

There is absolutely no reason why you can't use it, Fang, just make sure that your License is explicit about which parts are using the GPL'd sourcecode, and follow the rules. IOW, something like:

"Hey, everything in this mod is MINE, but the COB scripts use GPL'd code written by ARGH, which I have INCLUDED in this download, and are therefore covered under the GPL"

That doesn't give people the right to rip off your models, sounds, or whatever, and you can sell your game, if you choose, whether or not it is GPL. The GPL doesn't stop you from doing anything, so long as you adhere to the rules.
User avatar
Neddie
Community Lead
Posts: 9406
Joined: 10 Apr 2006, 05:05

Post by Neddie »

The GPL rules really need to be taken to the Supreme Court sometime so there is no doubt in our minds how they apply. They aren't explicit enough as it is - don't deny it.
User avatar
Guessmyname
Posts: 3301
Joined: 28 Apr 2005, 21:07

Post by Guessmyname »

Why don't you just release it for all to use without bothering with the GPL and just asking for credit. That's what I'd do, rather than force people who want to use my stuff into using this licence.
User avatar
Neddie
Community Lead
Posts: 9406
Joined: 10 Apr 2006, 05:05

Post by Neddie »

It is Argh's decision, that is the end of it. I do not want this thread to degenerate into a discussion of licenses. If you want to discuss them, make a new one elsewhere so we can get back to the point here.
User avatar
FLOZi
MC: Legacy & Spring 1944 Developer
Posts: 6241
Joined: 29 Apr 2005, 01:14

Post by FLOZi »

KDR_11k wrote:
Argh wrote:Static-vars and #defines are identical in actual function within the stack. There is no difference at the machine-language level.
So all literals are static vars? Why are you using literals then if you say local vars are the most efficient?
I'm also rather confused by this statement. Seen as #defines are dealt with entirely outside of COB. Care to clarify the point you are trying to make Argh? :?:
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Post by KDR_11k »

Argh wrote:As you can see, the code is actually pushing the literals into the stack instructions as they occur. If you write it with a var, then it has to go fetch the var, which requires two steps, not one. If you use a static-var, then it has to do a search to the static-vars section of the COB, return the value, and populate the memory with it.
Yes but what about #defines? That *should* replace the chunk of text before sending it off to the compiler, meaning it ends up as literals.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post by Argh »

Well, OK, but it ends up executing the same way anyhow, and it takes longer to code that way.

Here's what it looks like:

Code: Select all

#define MY_VARIABLE_A 45

piece Part;

Create()
{
	turn Part to x-axis MY_VARIABLE_A speed MY_VARIABLE_A;
}
Becomes:

Code: Select all

piece  Part;


Create()
{
	// PushConst->45.000000 StackPos 1
	// PushConst->45.000000 StackPos 2
	turn Part to x-axis <0.2> speed <0.2>;
	// StackAllocate
}
Compare with this:

Code: Select all

piece Part;

Create()
{
	turn Part to x-axis 45 speed 45;
}


Code: Select all

piece  Part;

Create()
{
	// PushConst->45.0 StackPos 1
	// PushConst->45.0 StackPos 2
	turn Part to x-axis <0.2> speed <0.2>;
	// StackAllocate
}
So I really don't see any efficiency gained here, when it actually runs. If it can make things significantly easier to write and maintain, though, I'm certainly listening. Thus far, though, I think it'd make it a lot more complicated to maintain, actually. It looks easier, because it'll do the math steps for us, but it also requires a lot more stuff be explicitly laid out in #define stages. A lot more work on setup, for minor time-savings later, when you could just as easily put a local-var speed multiplier in, test the bugger, then do the final math. It'd cut down on math errors, though.

Given that, what I'm doing is I write things the bad way first, for simplicity's sake, then I write things the good way, when I have the multiplier correct. Which is annoying.

I should probably figure out a grep method of doing all that math automatically, since I'm tragically bad even with a calculator and frequently miss errors, but meh.
Last edited by Argh on 03 Jun 2007, 22:28, edited 1 time in total.
tombom
Posts: 1933
Joined: 18 Dec 2005, 20:21

Post by tombom »

Argh did you ever explain why you expand the <>s because I'm confused about that :?
Post Reply

Return to “Game Development”