This is a multi-part message in MIME format.
--
[ Picked text/plain from multipart/alternative ]
This is my first post on here so go easy on me :). I tried looking through the
archives for a similar discussion on this but didn't find anything...
First let me try to give an abstract,
I've created a weapon that will need to rotate the impact decal it makes on
entities from case to case. I have run into the problem that there's no way of
telling the engine to paint the impact decal with a given rotation. Well ok,
the engine will happily paint a decal with a rotation, the problem is the
process the game uses to add an effect doesn't take rotation into account at
all! I see two solutions so far: A hackish rewrite involving a lot of
duplicate code to pass the rotation value through the normal impact effect
process, or a shorter rewrite (with minimal duplicate code) that makes a direct
call to the engine as quickly as possible. I'm wondering if there's a way to
do this without the hack'ish rewrites, or skipping the process that's already
set up. Or if everyone's in agreement that I'll need to do one of the two
former ways. Or at least a i'm looking for some explanation of why i shouldn't
try to shorten the code between the weapon hit and the engine call (since I
know there's gotta be a reason for the process and shortening it could cause
problems).
Ok, now with some code...
First off, here's the engine call to paint a decal:
DecalShoot( int textureIndex, int entity, const model_t *model, const Vector&
model_origin,
const QAngle& model_angles, const Vector& position, const
Vector *saxis, int flags) = 0;
The main thing to note is the Vector *saxis, that will rotate the decal and
works fine. The problem is out of every call ever made with this from the
game, all but 2 pass 0 as the rotation value! (The two exceptions are the left
and right footprint decal calls). Obviously I'm not going to be able to rely
on the existing engine calls if i want to rotate a decal.
Ok, but something tells me that I *will* need to rely on the process of
creating impact decals. Take a look at the call stack when it tries to paint a
decal to a brush entity, client-side:
* C_BaseAOCBludgeonWeapon::Hit(...) <-- Here's my weapon
code where I just hit a wall and would determine the decal rotation
* C_BaseAOCBludgeonWeapon::ImpactEffect(...) <-- (Actually, i could
have it here too, either way)
* UTIL_ImpactTrace(...)
* C_BaseEntity::ImpactTrace(...)
* DispatchEffect(...)
* C_TempEntsSystem::DispatchEffect(...)
* TE_DispatchEffect(...) <-- Here is where the
client/server break would be if client didn't make the effect
* DispatchEffectToCallback(...)
* ImpactCallback(...)
* Impact(...)
* C_BaseEntity::AddDecal(...)
* C_BaseEntity::AddBrushModelDecal(...) <-- Here is where the
actual engine call is made, and passes 0 as the rotation variable
That's a lot of jumps! My main conundrum is getting a rotation value from the
top of that list to the bottom (sorry, I should probably rewrite the call stack
going the other way as it's inverted, the IP would be the bottom line). NONE
of those calls pass a rotation value along There's also no passed object I can
sneak it into, since at the very least that would get lost when it hits the
client/server messaging system. So, my first solution (the hackish rewrite)
would be something like this:
* C_BaseAOCBludgeonWeapon::Hit(...)
* C_BaseAOCBludgeonWeapon::ImpactEffect(..., Vector *saxis) <-- Pass
the rotaton along
* UTIL_ImpactTrace(..., Vector *saxis)
<-- Pass the rotaton along
* C_BaseEntity::ImpactTrace(..., Vector *saxis)
<-- Pass the rotaton along
etc...
ie. Just make a clone of all those calls with an extra Vector passed through
(and of course add it to the messaging across client/server). It would
certainly work, but just feels like a bad way of doing it. Copy, paste, add
the variable. Copy, paste, add the variable, etc. I guess if it were only 1
or 2 functions it was going through it would seem like a better option.
The other option would be a more direct route, trying to get to the engine call
as soon as possible. Now that I think about it though, this probably isn't a
good idea, since we're going to have to put it through the messaging system
anyway, might as well not walk around all the impact code. But just for
reference, my idea would be to shorten the chain to something like this (with
better func names than "MyDecal" of course):
* C_BaseAOCBludgeonWeapon::ImpactEffect(..., Vector *saxis) <-- first spot
where we get the rotation
* TE_DispatchMyDecal(..., Vector *saxis) <--
client/server split, custom function
* DispatchEffectToCallback(...)
<-- client picking the msg up, same function with my callback added
* MyDecalCallback(..., Vector *saxis)
<-- the callback, custom function
* effects->DecalShoot(...)
<-- the engine has it now with the rotation
I would put necessary code into those functions that are needed (like probably
recreating a CEffectData object, figuring out the decal index, etc). I haven't
looked at it closely enough, and that's the problem with this idea. It doesn't
overload a bunch of functions, but it's still a hackish rewrite in that I'm
going from the weapon hitting to the decal being drawn in a lot fewer steps.
There's a lot of ray traces and, i mean, even the big "Impact()" gets called to
draw a decal that we already know where to draw. In other words, I'm not
familiar enough with why we're doing all this extra stuff before drawing a
decal, and so I don't think it's a good idea to just shun it all and print a
decal as soon as we know where to. Can anyone give me an idea how this would
be a problem? My only guess is it's trying to account for network issues
somehow, but even then, shouldn't the server be always right in that case?
Anyway, I hope that was descriptive enough to explain my trouble. In short: my
weapon code determines the decal rotation, and that rotation value needs to
make it to the engine call. I think the first way of doing it will be the
best, but it just feels like a bad habit to be overloading all those functions
for one single gain. Maybe there's a better way about this (or a method I
don't know about) for rotating a decal...
Thanks for listening, I'm open to any ideas
-Matt
--
_______________________________________________
To unsubscribe, edit your list preferences, or view the list archives, please
visit:
http://list.valvesoftware.com/mailman/listinfo/hlcoders