ODE Middleware

Return to Code Snippets

Postby coppertop » Sun Aug 15, 2010 12:06 pm

Ah, that's what I thought, just didn't want to get into explaining without making sure ;).

I forgot to add...
Code: Select all
self.objectType = "trigger"
...in the odeTrigger class. Put it right after:
Code: Select all
class odeTrigger(staticObject):
   def __init__(self, map, model, name):
      staticObject.__init__(self, map)


Additionally, change the player's setFly method to this:
Code: Select all
def setFly(self, value, object, trigger):
      print "SET FLY", value
      if object is not self:
         return
      if value:
         self.state = "fly"
         self.movementParent = base.cam
      else:
         self.state = "ground"
         self.movementParent = self.geom


And, AFAIR, that should be all.

On a side note, I'm not complaining about the need to post a few lines here, but why don't you just download the fixed version? ;). Asking just out of curiosity ;).
User avatar
coppertop
 
Posts: 527
Joined: Sat Apr 18, 2009 5:48 am

Postby blenderkid » Sun Aug 15, 2010 12:24 pm

Thank you =)

I downloaded the new version, but I removed the old one =/ (stupid me). So I had not had a file to compare, in my game I've already changed a lot so I can't see so easy what was changed =)

Thank you

blenderkid
blenderkid
 
Posts: 85
Joined: Sat Jun 20, 2009 4:15 am
Location: Germany

Postby blenderkid » Sat Sep 25, 2010 6:49 am

Hi,

I finally found some time to continue the game and I have a problem, which I don't realy understand because I do almost exactly the same as you in your map script.

I am trying to load a gun:

Code: Select all
firearmtest = Firearm()  #<--basically your gun class
firearmtest.loadConfig("config/guns/P90/main.txt") #<-- this does not matter
firearmtest.setupGeomAndPhysics(g.map, (0,0,10))  #<--Here the error occurs


The error message is:

Code: Select all
Traceback (most recent call last):
  File "test.py", line 72, in <module>
    firearmtest.setupGeomAndPhysics(g.map, (0,0,10))
  File "/home/filip/develop/panda-shooter/dev/new/pickables.py", line 45, in setupGeomAndPhysics
    DynamicObject.__init__(self, map)
  File "/home/filip/develop/panda-shooter/dev/new/odeWorldManager.py", line 456, in __init__
    DynamicObjectNoCCD.__init__(self, map)
  File "/home/filip/develop/panda-shooter/dev/new/odeWorldManager.py", line 342, in __init__
    StaticObject.__init__(self, map)
TypeError: unbound method __init__() must be called with StaticObject instance as first argument (got Firearm instance instead)
Segmentation fault



I am a bit confused. I know why it has Firearm as "self", but firearm is an Extension of StaticObject... so I dont understand the problem...

I hope you know what to do =)

Thank you very much
blenderkid
blenderkid
 
Posts: 85
Joined: Sat Jun 20, 2009 4:15 am
Location: Germany

Postby coppertop » Sat Sep 25, 2010 7:55 am

firearmtest = Firearm() #<--basically your gun class

I guess "basically" means "not exactly", right? ;). Can you show me the code of that class? Or the changes made to it, if it's a changed gun class and not a new one derived from it.

My first thought is that Firearm does not correctly inherit from the classes it's supposed to inherit from. The original Gun class inherits from pickableObject. Maybe you've made some changes to that class and removed correct inheritance by accident?

Anyhow, please show the code for Firearm.
User avatar
coppertop
 
Posts: 527
Joined: Sat Apr 18, 2009 5:48 am

Postby blenderkid » Sat Sep 25, 2010 12:52 pm

But it is almost exactly the same ( at least the necessary parts )

Code: Select all
from pandac.PandaModules import Point3, Vec3
from direct.interval.IntervalGlobal import *
from direct.showbase.DirectObject import DirectObject

from odeWorldManager import *
from pickables import PickableObject

import random
import configurations


