Sign in to follow this  
arithma

Space Ship Trails [NEW INFO ABOUT QUESTION]

Recommended Posts

arithma    226
I have this space ship that should produce a trail behind it. The trail is a single curve, a list of points. I don't want to insert a new point for each frame of the game, instead I want it to be something adaptive perhaps. Insert a point when it's needed kinda style. I think it has to do with the curvature of the path. But further than that, am blanked out. Another subproblem is with the initial points of the curve, and when they should be placed. The first point of course is the initial position of the ship. But the placement of the second point could be very crucial to the points coming afterwards. So far am considering some ad hoc methods that came to mind, like crossing previous segment with the current segment, and not inserting a point until a certain threshold, but perhaps there are constants to consider or something, so am still unsure. I don't want to try something that's gonna fail directly.. [Edited by - arithma on May 9, 2007 12:16:16 AM]

Share this post


Link to post
Share on other sites
geolycosa    217
I would record the position of the ship every few ticks, and build my trail from that. It's probably not as expensive as you think.

Share this post


Link to post
Share on other sites
Dan_    139
You could have the ship drop particles after a certain amount of time. After X amount of time has expired create a new particle at the current position of the ship (or the position of it's engine). When the ship moves particles blend together to form a trail. You could use a fixed amount of particles so that when you run out of particles you kill the oldest particle (at the back of the trail) and place it at the front of the trail (at the engine/ship position).

One drawback to this approach however, is that if the ship moves very fast, then the particles become more spaced so they fail to blend and the trail looks choppy although you could have more particles emitted when the ship is moving fast than when it is moving slowly.

Share this post


Link to post
Share on other sites
TheAdmiral    1122
Quote:
Original post by geolycosa
I would record the position of the ship every few ticks, and build my trail from that. It's probably not as expensive as you think.

You're right about the method and the performance. I'm not so sure that 'every few ticks' is good advice.

I did something similar not too long ago, and was quite displeased with the idea of recording the positions of several entities at 30fps. But when I profiled it running for two minutes, it turned out to be the least of my worries.

You could compare the current position against the last recorded position, and use it only when a certain distance has been traversed, but this would be shifting the load from RAM-consumption (abundant) to CPU-time (far more valuable). Extending the method to form variable-length segments according to curvature, as clever as it may seem, is veritable frame-rate-icide.

If you consider that recording three floats thirty times per second takes 360 bytes per second (a second is quite a long time), there's really nothing to worry about. You could even up that to 60Hz if you like.

Admiral

Share this post


Link to post
Share on other sites
geolycosa    217
I think we're talking about the same thing here. By 'every few ticks' I simply meant that you could save your position at a lower frequency than your frame rate if you were really concerned about ram usage.

Share this post


Link to post
Share on other sites
arithma    226
The thing is: the trail is a game element. I will have to do collision detection against every segment in the trail with a sphere.
In light of this new information, is this still premature optimization?

If the ship moves in a straight path for like a second, it would create a single segment instead of at least 30 segments (and at maximum 80 at the moment). I'd really prefer collision detection against the optimized version.

Share this post


Link to post
Share on other sites
hoLogramm    170
You could use some sort of rubberband solution here.

Store segments in your list which contain the origin and the direction(needs to be normalized). The last segment in this list represents your moving object.

If the dot product of the directions of segment N and segment N-1 is not 1-threshold anymore, insert a new segment.

In the initial case you have two segments. The first segment is the initial pose of your object and the second is the current pose (identical of course in the beginning).


h.

Share this post


Link to post
Share on other sites
Quote:
Original post by arithma
The thing is: the trail is a game element. I will have to do collision detection against every segment in the trail with a sphere.
In light of this new information, is this still premature optimization?

If the ship moves in a straight path for like a second, it would create a single segment instead of at least 30 segments (and at maximum 80 at the moment). I'd really prefer collision detection against the optimized version.



In that case, maybe Not optimizing is a good thing.

If you do optimize, then the number of segments will be smaller for straighter paths. Won't this mean that when colliding with the trail, straighter paths will do less damage than curved ones? Having the brute force method of always adding a new point to the trail each frame also accounts for the trail density caused by ship speed.

Share this post


Link to post
Share on other sites
arithma    226
Quote:
Original post by haphazardlynamed
Quote:
Original post by arithma
The thing is: the trail is a game element. I will have to do collision detection against every segment in the trail with a sphere.
In light of this new information, is this still premature optimization?

If the ship moves in a straight path for like a second, it would create a single segment instead of at least 30 segments (and at maximum 80 at the moment). I'd really prefer collision detection against the optimized version.



In that case, maybe Not optimizing is a good thing.

If you do optimize, then the number of segments will be smaller for straighter paths. Won't this mean that when colliding with the trail, straighter paths will do less damage than curved ones? Having the brute force method of always adding a new point to the trail each frame also accounts for the trail density caused by ship speed.


I know I haven't provided this info yet, but the trail will be instant kill (think TRON), so trail density isn't a real consideration. Still though, I believe recording ship velocity at key points can provide trail density in some kind of matter.

Am not gonna go brute force style because I believe it will be wasted effort and I'll eventually have to optimize, unless someone bashes otherwise into my skull.

The method I'll use is recording position and velocity of ship at each point.
If either distance or curvature exceeds a limit, a point will be created... For now, I'll implement distance. I still find the curvature thing a bit fuzzy even with hoLogramm's method.

Share this post


Link to post
Share on other sites
OrangyTang    1298
Quote:
Original post by arithma
Am not gonna go brute force style because I believe it will be wasted effort and I'll eventually have to optimize, unless someone bashes otherwise into my skull.

The method I'll use is recording position and velocity of ship at each point.
If either distance or curvature exceeds a limit, a point will be created... For now, I'll implement distance. I still find the curvature thing a bit fuzzy even with hoLogramm's method.

It is almost always easier to get something simple that works done first, then optimise that rather than going from scratch to a complete optimised version.

In your case it's easy - you can do your basic implementation with a shouldCreateNewPoint(oldPoint, newPosition) which returns true if some tolerance (curvature/distance) is exceeded. To start with you just stub the function out with something which always returns true. You can then implement all the other bits and have a brute force version working which has a new point every frame.

Then you can start worrying about the exact implementation of shouldCreateNewPoint() - a simple change would be every X frames rather than every frame, but you could start taking into account distance or curvature if you want. And you can do that safe in the knowledge that the rest of the implementation already works and is bug free.

Share this post


Link to post
Share on other sites
Fingers_    410
The way traditional "worm" games work is they record the position each time the player moves. Typically you'd use a circular buffer whose size is determined by the maximum length. In really old-school implementations you'd only need to render in two places (adding a new block at the "head", removing a block at the "tail" each frame).

Some years ago I wrote a worm game with 360-degree smooth movement, using the same principle except it kept track of how much distance was covered by each frame in addition to recording the position. When rendering I'd start from the newest position (head) and continue down toward the tail, accumulating the frame distances into a variable that was used to determine when to draw another segment of the worm (e.g. If the player was moving one pixel/frame and the segments were ten pixels long, it'd draw a worm segment once every ten locations in the buffer). This worked rather well even on low-end machines.

