Author Topic: Collision sphere?  (Read 2445 times)

0 Members and 1 Guest are viewing this topic.

Offline Alan Bolte

  • 28
  • Deneb III
    • @Compellor
I'm trying to create an invisible sphere that causes damage to any ships that pass through it (I can just overlay visual effects later). Ideally, this sphere would also take damage from explosions (haven't decided about shockwaves) which intersect with it. Were you to target this sphere with a flack gun or missiles, they should explode inside the sphere, not on the surface. Primaries should pass through harmlessly; not sure about beams.

I can't quite work out how to do the collision detection. I think I could use the $On Frame hook with getDistance(), model radius, and checkRayCollision() to create collision detection, but aside from how much work that would be I'm concerned that it would be very slow in Lua, especially if I'm calling it for dozens of spheres at a time. I don't think I could use the $On Weapon Collision hook because as far as I can tell weapons are treated as line segments rather than spheres or meshes. $On Ship Collision might work if I created a ship .pof that was an invisible polysphere, but aside from just generally being inefficient and reducing the number of ships you can have in a mission, I haven't seen any examples of that hook in use so I don't really know if what I want to do will work.

Also, to determine how much damage to do and generate visual effects, I need the exact time or a close estimation (between frames) that the ship entered the collision sphere, and the ship's position (or a close estimate) when it did so.

Is there some simpler method that I'm not seeing? Aside from learning how to write C++ well enough to write a patch worth committing, I mean.
Anything worth doing is worth analyzing to death -Iranon

 

Offline zookeeper

  • *knock knock* Who's there? Poe. Poe who?
  • 210
Well, all that is pretty complicated so I wouldn't have high hopes of finding a method I'd call simple.

I'm trying to create an invisible sphere that causes damage to any ships that pass through it (I can just overlay visual effects later). Ideally, this sphere would also take damage from explosions (haven't decided about shockwaves) which intersect with it. Were you to target this sphere with a flack gun or missiles, they should explode inside the sphere, not on the surface. Primaries should pass through harmlessly; not sure about beams.

I can't quite work out how to do the collision detection. I think I could use the $On Frame hook with getDistance(), model radius, and checkRayCollision() to create collision detection, but aside from how much work that would be I'm concerned that it would be very slow in Lua, especially if I'm calling it for dozens of spheres at a time. I don't think I could use the $On Weapon Collision hook because as far as I can tell weapons are treated as line segments rather than spheres or meshes. $On Ship Collision might work if I created a ship .pof that was an invisible polysphere, but aside from just generally being inefficient and reducing the number of ships you can have in a mission, I haven't seen any examples of that hook in use so I don't really know if what I want to do will work.

I can't really tell how much of a performance impact that would have, but it should be pretty straightforward to test. Just use an $On Frame hook to iterate through every ship and weapon in the mission and check if their distance to each sphere is less than the sphere's radius, and time it to see how many milliseconds it takes each turn when there's a healthy number of ships and weapons flying around. It's probably a meaningless amount of time for one or two spheres, but of course it might not be so if there's dozens of them. Still, that's something I'd check out first.

Also, to determine how much damage to do and generate visual effects, I need the exact time or a close estimation (between frames) that the ship entered the collision sphere, and the ship's position (or a close estimate) when it did so.

When you detect a collision, it seems like you could calculate the time and place with the colliding object's current position and velocity (and if necessary, its position last frame using object.LastPosition) and the sphere's position and radius. I wouldn't know how exactly to do the math, but it seems entirely feasible and very likely accurate enough.

And if it's invisible anyway, then do you really need a more exact time and place for when a ship entered the sphere? With FS2-like ship speeds the margin of error would probably be just a couple of meters even on low'ish fps, if you simply used the time and place of the first time you detect the ship to be inside the sphere. Maybe you really do need more precision, but better make sure that you do before writing such a system.

 

Offline The E

  • He's Ebeneezer Goode
  • 213
  • Nothing personal, just tech support.
    • Steam
    • Twitter
Quote
I can't really tell how much of a performance impact that would have, but it should be pretty straightforward to test. Just use an $On Frame hook to iterate through every ship and weapon in the mission and check if their distance to each sphere is less than the sphere's radius, and time it to see how many milliseconds it takes each turn when there's a healthy number of ships and weapons flying around. It's probably a meaningless amount of time for one or two spheres, but of course it might not be so if there's dozens of them. Still, that's something I'd check out first.