class Firearm(PickableObject, DirectObject):
   def __init__(self, name="handgun", weight=0.630):
      PickableObject.__init__(self, name, weight)
      
      self.config = configurations.Configuration()
      
      
      
      self.pickableType = "firearm"
      
      
      self.modelPath = "models/p90.egg"
      self.worldModelPath = "models/p90.egg"
      self.hudModelPath   = "models/p90.egg"
      self.geomSize = (0.054, 0.381, 0.227)
      
      """
      Is it automatic or semi-automatic?
      """
      self.automatic = False
      
      """
      How far do you want the bullets to go?
      """
      self.effectiveRange = 300.0
      
      """
      Rate of Fire for automatic weapons.
      """
      self.autoROF = 250.0
      
      """
      Used for ROF, more on that in the update method.
      """
      self.autoAccumulator = 0.0
      
      """
      Number of rays to search for hits with. This basically
      translates to this: If it's more than one, you have a shotgun.
      It it's one -- a pistol or a rifle.
      """
      self.aimRaysNum = 1
      
      """
      Holds aim rays.
      """
      self.aimRays = []
      
      """
      If you have more than one aim ray, then here you can set how
      dispersed they're going to be.
      """
      self.shotgunDispersion = 0.2
      
      """
      Are we shooting ATM?
      """
      self.shooting = False
      
      """
      Contains the hits.
      """
      self.aimCollisions = []
      
      
   
   """
   The callback for aim ray collisions.
   """
   def aimCollision(self, entry, object1, object2):
      """
      No point hitting triggers or ccd helpers.
      """
      if object2.objectType is ["ccd"]:
         return
      
      """
      So we don't shoot ourselves.
      """
      if object2 is self.owner:
         return
      
      """
      Append the hit to the list.
      """
      self.aimCollisions.append([entry, object2])
   
   def destroy(self):
      for ray in self.aimRays:
         self.map.worldManager.removeObject(ray)
         ray.destroy()
      del self.aimCollisions
      del self.aimRays
      pickableObject.destroy(self)
      self.ignoreAll()
   
   """
   Create the requested number of aim rays.
   """
   def createAimRays(self):
      for i in range(self.aimRaysNum):
         self.createAimRay()
   
   """
   Create a single aim ray.
   """
   def createAimRay(self):
      ray = rayObject(self.map)
      ray.objectType = "ray"
      ray.setRayGeom(self.effectiveRange, [Vec3(0,0,0), Vec3(0,0,-1)])
      ray.collisionCallback = self.aimCollision
      
      self.map.worldManager.addObject(ray)
      self.aimRays.append(ray)
   
   def destroyAimRays(self):
      for ray in self.aimRays:
         self.map.worldManager.removeObject(ray)
         ray.destroy()
      self.aimRays = []
      self.aimCollisions = []
   
   def selectionCallback(self, character, direction):
      PickableObject.selectionCallback(self, character, direction)
      
      """
      Create the rays when we pick up the gun. No need having them around all the time.
      
      NOTE: In my game, I actually create the rays when the Player withdraws the gun
      from the inventory, but the actual usage depends on application's design.
      """
      self.createAimRays()
   
   def drop(self):
      """
      Destroy the rays when we drop the gun.
      """
      self.destroyAimRays()
      PickableObject.drop(self)
   
   def useHeld(self):
      """
      Start shooting...
      """
      self.shooting = True
      return True
   
   def useHeldStop(self):
      """
      Stop shooting an automatic weapon.
      Semi automatic weapons stop shooting by themselves, right after
      one update pass.
      """
      if self.automatic:
         self.stopShooting()
      return
   
   def shoot(self, dir):
      """
      Process the collected hits.
      """
      for entry, object in self.aimCollisions:
         p = entry.getContactPoint(0)
         if object.body:
            object.body.enable()
            object.body.addForceAtPos(dir*(10**2), p)
   
   def stopShooting(self):
      """
      Stop shooting and clear the collisions accumulator.
      """
      self.shooting = False
      self.autoAccumulator = 0.0
      
   def update(self, stepSize):
      PickableObject.update(self,stepSize)
      
      if not self.aimRays:
         self.aimCollisions = []
         return
      
      """
      Only process hits if the gun is picked up.
      """
      if self.owner:
         """
         Get the desired position and direction of the aim ray/s.
         
         NOTE that currently there's only support for Player (camera)
         and not NPCs. Supports for NPCs will come in the next major version.
         """
         pos = base.cam.getPos(render) + render.getRelativeVector(base.cam, Vec3(0, 0.8, 0))
         dir = render.getRelativeVector(base.cam, Vec3(0, 1.0, 0))
         
         """
         Handle the Rays and add some random dispersion.
         """

         for ray in self.aimRays:
            """
            Scatter the rays within the limits set by the shotgunDispersion variable.
            """
            x = random.uniform(-self.shotgunDispersion, self.shotgunDispersion)
            z = random.uniform(-self.shotgunDispersion, self.shotgunDispersion)
            
            """
            Tweak the direction to take the random values into account.
            """
            rayDir = Vec3(dir)
            rayDir[0] += x
            rayDir[2] += z
            
            """
            Position the ray.
            """
            ray.geom.set(pos, rayDir)
         
         """
         Handle automatic weapons.
         """
         if self.automatic and self.shooting:
            """
            If this is the first frame we're self.shooting == True,
            shoot once and then continue processing.
            """
            if self.autoAccumulator == 0.0:
               self.shoot(dir)
            
            """
            Add the rate-of-fire to the accumulator.
            """
            self.autoAccumulator += self.autoROF
            
            """
            Get the ROF per second
            """
            currentROF = 1.0/self.autoAccumulator
            
            """
            Call shoot method as many times as shots fitting in the
            simulation time step.
            
            That's what the accumulator is for -- thanx to that,
            the speed of shooting depends on values set, not on
            the simulation's update rate.
            """
            if currentROF < stepSize:
               for i in range(int(stepSize / currentROF)):
                  self.shoot(dir)
               self.autoAccumulator = 0.0
         
            """
            Handle semi automatic shooting.
            """
         elif self.shooting:
            self.shoot(dir)
      
      """
      If semi-automatic, make sure to shoot only once.
      """
      if not self.automatic:
         self.stopShooting()
      
      """
      Clear aim collisions before the next frame.
      """
      self.aimCollisions = []
      
   def loadConfig(self, filename):
      self.config.addConfig(filename)
      self.configName = self.config.configs.keys()[0]
      
      self.activateConfigs()
      
   def activateConfigs(self):
      self.name   = self.config.getConfig(self.configName)["properties"]["name"]
      self.rps    = self.config.getConfig(self.configName)["properties"]["rps"]
      self.type   = self.config.getConfig(self.configName)["properties"]["type"]
      self.hudModelPath  = self.config.getConfig(self.configName)["properties"]["model"]
      self.worldModelPath  = self.config.getConfig(self.configName)["properties"]["worldmodel"]

      self.modelPath = self.worldModelPath


