HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Smooth Flying System (AKA nice projectile system)

08-23-2007, 04:09 AM#1
moyack
Hi guys:

One of the features that I'm implementing in my project is a projectile system, so I did a trivial one which allowed me to simulate parabolic movement, and it was nice.

But then, Mad[Lion] posted a problem related with movement, and I developed a solution for him. Unfortunately I think he decided not to use, so I tested to see how it behaves, and believe me, it works more fantastic than I expected.

Features:
  • Vector based (vector struct included)
  • Scriptable projectile start and end (AKA custom events when the projectile starts and ends)
  • Smooth movement and highly decent performance with large number of instances.

EDIT: test map and code removed. kthanksbai
08-23-2007, 06:01 AM#2
Av3n
I'll check it out

-Av3n

EDIT: This is pretty neat and smooth it taught me a few things about how to effectively use structs as well. One thing in the test map is to make the projectile units unselectable?
08-23-2007, 06:16 AM#3
cohadar
Very nice indeed.

Some suggestions:
* You don't need Start function, this function is always called when the projectile is started.
* Instead of using HandleVars, use global struct array, it will be faster
* Instead using simple callback for End function make an interface function
that takes your movement struct as an argument, pass that interface as parameter to projectile and call it on end of projectile movement with evaluate()

Collapse JASS:
//callback interface
//==============================================================================
function interface EndOfImpulse takes ImpulseData data returns nothing

// call this on end of your movement [b]before[/b] destroying structs
//==============================================================================
            if data.callback != null then
                call EndOfImpulse(data.callback).evaluate(data)
            endif


Final note:
If you make this with Collections it takes 3 times less code and is faster.
08-23-2007, 07:41 AM#4
MaD[Lion]
ur method may work, but it was just futher derivation of acceleration, didnt really see how to implement tat until now. But i talked to Anitarf and his method was more simple, and doesnt give much noticable differents. Also his method require less calculation therefore higher performance. So credit goes to him here.

About your system i havent checked yet, but i think its good :) The first thing i see tat is not so nice is the use of function calls. But its alright as long as its not in periodic.

And also 12.5 projectiles is not much :/ Try increasing it more by inlining to make it faster. My system can run about 160 projectiles without lag, 200 without lag on my comp. But tats also only projectiles. And i got tat far by inlining. If u remember the first version i made only support 12 projectiles
08-23-2007, 12:47 PM#5
moyack
Quote:
Originally Posted by Av3n
EDIT: This is pretty neat and smooth it taught me a few things about how to effectively use structs as well. One thing in the test map is to make the projectile units unselectable?
I make it selectable and selected by purpose :)

If you make click on the sheep avatar and keep pressed the mouse button, the camera will follow any of the flying sheeps, so you see how smooth the projectiles move.


Quote:
Originally Posted by cohadar
Some suggestions:
* You don't need Start function, this function is always called when the projectile is started.
* Instead of using HandleVars, use global struct array, it will be faster
* Instead using simple callback for End function make an interface function
that takes your movement struct as an argument, pass that interface as parameter to projectile and call it on end of projectile movement with evaluate()
The idea with the start and final function is to make them optional, only you use them if you really want to configure something. With this system, it's not necessary to set these scripts, but they are really convenient to apply effects. In my example, I use the start script to add the fire effect to the sheep and link it with a struct to call it later, and the final script calls the effect struct, destroys the effect and kills the sheep. With that I want to show how convenient is the custom events feature. Of course you use your ABC system to replace the gamacache method.

About the interface function, I'm afraid that I'm not familiar with them (honestly I haven't needed to use them), I have to ask how it works and what advantages they have.

Now that I notice, I have to add a protection if you don't set the custom scripts. I'll fix it this night.

Quote:
Originally Posted by MaD[Lion
]ur method may work, but it was just futher derivation of acceleration, didnt really see how to implement tat until now. But i talked to Anitarf and his method was more simple, and doesnt give much noticable differents. Also his method require less calculation therefore higher performance. So credit goes to him here.

About your system i havent checked yet, but i think its good :) The first thing i see tat is not so nice is the use of function calls. But its alright as long as its not in periodic.

And also 12.5 projectiles is not much :/ Try increasing it more by inlining to make it faster. My system can run about 160 projectiles without lag, 200 without lag on my comp. But tats also only projectiles. And i got tat far by inlining. If u remember the first version i made only support 12 projectiles
My method may not work, it really works :)

The advantage wit my system is that you can achieve complex movements easily and reliably. About the credits, they goes for you and me, you because you proposed the problem and if you wouldn't have posted that problem, this system wouldn't exist, and me because I modeled it. Besides, my approach to the problem is totally different to Anitarf's solution.

If we have a production rate of 12.5 units per second, and if the last for 10 seconds, then we could have in the test map 125 flying burning sheep moving around the terrain. You can change the periodic data to a 0.02 and you will have too much units to see.


Thannks for your comments and help, I'll await for more comments.
08-23-2007, 04:50 PM#6
grim001
You should make use of interfaces to hold configuration variables for object types and their events. Then you could create a user friendly front end. It would look something like this