Welcome to the world of O(n^2) algorithms. In that particular case, it wouldn't be the checks themselves that would be expensive, but rather going through both the Ships and Weapons lists, and then comparing each object with each other object. Table access in lua is rather slow, throwing in an n^2 algorithm to walk across them (with an n that can easily go into the hundreds) will be a major pain.
If I'm just aching this can't go on
I came from chasing dreams to feel alone
There must be changes, miss to feel strong
I really need lifе to touch me
--Evergrey, Where August Mourns

 

Offline Alan Bolte

  • 28
  • Deneb III
    • @Compellor
Well, all that is pretty complicated so I wouldn't have high hopes of finding a method I'd call simple.
Yeah, but even if all I had was a way to take a ship and tell it to use sphere vs mesh instead of mesh vs mesh in collision with ships, asteroids, and debris, then that'd be a vast improvement.
Quote
And if it's invisible anyway, then do you really need a more exact time and place for when a ship entered the sphere? With FS2-like ship speeds the margin of error would probably be just a couple of meters even on low'ish fps, if you simply used the time and place of the first time you detect the ship to be inside the sphere. Maybe you really do need more precision, but better make sure that you do before writing such a system.
It's only invisible for the purpose of this script, I'd pass some data onto another script, or a later part of the script, to generate the visuals. I hope to eventually get this working in multiplayer, so my concern was that a ship that was (as you more or less figured out) lagging badly and traveling very quickly might simply blink through all or most of the sphere without taking damage. On the other hand, now that I've bothered to do the math, it probably would take some really extraordinary situation to make a noticeable or exploitable difference, so I guess that's not much of a concern.

As to The E, thanks for responding, I think I'll start by seeing if I can get $On Ship Collision working.
Anything worth doing is worth analyzing to death -Iranon

 

Offline Alan Bolte

  • 28
  • Deneb III
    • @Compellor
$On Ship Coliison +Override doesn't work for this since it only overrides the collision damage, not the physics. Looks I'd have to learn C++ to get this working efficiently.
Anything worth doing is worth analyzing to death -Iranon

 

Offline Cyborg17

  • 29
  • Life? Don't talk to me about life....
Wouldn't a Freding solution be simpler?  Even if you have multiple spheres you could use when-argument and everytime-argument to set it up.

Do you mean that you want the ship to take damage as it crosses the effect mesh threshold?  Or when they are within the mesh?

Either way, you might still be able to jury-rig a solution without resorting to large code changes.  It all depends on what ships you plan to put through this thing.

For the more complicated possibility, fighters and bombers should be just fine because you can set up a distance is less than x radius and greater than y radius event to check when they are crossing the threshold.  But if you want let Cruisers go through, then it could get hairy.  Destroyers might be impossible.

But, if the radius is say a hundred meters, and you wanted to send a cruiser through, you could check the subsystem distances instead of the ship distance.  But I would definitely set up a separate event for each cruiser class object.

I had a lot of useless crap about how to edit the pof's so that the SEXPs would work out, if you want to hear it, let me know.  I maybe asleep when you respond, though.

tl;dr: I think you can probably do this without resorting to collision detection.

 

Offline Alan Bolte

  • 28
  • Deneb III
    • @Compellor
Destroyers etc. were exactly why I wasn't going to use SEXPs. I want to be able to just throw any existing ship into a mission and have it start taking damage if part of it is passing through this sphere. A few meters either way isn't going to bother me, but if I have 90m of featureless, subsystem-less destroyer hull moving through a player-dropped 100m radius minefield without taking damage or having visual effects applied, then that's just not going to work.

I don't know what you're talking about with editing POFs for the purpose, could you elaborate?
Anything worth doing is worth analyzing to death -Iranon

 

Offline Cyborg17

  • 29
  • Life? Don't talk to me about life....
It's not useful information since you're going to solve it using scripting.  If you weren't going to use scripting, then it would have been really hard to get all the requirements you wanted with just one Mesh.  (i.e. How do you make it transparent and still make it able to take damage from missles and flak.)  I was just going to suggest using two meshes with different properties.

Actually, one thing I didn't think of earlier was that you could probably add dummy subsystems in PCS2 to a destroyer so that you can check whether the ship is supposed to be damaged across more areas.  It would be a lot of work if you plan on being able to check multiple destroyer classes, but it maybe less work than learning C++.

You would just have to add the "untargetable" flag in the table as a subsystem flag and put their hitpoints at 0 (so they won't be destroyed) for each of the dummy systems and the player won't know the difference.

Your choice to try it. I don't know which is easier to do.