That's the firearm module


I've renamed pickableObject to PickableObject because I am used to have classes capitalized ;) I've capitalized all classes =)

I hope you can find my mistake

Thank you very much
blenderkid
blenderkid
 
Posts: 85
Joined: Sat Jun 20, 2009 4:15 am
Location: Germany

Postby coppertop » Sat Sep 25, 2010 1:04 pm

Hm, it really is almost exactly the same... Sorry, but I still don't see what's wrong... Have you made any important changes to the PickableObject class? And do you experience the same problems with adding any other kind of objects inheriting from the PickableObject class? Like boxes or whatnot?

It seems like the problem is either in the Firearm class or the PickableObject class. I guess we can exclude the first one (well, frankly it was the less likely option since the error occurs in the setupGeomAndPhysics method).
User avatar
coppertop
 
Posts: 527
Joined: Sat Apr 18, 2009 5:48 am

Postby blenderkid » Sun Sep 26, 2010 4:32 am

Hi,

here is a gzip with all modules involved in that error =)
Modules with at least one error =P

I hope you find that error. I am still confused =/

Thank you very much!
blenderkid
blenderkid
 
Posts: 85
Joined: Sat Jun 20, 2009 4:15 am
Location: Germany

Postby coppertop » Sun Sep 26, 2010 5:39 am

Ok, found it. Line 340 to 342 in odeWorldManager.
Code: Select all
class DynamicObjectNoCCD(PhysicalObject):
   def __init__(self, map):
      StaticObject.__init__(self, map)

Seems like you've made a really big mess in inheritance when changing the names to capitalized ;). Ok, so this error should be obvious -- you inherit from PhysicalObject, but you attempt to call __init__ on StaticObject. This can't work.

However, there's more. You've generally changed the inheritance (probably because of attempting to change the names too quickly) and, unless you've made some real changes to the code itself (and it doesn't seem so at the first glance) the code just won't work.

The correct inheritance is as follows:
Code: Select all
PhysicalObject(object)
StaticObject(PhysicalObject)
RayObject(PhysicalObject)
KinematicObject(StaticObject)
DynamicObjectNoCCD(StaticObject)
DynamicObjectCCD(DynamicObjectNoCCD)
Explosion(KinematicObject)

In your version kinematic and basic dynamic objects inherit from the PhysicalObject instead from the StaticObject, which is incorrect.

When changing that pay attention to the contents of __init__ and all other methods which might contain calls to the parent classes with "self".

