Raised This Month: $51 Target: $400
 12% 

Rocket Bounce Sphere Surface


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Skippy
Senior Member
Join Date: Nov 2011
Old 01-15-2014 , 19:37   Rocket Bounce Sphere Surface
Reply With Quote #1

I have this Sphere that I created and I want rockets to reflect off of the surface of the sphere. The thing is I can't use on start touch with the rocket and have it reflect off because there isn't technically a surface. But what I coded is when the rocket gets within the sphere radius then do the reflect but it doesn't reflect properly. (I literally just copied and pasted the code from Rocket Bounce)

PHP Code:
public Action:Timer_Rocket(Handle:timerany:entref)
{
    new 
entity EntRefToEntIndex(entref);
    
    if(
IsValidEntity(entity))
    {
        
decl Float:vOrigin[3];
        
GetEntPropVector(entityProp_Data"m_vecOrigin"vOrigin);
    
        
decl Float:vAngles[3];
        
GetEntPropVector(entityProp_Data"m_angRotation"vAngles);
    
        
decl Float:vVelocity[3];
        
GetEntPropVector(entityProp_Data"m_vecAbsVelocity"vVelocity);
    
        new 
Handle:trace TR_TraceRayFilterEx(vOriginvAnglesMASK_SHOTRayType_InfiniteTEF_ExcludeEntityentity);
    
        if(!
TR_DidHit(trace))
        {
            
CloseHandle(trace);
            return 
Plugin_Continue;
        }
    
        
decl Float:vNormal[3];
        
TR_GetPlaneNormal(tracevNormal);
    
        
CloseHandle(trace);
    
        new 
Float:dotProduct GetVectorDotProduct(vNormalvVelocity);
    
        
ScaleVector(vNormaldotProduct);
        
ScaleVector(vNormal2.0);
    
        
decl Float:vBounceVec[3];
        
SubtractVectors(vVelocityvNormalvBounceVec);
    
        
decl Float:vNewAngles[3];
        
GetVectorAngles(vBounceVecvNewAngles);
        
        if(
GetVectorDistance(coordvOrigin) < sphereRadius 5.0//Hitting Sphere
        
{
            
TeleportEntity(entityNULL_VECTORvNewAnglesvBounceVec);
        }    
    }
    return 
Plugin_Continue;

__________________
Plugins:
[Any] Aim Menu

Want a TF2 plugin? Feel free to pm me to discuss it.

Last edited by Skippy; 01-15-2014 at 19:39.
Skippy is offline
xf117
Senior Member
Join Date: Mar 2010
Location: Russia
Old 01-16-2014 , 04:58   Re: Rocket Bounce Sphere Surface
Reply With Quote #2

Since it's a sphere, you can just compare distances between rocket and sphere center onTimer. Once the distance is closer than sphere's radius - invert rocket direction (teleport with opposite angles + some accuracy penalty).
xf117 is offline
Send a message via ICQ to xf117
MikeJS
Senior Member
Join Date: Nov 2008
Old 01-16-2014 , 06:52   Re: Rocket Bounce Sphere Surface
Reply With Quote #3

I don't think the normal from TR_GetPlaneNormal is the sphere normal you want. You are going to have to implement the intersection code yourself.

Do your checks in a think function rather than a timer so you can get 1/66s resolution rather than 1/10s if you want it to be more accurate.

I've written an outline of what it should look like. Note there are some gaps which will depend on the specifics of your code and it's fully not tested.

EDIT: I think IntersectSegmentSphere might be incorrect but I have to go to class in 5 minutes. I'll check in a bit
EDIT2: should be ok now. still untested

(LOL I got quite carried away. add me on steam or something if you want me to explain this)

Code:
#define BOUNCE_LIMIT 5 new Handle:lastPosArray; // = CreateArray( ... ) new Handle:spheres; // = CreateArray( 4 ) Float:IntersectSegmentSphere( const Float:start[ 3 ], const Float:end[ 3 ], const Float:centre[ 3 ], const Float:radius ) {     decl Float:d[ 3 ]; // holds the segment between start and end     decl Float:m[ 3 ]; // holds the segment between start and centre     SubtractVectors( end, start, d );     SubtractVectors( centre, start, m );     new Float:b = GetVectorDotProduct( m, d );     new const Float:c = GetVectorDotProduct( m, m ) - radius * radius;     // if c > 0.0, |m| > r ie we are starting outside the sphere     // if b <= 0.0, d . m < 0.0 ie we are not looking anywhere near the sphere     if( c > 0.0 && b <= 0.0 ) {         return -1.0;     }     new const Float:mag = GetVectorLength( d );     b /= mag;     new const Float:disc = b * b - c;     // did we miss the sphere?     if( disc < 0.0 ) {         return -1.0;     }     return b - SquareRoot( disc ); } // result = |v|( v' - 2(v'.n)n ), v' = v / |v| ReflectVector( const Float:vec[ 3 ], const Float:normal[ 3 ], Float:result[ 3 ] ) {     decl Float:vHat[ 3 ];     NormalizeVector( vec, vHat );     new const Float:dot = GetVectorDotProduct( normal, vHat );     new const Float:mag = GetVectorLength( vec );     ScaleVector( vHat, 2 * dot );     SubtractVectors( vec, vHat, result );     ScaleVector( result, mag ); } SphereNormalAt( const Float:centre[ 3 ], const Float:radius, const Float:pos[ 3 ], Float:result[ 3 ] ) {     SubtractVectors( pos, centre, result );     ScaleVector( result, 1.0 / radius ); } LerpVectors( const Float:vec1[ 3 ], const Float:vec2[ 3 ], const Float:t, Float:result[ 3 ] ) {     decl Float:d[ 3 ];     SubtractVectors( vec2, vec1, d );     ScaleVector( d, t );     AddVectors( vec1, d, result ); } CopyVector( const Float:vec[ 3 ], Float:result[ 3 ] ) {     result[ 0 ] = vec[ 0 ];     result[ 1 ] = vec[ 1 ];     result[ 2 ] = vec[ 2 ]; } AddDelta( const Float:vec1[ 3 ], const Float:d[ 3 ], Float:result[ 3 ] ) {     decl Float:delta[ 3 ]     NormalizeVector( d, delta );     ScaleVector( delta, 0.0001 );     AddVectors( vec1, delta, result ); } OnThink( rocket ) {     decl Float:lastPos[ 3 ];     // get lastPos from lastPosArray somehow     decl Float:pos[ 3 ];     decl Float:velocity[ 3 ];     GetEntPropVector( rocket, Prop_Send, "m_vecOrigin", pos );     GetEntPropVector( rocket, Prop_Send, "m_vecAbsVelocity", velocity );     new bounces = 0;     while( bounces < BOUNCE_LIMIT ) {         new closestSphere = -1;         decl Float:closestT;         // find the first sphere we intersect with         new numSpheres = GetArraySize( spheres );         for( new i = 0; i < numSpheres; i++ ) {             decl Float:centre[ 3 ];             GetArrayArray( spheres, i, centre, 3 );             new Float:radius = GetArrayCell( spheres, i, 4 );             new const Float:t = IntersectSegmentSphere( lastPos, pos, centre, radius );             if( closestSphere == -1 || t < closestT ) {                 closestSphere = i;                 closestT = t;             }         }         // we didn't hit anything         if( closestSphere == -1 || closestT > 1.0 ) {             break;         }         decl Float:centre[ 3 ];         GetArrayArray( spheres, closestSphere, centre, 3 );         new Float:radius = GetArrayCell( spheres, closestSphere, 4 );         decl Float:intersection[ 3 ];         LerpVectors( lastPos, pos, closestT, intersection );         decl Float:normal[ 3 ];         SphereNormalAt( centre, radius, intersection, normal );         decl Float:newVelocity[ 3 ];         ReflectVector( velocity, normal, newVelocity );         AddDelta( intersection, newVelocity, intersection );         decl Float:penetration[ 3 ];         CopyVector( velocity, penetration );         ScaleVector( penetration, 1.0 - closestT );         decl Float:reflection[ 3 ];         ReflectVector( penetration, normal, reflection );         decl Float:newPos[ 3 ];         AddVectors( intersection, reflection, newPos );         CopyVector( newVelocity, velocity );         CopyVector( intersection, lastPos );         CopyVector( newPos, pos );         bounces++;     }     if( bounces == BOUNCE_LIMIT ) {         // the rocket is stuck in some terrible situation.         // possible courses of action include:         // - put the rocket out of its misery and make it explode         // - ignore it (but then we are likely to encounter something         //   similar next frame)     }     // update lastPosArray with current pos     decl Float:angles[ 3 ];     GetVectorAngles( velocity, angles );     TeleportEntity( rocket, pos, angles, velocity ); }
__________________

Last edited by MikeJS; 01-17-2014 at 03:01. Reason: teleportentity > setentpropvector
MikeJS is offline
Skippy
Senior Member
Join Date: Nov 2011
Old 01-16-2014 , 08:29   Re: Rocket Bounce Sphere Surface
Reply With Quote #4

Yeah I probably won't be able to understand that. Could you show me how I should implement it with the timer I have.
__________________
Plugins:
[Any] Aim Menu

Want a TF2 plugin? Feel free to pm me to discuss it.
Skippy is offline
MikeJS
Senior Member
Join Date: Nov 2008
Old 01-16-2014 , 09:09   Re: Rocket Bounce Sphere Surface
Reply With Quote #5

You want to hook SetTransmit (SDKHooks can do this) and point it at OnThink in the code I gave you, and this should be done from OnEntityCreated.
__________________
MikeJS is offline
Skippy
Senior Member
Join Date: Nov 2011
Old 01-16-2014 , 18:31   Re: Rocket Bounce Sphere Surface
Reply With Quote #6

Wait what does the onthink do? Because I have a repeating timer to get the rockets position and if it's within the radius compared to the center then it will reflect it.
__________________
Plugins:
[Any] Aim Menu

Want a TF2 plugin? Feel free to pm me to discuss it.
Skippy is offline
Root_
Veteran Member
Join Date: Jan 2012
Location: ryssland
Old 01-16-2014 , 18:33   Re: Rocket Bounce Sphere Surface
Reply With Quote #7

Skippy,
Quote:
Originally Posted by MikeJS View Post
Do your checks in a think function rather than a timer so you can get 1/66s resolution rather than 1/10s if you want it to be more accurate.
Also welcome back, Mike!
__________________


dodsplugins.com - Plugins and Resources for Day of Defeat
http://twitch.tv/zadroot
Root_ is offline
Skippy
Senior Member
Join Date: Nov 2011
Old 01-16-2014 , 18:34   Re: Rocket Bounce Sphere Surface
Reply With Quote #8

So OnThink is like ongameframe?
__________________
Plugins:
[Any] Aim Menu

Want a TF2 plugin? Feel free to pm me to discuss it.
Skippy is offline
Root_
Veteran Member
Join Date: Jan 2012
Location: ryssland
Old 01-16-2014 , 18:36   Re: Rocket Bounce Sphere Surface
Reply With Quote #9

Quote:
Originally Posted by Skippy View Post
So OnThink is like ongameframe?
Yes, but for single entity.
__________________


dodsplugins.com - Plugins and Resources for Day of Defeat
http://twitch.tv/zadroot
Root_ is offline
Skippy
Senior Member
Join Date: Nov 2011
Old 01-16-2014 , 18:48   Re: Rocket Bounce Sphere Surface
Reply With Quote #10

These are the errors I'm getting

HTML Code:
error 022: must be lvalue (non-constant)
PHP Code:
    b /= mag
HTML Code:
error 035: argument type mismatch (argument 2)
PHP Code:
GetArrayArrayspherescentrei); 
HTML Code:
error 017: undefined symbol "i"
PHP Code:
new Float:radius GetArrayCellspheresi); 
HTML Code:
error 017: undefined symbol "t"
PHP Code:
LerpVectorslastPospostintersection ); 
HTML Code:
error 017: undefined symbol "t"
PHP Code:
ScaleVectorpenetration1.0 ); 
__________________
Plugins:
[Any] Aim Menu

Want a TF2 plugin? Feel free to pm me to discuss it.
Skippy is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 12:51.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode