Dave Schuyler пре 21 година
родитељ
комит
9824a5411e

+ 8 - 3
direct/src/directnotify/Notifier.py

@@ -4,6 +4,7 @@
 from LoggerGlobal import *
 from direct.showbase import PythonUtil
 import time
+import types
 
 class Notifier:
     serverDelta = 0
@@ -194,7 +195,7 @@ class Notifier:
         could put it here.
         """
         print string
-
+        
     def debugStateCall(self, obj=None, fsmMemberName='fsm'):
         """
         If this notify is in debug mode, print the time of the 
@@ -207,11 +208,15 @@ class Notifier:
                 if hasattr(obj, fsmMemberName) and obj.fsm.getCurrentState() is not None:
                     #state = "%s=%s"%(obj.fsm.getName(), obj.fsm.getCurrentState().getName())
                     state = obj.fsm.getCurrentState().getName()
-            string = ":%s [%-7s] %s %s.%s"%(
+            if 1 or type(obj) == types.ClassType:
+                name = "%s."%(obj.__class__.__name__,)
+            else:
+                name = "%s "%(self.__name,)
+            string = ":%s [%-7s] %s %s%s"%(
                 self.getOnlyTime(),
                 state,
                 id(obj),
-                self.__name,
+                name,
                 PythonUtil.traceParentCall())
             self.__log(string)
             self.__print(string)

+ 207 - 0
direct/src/distributed/ClientRepository.py

@@ -31,6 +31,10 @@ class ClientRepository(ConnectionRepository.ConnectionRepository):
         self.bootedIndex = None
         self.bootedText = None
 
+        self.worldScale = render.attachNewNode("worldScale") # for grid zones.
+        self.worldScale.setScale(base.config.GetFloat('world-scale', 100))
+        self.priorWorldPos = None
+        
         # create a parentMgr to handle distributed reparents
         # this used to be 'token2nodePath'
         self.parentMgr = ParentMgr.ParentMgr()
@@ -65,6 +69,40 @@ class ClientRepository(ConnectionRepository.ConnectionRepository):
             self.disconnect()
         self.stopHeartbeat()
 
+    def setWorldOffset(self, xOffset=0, yOffset=0):
+        self.worldXOffset=xOffset
+        self.worldYOffset=yOffset
+
+    def getWorldPos(self, nodePath):
+        pos = nodePath.getPos(self.worldScale)
+        return (int(round(pos.getX())), int(round(pos.getY())))
+
+    def sendWorldPos(self, x, y):
+        # The server will need to know the world
+        # offset of our current render node path
+        # and adjust the x, y accordingly.  At one
+        # point I considered adding the world offset
+        # here, but that would just use extra bits.
+
+        onScreenDebug.add("worldPos", "%-4d, %-4d"%(x, y))
+        return #*#
+
+        datagram = PyDatagram()
+        # Add message type
+        datagram.addUint16(CLIENT_SET_WORLD_POS)
+        # Add x
+        datagram.addInt16(x)
+        # Add y
+        datagram.addSint16(y)
+        # send the message
+        self.send(datagram)
+
+    def checkWorldPos(self, nodePath):
+        worldPos = self.getWorldPos(nodePath)
+        if self.priorWorldPos != worldPos:
+            self.priorWorldPos = worldPos
+            self.sendWorldPos(worldPos[0], worldPos[1])
+
     def setServerDelta(self, delta):
         """
         Indicates the approximate difference in seconds between the
@@ -408,6 +446,175 @@ class ClientRepository(ConnectionRepository.ConnectionRepository):
         # send the message
         self.send(datagram)
 
+    def gridZoneCenter(self, x, y, zoneBase=0, resolution=500):
+        """
+        x is a float in the range 0.0 to 1.0
+        y is a float in the range 0.0 to 1.0
+        resolution is the number of cells on each axsis.
+        """
+        if x < 0.0 or x > 1.0 or y < 0.0 or y > 1.0:
+            return None
+        resolution=int(resolution)
+        print "resolution", resolution,
+        xCell=min(int(x*resolution), resolution-1)
+        yCell=min(int(y*resolution), resolution-1)
+        cell=yCell*resolution+xCell
+        print "cell", cell,
+        zone=zoneBase+cell
+        print "zone", zone
+        assert zone >= zoneBase and zone < zoneBase+resolution*resolution
+        return zone
+
+    def gridZoneList(self, x, y, zoneBase=0, zoneList=[], resolution=500):
+        """
+        x is a float in the range 0.0 to 1.0
+        y is a float in the range 0.0 to 1.0
+        resolution is the number of cells on each axsis.
+        returns a list of zone ids.
+        
+        Create a box of cell numbers, while clipping
+        to the edges of the set of cells.
+        """
+        if x < 0.0 or x > 1.0 or y < 0.0 or y > 1.0:
+            return None
+        resolution=int(resolution)
+        print "resolution", resolution,
+        xCell=min(int(x*resolution), resolution-1)
+        yCell=min(int(y*resolution), resolution-1)
+        cell=yCell*resolution+xCell
+        print "cell", cell,
+        zone=zoneBase+cell
+        print "zone", zone
+
+        zone=zone-2*resolution
+        endZone=zone+5*resolution
+        yCell=yCell-2
+        while zone < endZone:
+            if yCell >= 0 and yCell < resolution:
+                if xCell > 1:
+                    zoneList.append(zone-2)
+                    zoneList.append(zone-1)
+                elif xCell > 0:
+                    zoneList.append(zone-1)
+                r.append(zone)
+                if xCell < resolution-2:
+                    zoneList.append(zone+1)
+                    zoneList.append(zone+2)
+                elif xCell < resolution-1:
+                    zoneList.append(zone+1)
+            yCell+=1
+            zone+=resolution
+        return zoneList
+
+    def gridZone(self, zoneId, pos):
+        """
+        zoneId is an integer.
+        pos is a Vec3 with x,y,z float values.
+        
+        Figure out which zones in the multi-zone heirarchy
+        the avatar is currently.  Use sendSetZoneMsg() to
+        send the info to the server.
+        
+        So, one possibility is to use a 3x3 grid and have
+        each cell be the movement distance in the load time
+        plus the vision distance.
+        
+        Another possibility is to use a 5x5 grid and have
+        each cell be the greater of the movement distance
+        or the vision distance.
+        
+        Yet another possibility is to use a nxn grid inside
+        of a mxm grid.  The nxn grid is used to add cells
+        to the visible set, while the mxm grid is used to
+        retain old cells a little longer.  This avoids 
+        jitter (i.e. rapid generation and deletion of zones
+        as the avatar runs down the line separating two cells).
+        Also, the mxm grid is not neccessarily
+        full (and is likely not to be full).  So, cell in
+        the nxn grid are added and cells outside of the
+        mxm grid are removed.
+        
+        When choosing a method, the generation (inlcluding
+        loading and setup) time should be compared to the
+        cost of having extra distributed objects.
+        
+        The third option optimizes for expensive generation,
+        while the second option optimizes for epensive
+        maintenance.
+        
+        o o o o o o o 
+        o o o o o o o 
+        o o[k k o]o o 
+        o o|k a a|o o 
+        o o[o a a]o o 
+        o o o o o o o 
+        o o o o o o o 
+        """
+        # The teirs are offset from each other to spread the
+        # generates.
+        width=2000.0
+        height=2000.0
+        teirBase=1000
+        # The teirBase is a teir unto itself, all avatars in
+        # in the given teir system are also in the main teir:
+        r=[teirBase]
+        teirBase+=1
+        
+        x=pos.getX()/width
+        y=pos.getY()/height
+        getGridZones(x, y, teirBase, r, 500)
+        
+        return r
+
+        #*#
+        # The teirs are offset from each other to spread the
+        # generates.
+        width=2000.0
+        height=2000.0
+        teirs=[20, 100, 500]
+        teirOffsets=[0.33, 0.5, 0.0]
+        teirBase=1000
+        # The teirBase is a teir unto itself, all avatars in
+        # in the given teir system are also in the main teir:
+        r=[teirBase]
+        teirBase+=1
+        
+        x=pos.getX()
+        y=pos.getY()
+        for i, offset in zip(teirs, teirOffsets):
+            print "teirBase", teirBase,
+            xCell=min(int((x-width/i*offset)/i), i-1)
+            yCell=min(int((y-height/i*offset)/i), i-1)
+            print "xCell", xCell, "yCell", yCell,
+            cell=yCell*i+xCell
+            print "cell", cell,
+            zone=teirBase+cell
+            print "zone", zone
+            #for zone in range(teirBase+cell, teirBase+cell+5*i, i):
+            zone=zone-2*i
+            endZone=teirBase+cell+5*i
+            yCell=yCell-2
+            while zone < endZone:
+                if yCell >= 0 and yCell < i:
+                    if xCell > 1:
+                        r.append(zone-2)
+                        r.append(zone-1)
+                    elif xCell > 0:
+                        r.append(zone-1)
+                    r.append(zone)
+                    if xCell < i-2:
+                        r.append(zone+1)
+                        r.append(zone+2)
+                    elif xCell < i-1:
+                        r.append(zone+1)
+                yCell+=1
+                zone+=i
+            print ""
+            teirBase+=i*i
+        print "teirBase", teirBase
+        
+        return r
+
     def handleDatagram(self, di):
         if self.notify.getDebug():
             print "ClientRepository received datagram:"

+ 2 - 0
direct/src/distributed/MsgTypes.py

@@ -69,6 +69,8 @@ CLIENT_SET_AVTYPE =                          80
 CLIENT_GET_PET_DETAILS =                     81
 CLIENT_GET_PET_DETAILS_RESP =                82
 
+CLIENT_SET_WORLD_POS =                       83
+
 # These messages are ignored when the client is headed to the quiet zone
 QUIET_ZONE_IGNORED_LIST = [
 

+ 0 - 6
direct/src/particles/ParticleEffect.py

@@ -124,7 +124,6 @@ class ParticleEffect(NodePath):
                 particles.addForce(fg[i])
 
     def removeParticles(self, particles):
-        """removeParticles(particles)"""
         if (particles == None):
             self.notify.warning('removeParticles() - particles == None!')
             return
@@ -141,23 +140,18 @@ class ParticleEffect(NodePath):
             self.removeParticles(p)
 
     def getParticlesList(self):
-        """getParticles()"""
         return self.particlesDict.values()
     
     def getParticlesNamed(self, name):
-        """getParticlesNamed(name)"""
         return self.particlesDict.get(name, None)
 
     def getParticlesDict(self):
-        """getParticlesDict()"""
         return self.particlesDict
 
     def getForceGroupList(self):
-        """getForceGroup()"""
         return self.forceGroupDict.values()
 
     def getForceGroupNamed(self, name):
-        """getForceGroupNamed(name)"""
         return self.forceGroupDict.get(name, None)
 
     def getForceGroupDict(self):

+ 7 - 5
direct/src/particles/ParticleTest.py

@@ -1,4 +1,4 @@
-from direct.directbase.DirectStart import *
+from direct.directbase.TestStart import *
 
 from pandac.LinearVectorForce import LinearVectorForce
 from pandac.Vec3 import Vec3
@@ -10,15 +10,17 @@ import ForceGroup
 base.enableParticles()
 
 # ForceGroup
-gravity = LinearVectorForce(Vec3(0.0, 0.0, -10.0))
 fg = ForceGroup.ForceGroup()
-fg.addForce(gravity)
+if 0:
+    gravity = LinearVectorForce(Vec3(0.0, 0.0, -10.0))
+    fg.addForce(gravity)
 
 # Particle effect
 pe = ParticleEffect.ParticleEffect('particle-fx')
 pe.reparentTo(render)
-pe.setPos(0.0, 5.0, 4.0)
+#pe.setPos(0.0, 5.0, 4.0)
 pe.addForceGroup(fg)
 
 # Particle Panel
-pp = ParticlePanel.ParticlePanel(pe)
+#*#pp = ParticlePanel.ParticlePanel(pe)
+pp = ParticlePanel.ParticlePanel()

+ 3 - 13
direct/src/particles/Particles.py

@@ -34,8 +34,6 @@ class Particles(ParticleSystem.ParticleSystem):
     id = 1
 
     def __init__(self, name=None, poolSize=1024):
-        """__init__(name, poolSize)"""
-
         if (name == None):
             self.name = 'particles-%d' % Particles.id
             Particles.id += 1
@@ -80,14 +78,12 @@ class Particles(ParticleSystem.ParticleSystem):
         del self.emitter
 
     def enable(self):
-        """enable()"""
         if (self.fEnabled == 0):
             physicsMgr.attachPhysical(self)
             particleMgr.attachParticlesystem(self)
             self.fEnabled = 1
 
     def disable(self):
-        """disable()"""
         if (self.fEnabled == 1):
             physicsMgr.removePhysical(self)
             particleMgr.removeParticlesystem(self)
@@ -100,7 +96,6 @@ class Particles(ParticleSystem.ParticleSystem):
         return self.node
 
     def setFactory(self, type):
-        """setFactory(type)"""
         if (self.factoryType == type):
             return None
         if (self.factory):
@@ -119,7 +114,6 @@ class Particles(ParticleSystem.ParticleSystem):
         ParticleSystem.ParticleSystem.setFactory(self, self.factory)
 
     def setRenderer(self, type):
-        """setRenderer(type)"""
         if (self.rendererType == type):
             return None
         if (self.renderer):
@@ -188,14 +182,12 @@ class Particles(ParticleSystem.ParticleSystem):
         ParticleSystem.ParticleSystem.setEmitter(self, self.emitter)
 
     def addForce(self, force):
-        """addForce(force)"""
         if (force.isLinear()):
             self.addLinearForce(force)
         else:
             self.addAngularForce(force)
 
     def removeForce(self, force):
-        """removeForce(force)"""
         if (force == None):
             self.notify.warning('removeForce() - force == None!')
             return
@@ -209,20 +201,18 @@ class Particles(ParticleSystem.ParticleSystem):
 
     ## Getters ##
     def getName(self):
-        """getName()"""
         return self.name
+
     def getFactory(self):
-        """getFactory()"""
         return self.factory
+
     def getEmitter(self):
-        """getEmitter()"""
         return self.emitter
+
     def getRenderer(self):
-        """getRenderer()"""
         return self.renderer
 
     def printParams(self, file = sys.stdout, targ = 'self'):
-        """printParams(file, targ)"""
         file.write('# Particles parameters\n')
         file.write(targ + '.setFactory(\"' + self.factoryType + '\")\n')
         file.write(targ + '.setRenderer(\"' + self.rendererType + '\")\n')

+ 3 - 9
direct/src/showbase/ShowBase.py

@@ -979,8 +979,9 @@ class ShowBase(DirectObject.DirectObject):
 
         aspectRatio = self.getAspectRatio()
         # Scale the smiley face to 32x32 pixels.
-        lilsmiley.setScale(32.0 / self.win.getHeight() / aspectRatio,
-                           1.0, 32.0 / self.win.getHeight())
+        lilsmiley.setScale(
+            32.0 / self.win.getHeight() / aspectRatio,
+            1.0, 32.0 / self.win.getHeight())
         #self.mouseWatcherNode.setGeometry(mouseViz)
         
     def getAlt(self):
@@ -1272,7 +1273,6 @@ class ShowBase(DirectObject.DirectObject):
         The color may be either a VBase3 or a VBase4, or a 3-component
         tuple, or the individual r, g, b parameters.
         """
-
         if g != None:
             color = VBase4(r, g, b, 1.0)
         else:
@@ -1410,10 +1410,8 @@ class ShowBase(DirectObject.DirectObject):
         This is a toggle; the second time this function is called, it
         disables the mode.
         """
-
         # If oobeMode was never set, set it to false and create the
         # structures we need to implement OOBE.
-
         try:
             self.oobeMode
         except:
@@ -1438,7 +1436,6 @@ class ShowBase(DirectObject.DirectObject):
 
         if self.oobeMode:
             # Disable OOBE mode.
-
             if self.oobeCullFrustum != None:
                 # First, disable OOBE cull mode.
                 self.oobeCull()
@@ -1485,7 +1482,6 @@ class ShowBase(DirectObject.DirectObject):
         it were still attached to our original camera.  This allows us
         to visualize the effectiveness of our bounding volumes.
         """
-
         # First, make sure OOBE mode is enabled.
         try:
             if not self.oobeMode:
@@ -1509,7 +1505,6 @@ class ShowBase(DirectObject.DirectObject):
             # Tell the camera to cull from here instead of its own
             # origin.
             self.camNode.setCullCenter(self.oobeCullFrustum)
-
         else:
             # Disable OOBE culling.
 
@@ -1591,7 +1586,6 @@ class ShowBase(DirectObject.DirectObject):
                 # stop the music.
                 self.mainWinMinimized = 1
                 messenger.send('PandaPaused')
-
             elif not properties.getMinimized() and self.mainWinMinimized:
                 # If the main window is restored, throw an event to
                 # restart the music.

+ 1 - 1
direct/src/showbase/ShowBaseGlobal.py

@@ -2,7 +2,7 @@
 
 from ShowBase import *
 
-CollisionHandlerRayStart = 10.0 # This is a hack, it may be better to use a line instead of a ray.
+CollisionHandlerRayStart = 4000.0 # This is a hack, it may be better to use a line instead of a ray.
 
 # Create the showbase instance
 # This should be created by the game specific "start" file

+ 127 - 0
direct/src/showbase/showBase.cxx

@@ -87,3 +87,130 @@ query_fullscreen_testresult(int xsize, int ysize) {
   return false;
 }
 
+#if 0
+int TempGridZoneManager::
+add_grid_zone(unsigned int x, 
+              unsigned int y, 
+              unsigned int width, 
+              unsigned int height, 
+              unsigned int zoneBase, 
+              unsigned int xZoneResolution,
+              unsigned int yZoneResolution) {
+  // zoneBase is the first zone in the grid (e.g. the upper left)
+  // zoneResolution is the number of cells on each axsis.
+  // returns the next available zoneBase (i.e. zoneBase+xZoneResolution*yZoneResolution)
+  cerr<<"adding grid zone with a zoneBase of "<<zoneBase<<" and a zoneResolution of "<<zoneResolution;
+  _grids.append(TempGridZoneManager::GridZone(x, y, width, height, zoneBase, xZoneResolution, yZoneResolution));
+  return zoneBase+xZoneResolution*yZoneResolution;
+}
+
+void TempGridZoneManager::GridZone
+GridZone(unsigned int x, 
+         unsigned int y, 
+         unsigned int width, 
+         unsigned int height, 
+         unsigned int zoneBase, 
+         unsigned int xZoneResolution,
+         unsigned int yZoneResolution) {
+  _x=x;
+  _y=y;
+  _width=width;
+  _height=heigth; 
+  _zoneBase=zoneBase;
+  _xZoneResolution=xZoneResolution;
+  _yZoneResolution=yZoneResolution;
+  
+  // The cellVis is the number of cells radius that can
+  // be seen, including the center cell.  So, for a 5 x 5
+  // visible area, the cellVis is 3.
+  const float cellVis=3.0;
+  unsigned int xMargine=(unsigned int)((float)width/(float)xZoneResolution*cellVis+0.5);
+  unsigned int yMargine=(unsigned int)((float)height/(float)yZoneResolution*cellVis+0.5);
+  _xMinVis=x-xMargine;
+  _yMinVis=y-yMargine;
+  _xMaxVis=x+width+xMargine;
+  _yMaxVis=y+height+yMargine;
+}
+
+void TempGridZoneManager::
+get_grids(int x, int y) {
+  TempGridZoneManager::ZoneSet canSee;
+  TempGridZoneManager::GridSet::const_iterator i=_grids.begin();
+  for (; i!=_grids.end(); ++i) {
+    if (x >= i._xMinVis && x < i._xMaxVis && y >= i._yMinVis && y < i._yMaxVis) {
+      add_to_zone_list(i, x, y, canSee);
+    }
+  }
+}
+
+void TempGridZoneManager::
+add_to_zone_list(const TempGridZoneManager::GridZone &gridZone, 
+    unsigned int x,
+    unsigned int y,
+    TempGridZoneManager::ZoneSet &zoneSet) {
+  unsigned int xRes=gridZone._xZoneResolution;
+  unsigned int yRes=gridZone._yZoneResolution;
+  float xP=((float)(x-gridZone._x))/gridZone._width;
+  float yP=((float)(y-gridZone._y))/gridZone._height;
+  int xCell=(int)(xP*xRes);
+  int yCell=(int)(yP*yRes);
+
+  // range is how many cells can be seen in each direction:
+  const int range=2;
+  int yBegin=max(0, yCell-range);
+  int yEnd=min(yRes, yCell+range);
+  int xBegin=max(0, xCell-range);
+  int xEnd=min(xRes, xCell+range);
+  unsigned int zone=gridZone._zoneBase+yBegin*xRes+xBegin;
+
+  for (yCell=yBegin; yCell < yEnd; ++yCell) {
+    for (xCell=xBegin; xCell < xEnd; ++xCell) {
+      zoneSet.append(zone+xCell);
+    }
+    zone+=xRes;
+  }
+}
+
+int TempGridZoneManager::
+get_zone_list(int x, int y, int resolution) {
+  // x is a float in the range 0.0 to 1.0
+  // y is a float in the range 0.0 to 1.0
+  // resolution is the number of cells on each axsis.
+  // returns a list of zone ids.
+  // 
+  // Create a box of cell numbers, while clipping
+  // to the edges of the set of cells.
+  if (x < 0.0 || x > 1.0 || y < 0.0 || y > 1.0) {
+    return 0;
+  }
+  cerr<<"resolution="<<resolution;
+  xCell=min(int(x*resolution), resolution-1)
+  yCell=min(int(y*resolution), resolution-1)
+  cell=yCell*resolution+xCell
+  print "cell", cell,
+  zone=zoneBase+cell
+  print "zone", zone
+
+  zone=zone-2*resolution
+  endZone=zone+5*resolution
+  yCell=yCell-2
+  while zone < endZone:
+      if yCell >= 0 and yCell < resolution:
+          if xCell > 1:
+              zoneList.append(zone-2)
+              zoneList.append(zone-1)
+          elif xCell > 0:
+              zoneList.append(zone-1)
+          r.append(zone)
+          if xCell < resolution-2:
+              zoneList.append(zone+1)
+              zoneList.append(zone+2)
+          elif xCell < resolution-1:
+              zoneList.append(zone+1)
+      yCell+=1
+      zone+=resolution
+  return zoneList
+  return 5;
+}
+#endif
+

+ 38 - 0
direct/src/showbase/showBase.h

@@ -53,4 +53,42 @@ EXPCL_DIRECT bool query_fullscreen_testresult(int xsize, int ysize);
 
 END_PUBLISH
 
+
+#if 0
+class TempGridZoneManager {
+PUBLISHED:
+  TempGridZoneManager() {}
+  ~TempGridZoneManager() {}
+  
+  unsigned int add_grid_zone(
+      unsigned int x, 
+      unsigned int y, 
+      unsigned int width, 
+      unsigned int height, 
+      unsigned int zoneBase, 
+      unsigned int xZoneResolution,
+      unsigned int yZoneResolution);
+  int get_zone_list(int x, int y);
+
+protected:
+  class GridZone {
+  public:
+    unsigned int base;
+    unsigned int resolution;
+    GridZone(
+        unsigned int x, 
+        unsigned int y, 
+        unsigned int width, 
+        unsigned int height, 
+        unsigned int zoneBase, 
+        unsigned int xZoneResolution,
+        unsigned int yZoneResolution) {
+      base=zoneBase;
+      resolution=zoneResolution;
+    }
+  };
+  Set<GridZone> _grids;
+};
+#endif
+
 #endif