Assuming one has access to source code tracking down errors of that kind is very simple. It all comes down to walking through inheritance top-to-bottom.
User avatar
coppertop
 
Posts: 527
Joined: Sat Apr 18, 2009 5:48 am

Postby blenderkid » Sun Sep 26, 2010 5:51 am

Oh *facepalm* stupid me....

Thank you soo much!
blenderkid
blenderkid
 
Posts: 85
Joined: Sat Jun 20, 2009 4:15 am
Location: Germany

Postby coppertop » Thu Oct 21, 2010 6:53 am

A new minor version is up. It contains just one important bug fix, no new features were added this time. I've been away from any codding for some time, that's why it took so long.

Just to keep you informed, after that long silence, for the next version I'm planning full moving platforms support, for elevators and the like (no API changes planned at this time).
User avatar
coppertop
 
Posts: 527
Joined: Sat Apr 18, 2009 5:48 am

Postby Stoo » Fri Nov 19, 2010 10:49 am

I'm having trouble animating a model using this system. In the map.create method, I've added the following code after the self.processBranch call:
Code: Select all
      mNodePath = Actor.Actor("legs.egg",
                                {"walk": "legs-Walk.egg"})
      mNodePath.reparentTo(render)
      mNodePath.setPos(-10,-10,5.5)
      mNodePath.loop('walk')


The model shows up fine, but the animation doesn't play. The model is animated if I put it in the walking panda tutorial though; so I know the files are fine. mNodePath.getNumFrames('walk') is returning 21 frames, which is correct; so I'm not sure why it's not actually doing anything. Does the loop call need to be done at some later point?
Stoo
 
Posts: 16
Joined: Fri Nov 19, 2010 10:34 am

Postby coppertop » Fri Nov 19, 2010 12:27 pm

To be honest I have no idea why it doesn't work.

Can you show the whole method, i.e. this and the surrounding code? I don't think the problem is the framework, to be honest. If your model isn't a part of some dynamic, kinematic or static object, but just an arbitrary model loaded with the code you've shown, then the framework shouldn't affect it in any way (in fact, it shouldn't even if it was used by physical objects).
User avatar
coppertop
 
Posts: 527
Joined: Sat Apr 18, 2009 5:48 am

Postby Stoo » Fri Nov 19, 2010 12:39 pm

Sure, here:

Code: Select all
   def create(self):
      """
      Load the map Egg file and get it's root node
      """
      # MAP PARENT
      self.map = loader.loadModel(self.mapFile)
      self.map.reparentTo(render)
      self.mapRootNode = self.map.find("-PandaNode")

      """
      See the processBranch method definition lower
      """
      self.processBranch(self.mapRootNode)
      
      #Quick animation check
      mNodePath = Actor.Actor("legs",
                                {"walk": "legs-Walk"})
      mNodePath.reparentTo(render)
      mNodePath.setPos(-10,-10,5.5)
      mNodePath.loop('walk')


      """
      Start the simulation at the required time step size
      """
      self.worldManager.startSimulation(self.simTimeStep)
      
      """
      Enable player
      """
      self.player.enableInput()
      self.player.enableMovement()
Stoo
 
Posts: 16
Joined: Fri Nov 19, 2010 10:34 am

Postby drwr » Fri Nov 19, 2010 1:40 pm

This is a common mistake with Actor. You are creating an Actor, and saving it in a local variable (mNodePath). But you are not then saving that variable anywhere, so when it goes out of scope, Python cleans it up, and deletes the Actor part of the object.

The NodePath part of it remains and is visible in the scene graph, but since it is no longer an Actor it doesn't animate.

Solution: self.mNodePath = mNodePath

David
drwr
 
Posts: 11425
Joined: Fri Feb 13, 2004 12:42 pm
Location: Glendale, CA

Postby Stoo » Fri Nov 19, 2010 4:57 pm

Yep, that fixed it. Ironically, if I hadn't been testing each part first, I probably wouldn't have run into this :P

Thanks, both of you!
Stoo
 
Posts: 16
Joined: Fri Nov 19, 2010 10:34 am

Postby coppertop » Wed Dec 15, 2010 10:18 am

New major version (1.2.0) has been released bringing a lot of new stuff. See the first post for details.
User avatar
coppertop
 
Posts: 527
Joined: Sat Apr 18, 2009 5:48 am

Postby Stoo » Wed Dec 29, 2010 6:06 pm

Is there a limit on how large the kcc.setCapsuleData can be set? I can set the player to half-sized without any issues, but if I double the player's size ( self.setCapsuleData(3.7,1.6,0.6,0.7) ), the player "bounces" in place.

I haven't played with the code much yet - is there an easy way around this?

Platform looks good so far! Did finally see that memory leak in panda 1.7 with this version though; once I set another kcc object near it :p
Stoo
 
Posts: 16
Joined: Fri Nov 19, 2010 10:34 am

Postby coppertop » Thu Dec 30, 2010 7:07 am

Fixed. Looks like I just left the footRay's (and the environment checker ray's too) length hard codded for some reason. This caused the controller to bounce on the tip of the ray, like on a pogo stick. I've updated the download -- same version, don't think it really deserves it's own number ;).
User avatar
coppertop
 
Posts: 527
Joined: Sat Apr 18, 2009 5:48 am

Postby derfies » Sat Jan 01, 2011 9:56 pm

Hey Coppertop,

This is totally awesome, I'm currently getting a pipeline established between Maya and this framework. I am having troubles with running the latest 1.2 version however, getting this error:

Code: Select all
---------------------------
ODE INTERNAL ERROR 2
---------------------------
Bad argument(s) (..\..\ode\src\capsule.cpp:84)
---------------------------
OK   
---------------------------


The previous version seems to work fine however.
derfies
 
Posts: 236
Joined: Tue Jun 29, 2010 9:59 pm

Postby coppertop » Sun Jan 02, 2011 7:08 am

Ok, I've found the problem. Updated the download link with the fixed version.

Additionally, I also figured that I left the Player controller extremely big after fixing the previous bug... That's what happens when you try to do things too quickly. Anyway, I've got no idea why this latest bug didn't show on Linux, but it should be fine now.
User avatar
coppertop
 
Posts: 527
Joined: Sat Apr 18, 2009 5:48 am

Postby Stoo » Sun Jan 02, 2011 11:27 am

Latest version works fine for me! This is a Linux system, though...

I did wonder something about the class setup - was there a reason the kinematicCharacterController inherits from Object, rather than kinematicObject? I've been working on some other objects based on the kcc; and adjusting the inheritance that way made it a lot easier to manage the art and interactions.
Stoo
 
Posts: 16
Joined: Fri Nov 19, 2010 10:34 am

Postby coppertop » Sun Jan 02, 2011 11:43 am

was there a reason the kinematicCharacterController inherits from Object, rather than kinematicObject? I've been working on some other objects based on the kcc; and adjusting the inheritance that way made it a lot easier to manage the art and interactions.

The story is simple. If you scan through this topic you'll find that general kinematic objects class came around after the KCC. I started writing all this to get an ODE-based character controller, and everything else was added later. So the KCC doesn't inherit from other kinematic objects for, let's say, historic reasons. This setup just never done me any harm so I rarely notice it, and thus don't change it. Although, it might be considered an oversight (at best) of mine, yes.

EDIT:
Uploaded a new version, named 1.2.1, in which the KCC now inherits from general kinematics. It doesn't make much difference, but I guess since it makes your codding easier, Stoo, it might do the same to everybody else ;).

Let me know if I didn't screw up something when changing that ;D.
User avatar
coppertop
 
Posts: 527
Joined: Sat Apr 18, 2009 5:48 am

Postby Stoo » Sun Jan 02, 2011 7:05 pm

coppertop wrote:Uploaded a new version, named 1.2.1, in which the KCC now inherits from general kinematics. It doesn't make much difference, but I guess since it makes your codding easier, Stoo, it might do the same to everybody else ;).

Let me know if I didn't screw up something when changing that ;D.


What service! My quick test didn't show anything breaking, anyway :D
Stoo
 
Posts: 16
Joined: Fri Nov 19, 2010 10:34 am

Postby derfies » Tue Jan 04, 2011 2:57 am

Thanks Copper, the new version works for me now (Win7) :)

One thing I did notice - I threw a grenade in the bottom room into the corner with the other grenades and got this:

grenade exploding!
Traceback (most recent call last):
File "C:\Documents\Python\copperode 1.2.1\weapons\grenade.py", line 37, in explode
map = self.map
AttributeError: 'grenade' object has no attribute 'map'
:task(error): Exception occurred in PythonTask explosion
Traceback (most recent call last):
File "main.py", line 139, in <module>
run()
File "C:\Panda3D-1.7.0\direct\showbase\ShowBase.py", line 2531, in run
self.taskMgr.run()
File "C:\Panda3D-1.7.0\direct\task\Task.py", line 496, in run
self.step()
File "C:\Panda3D-1.7.0\direct\task\Task.py", line 454, in step
self.mgr.poll()
File "C:\Documents\Python\copperode 1.2.1\weapons\grenade.py", line 37, in explode
map = self.map
AttributeError: 'grenade' object has no attribute 'map'
derfies
 