Collapse JASS:
struct MyProjectile extends projectiledata
 real MaxH = 250.
 real MinH = 0.
 real MaxS = 1500.  //configure everything about this kind of projectile here
 real MaxD = 2500.
 string FX = "Abilities\\Weapons\\FireBallMissile\\FireBallMissile.mdl"
 real dt = 0.4

 method onStart takes projectile p returns nothing
  //onstart code for this kind of projectile here
 endmethod

 method onEnd takes projectile p returns nothing
  //onend code for this kind of projectile here
 endmethod
endstruct

You don't need to use any kind of system or gamecache for this, just loop through a global array of structs. It will be much faster and remove dependency on any outside system.
08-23-2007, 05:31 PM#7
PipeDream
You don't seem to have noticed, but we derived the same solution to this problem, through opposite directions =)
I'm really surprised that the inverse matrix has such a simple structure, I was expecting a horrific mess. No subtraction means I can believe you that this actually works well.

You can evaluate polynomials faster by partial factoring:
Collapse JASS:
    return A*t*t*t + B*t*t + C*t + D
//becomes
    return D + t*(C + t*(B + t*A))
and similarly for your more complex expressions
08-23-2007, 05:46 PM#8
cohadar
Quote:
Originally Posted by moyack
Of course you use your ABC system to replace the gamacache method.

I was talking about Collections not about ABC,
a.k.a what grim001 said: looping through a global array.

It is much more reliable and faster than using attachments of any kind.
(You can see this in ABC4.6 demo map, you can test attachments vs global array
and see that attachments support up to 70 moving objects before start to lag
while border for global arrays is 150 [slide vs glide spell])

*After realizing that ABC test had old collections v1.3
I decided to test with Cool v2.1, it supports up to 200 moving units without lag.
And that is without ANY optimizations.
Global arrays kick ass.


EDIT:

When you post systems please put the whole system code in a JASS tag (preferably hidden)
so we don't have to open your map every time we want to comment on something.
08-23-2007, 06:26 PM#9
chobibo
Hi! I've tested this and i think its really good, the sheeps really move smoothly.
08-24-2007, 01:34 AM#10
moyack
Quote:
Originally Posted by grim001
You should make use of interfaces to hold configuration variables for object types and their events. Then you could create a user friendly front end. It would look something like this

Collapse JASS:
struct MyProjectile extends projectiledata
 real MaxH = 250.
 real MinH = 0.
 real MaxS = 1500.  //configure everything about this kind of projectile here
 real MaxD = 2500.
 string FX = "Abilities\\Weapons\\FireBallMissile\\FireBallMissile.mdl"
 real dt = 0.4

 method onStart takes projectile p returns nothing
  //onstart code for this kind of projectile here
 endmethod

 method onEnd takes projectile p returns nothing
  //onend code for this kind of projectile here
 endmethod
endstruct

You don't need to use any kind of system or gamecache for this, just loop through a global array of structs. It will be much faster and remove dependency on any outside system.
The code that I'm showing in the first post is for testing the library, so I think it's not necessary to add interfaces and all that stuff, it could make messy the understanding of this library. Just to be sure, I edited the first post, so you can see the library code instead.

Quote:
Originally Posted by PipeDream
You don't seem to have noticed, but we derived the same solution to this problem, through opposite directions =)
I'm really surprised that the inverse matrix has such a simple structure, I was expecting a horrific mess. No subtraction means I can believe you that this actually works well.

You can evaluate polynomials faster by partial factoring:
Collapse JASS:
    return A*t*t*t + B*t*t + C*t + D
//becomes
    return D + t*(C + t*(B + t*A))
and similarly for your more complex expressions
LOL yes!!! XD

I worked at the university with your matrix approach, and yes, in some way I thought the same about how would look the model in the "normal way".

Thanks for the partial factoring notation, it's very helpful and efficient :) I'm giving credits to you for that.

Quote:
Originally Posted by cohadar
When you post systems please put the whole system code in a JASS tag (preferably hidden)
so we don't have to open your map every time we want to comment on something.
You lazy!!! check the first post.

Quote:
Originally Posted by chobibo
Hi! I've tested this and i think its really good, the sheeps really move smoothly.
I'm glad you like it :)

I'll try to update the map with the new library version, but you can see the updated code in the first post. I'll add some documentation later.
08-24-2007, 02:19 AM#11
grim001
I meant if you intend to make this into a system for use rather than a tech demo it could use an interface front-end.
08-24-2007, 07:34 AM#12
cohadar
And good comments in code.

PS: structs should begin with uppercase letters: Vector, not vector
08-24-2007, 10:19 AM#13
Toadcop
btw =\ Vector as structure is almost useless... cause you can simply use 3 global arrays or 3 vars to transfer needed vec data. but i dunno maybe you like it =)
08-24-2007, 11:39 AM#14
cohadar
Vector is not a structure it is actually a class,
(it has methods for vector manipulation)

Encapsulation is never useless.
And optimization in 90% of cases I have seen people use it is pointless.
08-24-2007, 03:27 PM#15
MaD[Lion]
vector as struct make some place simple to write. example in an object u can write:

vector V

instead of

real Vx
real Vy
real Vz