You can get the demo of my old game here: http://www.digital-eel.com/plasmaworm/

In a 3D implementation, I'd probably make the ship leave behind a spherical "trail particle" each time it has moved outside the radius of the previous particle. This'd give you a solid line of particles so you could just do sphere-sphere collisions instead of having to deal with segments at all. The trail could of course be rendered as a billboard strip connecting each particle to the next one. The performance will probably be limited by fillrate rather than geometry, so unless you have tens of thousands of polygons in the trail you shouldn't bother with micro-optimizations like reducing segments along straights.

Share this post


Link to post
Share on other sites
hoLogramm    170
Quote:

.... I still find the curvature thing a bit fuzzy even with hoLogramm's method.


Don't worry. I added my rubberband derivative to my engine to show you how it would look and the simple implementation speaks for itself. The segments are billboards rendered with quad strips.

Rubberband segments


[EDIT]
Forgot to show you the initialisation:
boost::shared_ptr<OVGeometry> initLine(new OVGeometry(OVGeometry::POLYLINE_OPEN));
m_Line = initLine;

m_Line->m_VertexList.push_back( Camera1->m_World.getTranslate() );
m_Line->m_VertexList.push_back( Camera1->m_World.getTranslate() );
[/EDIT]

// in the update section:
m_Line->m_VertexList.back() = Camera1->m_World.getTranslate();
OVVector3<float> Direction = (m_Line->m_VertexList.back() - m_Line->m_VertexList[m_Line->m_VertexList.size()-2]).normalise();

// Direction length should be 1
// if not, don't add segments because we are standing still
if(Direction.squareLength() > 0.5f)
{
float Dot = OVMath<float>::absolute(Direction.dot(Camera1->getWorldView()));
if( Dot < 0.999f )
{
m_Line->m_VertexList.push_back(Camera1->m_World.getTranslate());
}
}
}


The good thing about this method is, that the line will always end at the objects current position (recording positions every few frames gives you a hole behind the object and the line) and records fast orientation changes giving details, where they are needed.

h.

[Edited by - hoLogramm on May 10, 2007 8:52:17 AM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this