Posts: 236
Joined: Tue Jun 29, 2010 9:59 pm

Postby coppertop » Tue Jan 04, 2011 9:43 am

Thanks Copper, the new version works for me now (Win7)

Glad to read that :).

About that bug -- you probably threw a grenade, then picked in up, and then threw it again before it exploded. If you do that, the grenade's explosion is triggered twice, but it gets destroyed in between, resulting in this error.

It simply shouldn't be possible and it's just a result of the way stuff is handled in the simplistic placeholder inventory-ish system included in the sample. In the same way, the grenades are just meant for presenting the explosion mechanics, as well as providing an example of how a simple grenade can be implemented, rather than being ready-to-use in a real project.
User avatar
coppertop
 
Posts: 527
Joined: Sat Apr 18, 2009 5:48 am

Postby derfies » Fri Jan 07, 2011 3:14 am

Ah, I see. No worries then :)

Have another question - just curious as to why you have the map's egg file written into the constructor instead of passing it in as an argument? (I'm still a bit of a python n00b, please excuse me if this seems like an obvious question.)
derfies
 
Posts: 236
Joined: Tue Jun 29, 2010 9:59 pm

Postby coppertop » Fri Jan 07, 2011 6:17 am

Same reason as before :). It's meant solely for demonstration of how you can load objects by placing them in Blender using Empties with tags. But as far as the low level setup goes, you'll want rearrange it to fit your needs, whatever they may be. The point of the map.py file is how objects are created around empties and how the map's egg is traversed, so whether you pass it as an argument, hardcode it or do whatever else with it is up to you.
User avatar
coppertop
 
Posts: 527
Joined: Sat Apr 18, 2009 5:48 am

Postby derfies » Fri Jan 07, 2011 6:18 pm

Ok, great. :)

Small contribution from me - a tagger for maya based on the maya object tagger script. Middle mouse this script to your shelf and click it with some objects selected to add the tag attribute. Ctrl-click to remove the attribute.

Code: Select all
global proc copperOdeTagger()
{       
   string $sel[] = `ls -sl`;
   for ( $i in $sel )
   {
      string $attrName = "tagtype";

      // Modify this line as needed to add your own object types
      string $eggFlags = "none:solidBoxGeom:solidTriMeshGeom:playerPosition:alight:dlight:plight:fly_trigger";
      string $object = ( $i + "." + $attrName );
      
      // Command click removes the attribute, otherwise it is added
      int $mods = `getModifiers`;
      if ( ( $mods / 4 ) % 2 )
      {
         if( `objExists $object` )
         {
            deleteAttr -at $attrName $i;
         }
      }
      else
      {
         if( !`objExists $object` )
         {
            addAttr -ln $attrName -k 1 -at "enum" -en $eggFlags $i;
         }
      }
   }
}
copperOdeTagger();
derfies
 
Posts: 236
Joined: Tue Jun 29, 2010 9:59 pm

Postby coppertop » Sat Jan 08, 2011 6:15 pm

That's really cool. I don't have Maya, so I can't really try it out, but it's really nice to see such contribution :).
User avatar
coppertop
 
Posts: 527
Joined: Sat Apr 18, 2009 5:48 am

Postby Stoo » Thu Jan 13, 2011 8:46 pm

Okay; so I've got a basic vehicle class set up now, all that's really left on it is the turning behavior. Right now, in the update method for the vehicle, I've got the following:

Code: Select all
        newQuat = self.getQuat()
        newQuat[0] = newQuat[0] + self.rotamt * self.rotspeed
        self.setQuat(newQuat)


This should look at whatever the player has set the rotamt to, and rotate based on the vehicle's rotspeed. This works fine, until it almost completes a spin - it suddenly slows way down. I assume there's some funkiness with quaternion arithmetic, I'm not really familiar with using quats beyond pulling them out and messing with an axis. I didn't see any obvious examples of setting a slow, controlled spin in any of the dynamic or kinematic object classes, is there an easy way around this? Or do I need to do something else with the quaternion?
Stoo
 
Posts: 16
Joined: Fri Nov 19, 2010 10:34 am

PreviousNext

Return to Code Snippets

Who is online

Users browsing this forum: No registered users and 1 guest