• Rotating Entity to Angle using PhysicsSimulate
    2 replies, posted
I'm trying to make an entity that rotates towards a specific angle using PhysicsSimulate. The entity just spins and i also can't make any sense of the stuff that is output. In C++ to achieve something similar(in 2D) I use this code: [code] float nextAngle = body->GetAngle( ) + body->GetAngularVelocity( ) * dt * 1 / turnSpeed; float rotationDelta = wantedRotation - nextAngle; //Take Shortest Way Round if( rotationDelta < -M_PI ) rotationDelta += M_PI * 2; else if( rotationDelta > M_PI ) rotationDelta -= M_PI * 2; float impulse = body->GetInertia( ) * rotationDelta; body->ApplyAngularImpulse( impulse ); [/code] It's fairly simple, i take the difference of the angle next tick and the angle i want to have, make sure it rotates the right way and then apply the impulse. I tried to replicate this in gmod, however i'm having a few difficulties: phy:GetAngleVelocity( ) returns a Vector, why? I need to add it to an angle which doesnt work ofc, any of the :Forward() or :Angle() don't seem to work. What does GetAngleVelocity return? What value am i supposed to be returning in PhysicsSimulate? Is it the angular impulse or the angular velocity? It seems to me it is the Impulse as the velocity is never set correctly in prints. What is the meaning of the value returned and how would i calculate it correctly? This is what i have so far, it works when i change the a single component of the target angle and only for some values(seems to be good for 10-45° after that it starts bugging out ) Edit: Got it partly working, it works now but when i change the roll of the target angle it starts spazzing out [lua] function ENT:PhysicsSimulate( phys, deltaTime ) local turnSpeed = 10 local targetAngle = self:GetTargetAngle( ) targetAngle.r = 0 --roll Bugs local angVel = Angle( phys:GetAngleVelocity( ).y, phys:GetAngleVelocity( ).z, phys:GetAngleVelocity( ).x ) local angleNextThink = phys:GetAngles( ) + angVel * deltaTime * ( 1 / turnSpeed ) local angleDiff = targetAngle - angleNextThink angleDiff = doit( angleDiff ) local angleDiffV = Vector( angleDiff.r, angleDiff.p, angleDiff.y ) * turnSpeed local vAngular = angleDiffV * phys:GetInertia( ) local vAngular = -phys:GetAngleVelocity( ) * deltaTime + angleDiffV * deltaTime return vAngular, vLinear, SIM_GLOBAL_FORCE [/lua]
1. GetAngleVelocity returns a Angle in a Vector object, X=Pitch, Y=Yaw, Z=Roll (You could make a github issue about this if you want) 2. Since you are using the PhysicsSimulate hook rather then anything i guess you need some kind of physics prediction (because else you really shouldn't be using it). 3. What you actually want to do is much much easier then what you are doing. self:GetTargetAngle -> Normalize Target Angle -> TargetAngle - CurrentAngle -> Multiply with dt and turnSpeed -> Return
i tried that but unfortunately it wouldn't work :/ Also i found out this is how to make the angle wrapped in vector to an angle: [lua] function v2a( v ) return Angle( v.y, v.z, v.x ) emd function a2v( a ) return Vector( a.r, a.p, a.y ) end [/lua] really strange ordering O.o Using x = pitch, y=yaw and z = roll made it spazz out extremely, this works, somewhat using just the deltaAngles * dt * turnSpeed would make it spin endlessly, i think you're supposed to return something that adds to the current angular velocity( kind of like AddAngleVelocity ) This is my code right now: [lua] local targetAngle = Angle( 90, 0, 0 )--self:GetTargetAngle( ) targetAngle:Normalize( ) local angleDiff = targetAngle - self:GetAngles( ) local vAngular = -phys:GetAngleVelocity( ) * deltaTime + a2v(angleDiff) * deltaTime * 1 [/lua] It works for angles < 90°, from 90° upwards after a while it starts spinning in the dumbest way(most rotation you can make) to get back to the 90°. It's stable for a few moments than starts doing it again.
Sorry, you need to Log In to post a reply to this thread.