diff --git a/Doc/library/stackless/debugging.rst b/Doc/library/stackless/debugging.rst index b05a970ac85696..4a265a6a347144 100644 --- a/Doc/library/stackless/debugging.rst +++ b/Doc/library/stackless/debugging.rst @@ -39,152 +39,158 @@ ensure you enable tracing for all tasklets. This can be archived by the schedule callback. This callback sees every task switch. Here is a complete example:: - from stackless import * - import types - import traceback - - - # Named tasklets - def _tasklet__repr__(self): - try: - return "" % ("main" if self.is_main else self.name,) - except AttributeError: - return super(tasklet, self).__repr__() - tasklet.__repr__ = _tasklet__repr__ - - - class NamedTasklet(tasklet): - __slots__ = ["name"] - - def __new__(self, func, name=None): - t = tasklet.__new__(self, func) - if name is None: - name = "at %08x" % (id(t)) - t.name = name - return t - - - class Mutex(object): - "general purpose mutex class based on stackless.channels" - def __init__(self, capacity=1): - self.queue = channel() - self.capacity = capacity - - def isLocked(self): - '''return non-zero if locked''' - return self.capacity == 0 - - def lock(self): - '''acquire the lock''' - currentTasklet = stackless.getcurrent() - atomic = currentTasklet.set_atomic(True) - try: - if self.capacity: - self.capacity -= 1 - else: - self.queue.receive() - finally: - currentTasklet.set_atomic(atomic) - - def unlock(self): - '''release the lock''' - currentTasklet = stackless.getcurrent() - atomic = currentTasklet.set_atomic(True) - try: - if self.queue.balance < 0: - self.queue.send(None) - else: - self.capacity += 1 - finally: - currentTasklet.set_atomic(atomic) - - m = Mutex() - - - def task(): - name = getcurrent().name - print name, "acquiring" - m.lock() - print name, "switching" - schedule() - print name, "releasing" - m.unlock() - - - def trace_function(frame, event, arg): - if frame.f_code.co_name in ('schedule_cb', 'channel_cb'): - return None - print " trace_function: %s %s in %s, line %s" % \ - (stackless.current, event, frame.f_code.co_name, frame.f_lineno) - if event in ('call', 'line', 'exception'): - return trace_function - return None - - - def channel_cb(channel, tasklet, sending, willblock): - tf = tasklet.trace_function - try: - tasklet.trace_function = None - print "Channel CB, tasklet %r, %s%s" % \ - (tasklet, ("recv", "send")[sending], ("", " will block")[willblock]) - finally: - tasklet.trace_function = tf - - - def schedule_cb(prev, next): - current = stackless.getcurrent() - current_tf = current.trace_function - try: - current.trace_function = None - current_info = "Schedule CB, current %r, " % (current,) - if current_tf is None: - # also look at the previous frame, in case this callback is exempt - # from tracing - f_back = current.frame.f_back - if f_back is not None: - current_tf = f_back.f_trace - - if not prev: - print "%sstarting %r" % (current_info, next) - elif not next: - print "%sending %r" % (current_info, prev) - else: - print "%sjumping from %s to %s" % (current_info, prev, next) - prev_tf = current_tf if prev is current else prev.trace_function - next_tf = current_tf if next is current else next.trace_function - print " Current trace functions: prev: %r, next: %r" % \ - (prev_tf, next_tf) - if next is not None: - if not next.is_main: - tf = trace_function - else: - tf = None - print " Setting trace function for next: %r" % (tf,) - task = next.frame - if next is current: - task = task.f_back - while task is not None: - if isinstance(task, types.FrameType): - task.f_trace = tf - task = task.f_back - next.trace_function = tf - except: - traceback.print_exc() - finally: - current.trace_function = current_tf - - if __name__ == "__main__": - set_channel_callback(channel_cb) - set_schedule_callback(schedule_cb) - - NamedTasklet(task, "tick")() - NamedTasklet(task, "trick")() - NamedTasklet(task, "track")() - - run() - - set_channel_callback(None) - set_schedule_callback(None) + from __future__ import absolute_import, print_function + + import sys + import stackless + import traceback + + + class NamedTasklet(stackless.tasklet): + __slots__ = ("name",) + + def __init__(self, func, name=None): + stackless.tasklet.__init__(self, func) + if name is None: + name = "at %08x" % (id(self)) + self.name = name + + def __repr__(self): + return "" % (self.name) + + + class Mutex(object): + + def __init__(self, capacity=1): + self.queue = stackless.channel() + self.capacity = capacity + + def isLocked(self): + '''return non-zero if locked''' + return self.capacity == 0 + + def lock(self): + '''acquire the lock''' + currentTasklet = stackless.getcurrent() + atomic = currentTasklet.set_atomic(True) + try: + if self.capacity: + self.capacity -= 1 + else: + self.queue.receive() + finally: + currentTasklet.set_atomic(atomic) + + def unlock(self): + '''release the lock''' + currentTasklet = stackless.getcurrent() + atomic = currentTasklet.set_atomic(True) + try: + if self.queue.balance < 0: + self.queue.send(None) + else: + self.capacity += 1 + finally: + currentTasklet.set_atomic(atomic) + + m = Mutex() + + + def task(): + name = stackless.getcurrent().name + print(name, "acquiring") + m.lock() + print(name, "switching") + stackless.schedule() + print(name, "releasing") + m.unlock() + + + def trace_function(frame, event, arg): + if frame.f_code.co_name in ('schedule_cb', 'channel_cb'): + return None + print(" trace_function: %s %s in %s, line %s" % + (stackless.current, event, frame.f_code.co_name, frame.f_lineno)) + if event in ('call', 'line', 'exception'): + return trace_function + return None + + + def channel_cb(channel, tasklet, sending, willblock): + tf = tasklet.trace_function + try: + tasklet.trace_function = None + print("Channel CB, tasklet %r, %s%s" % + (tasklet, ("recv", "send")[sending], ("", " will block")[willblock])) + finally: + tasklet.trace_function = tf + + + def schedule_cb(prev, next): + # During a tasklet switch (during the execution of this function) the + # the result of stackless.getcurrent() is implementation defined. + # Therefore this function avoids any assumptions about the current tasklet. + current_tf = sys.gettrace() + try: + sys.settrace(None) # don't trace this callback + current_frame = sys._getframe() + if current_tf is None: + # also look at the previous frame, in case this callback is exempt + # from tracing + f_back = current_frame.f_back + if f_back is not None: + current_tf = f_back.f_trace + + current_info = "Schedule CB " + if not prev: + print("%sstarting %r" % (current_info, next)) + elif not next: + print("%sending %r" % (current_info, prev)) + else: + print("%sjumping from %s to %s" % (current_info, prev, next)) + + # Inform about the installed trace functions + prev_tf = current_tf if prev.frame is current_frame else prev.trace_function + next_tf = current_tf if next.frame is current_frame else next.trace_function + print(" Current trace functions: prev: %r, next: %r" % (prev_tf, next_tf)) + + # Eventually set a trace function + if next is not None: + if not next.is_main: + tf = trace_function + else: + tf = None + print(" Setting trace function for next: %r" % (tf,)) + # Set the "global" trace function for the tasklet + next.trace_function = tf + # Set the "local" trace function for each frame + # This is required, if the tasklet is already running + frame = next.frame + if frame is current_frame: + frame = frame.f_back + while frame is not None: + frame.f_trace = tf + frame = frame.f_back + except: + traceback.print_exc() + finally: + sys.settrace(current_tf) + + if __name__ == "__main__": + if len(sys.argv) > 1 and sys.argv[1] == 'hard': + stackless.enable_softswitch(False) + + stackless.set_channel_callback(channel_cb) + stackless.set_schedule_callback(schedule_cb) + + NamedTasklet(task, "tick")() + NamedTasklet(task, "trick")() + NamedTasklet(task, "track")() + + stackless.run() + + stackless.set_channel_callback(None) + stackless.set_schedule_callback(None) ------------------------- diff --git a/Doc/library/stackless/stackless.rst b/Doc/library/stackless/stackless.rst index e92f5749425ba0..d7e0d781e443f6 100644 --- a/Doc/library/stackless/stackless.rst +++ b/Doc/library/stackless/stackless.rst @@ -199,6 +199,13 @@ Callback related functions: The *prev* callback argument is the tasklet that was just running. The *next* callback argument is the tasklet that is going to run now. + + .. note:: + + During the execution of the scheduler callback the return value + of :func:`getcurrent` and the value of :attr:`current` are + implementation defined. You are not allowed to execute any methods, that + change the state of stackless for the current thread. .. function:: get_schedule_callback() diff --git a/Stackless/changelog.txt b/Stackless/changelog.txt index 5b1ffb0959f001..1f464de44110af 100644 --- a/Stackless/changelog.txt +++ b/Stackless/changelog.txt @@ -10,6 +10,10 @@ What's New in Stackless 3.X.X? *Release date: 20XX-XX-XX* +- https://bitbucket.org/stackless-dev/stackless/issue/83 + Fix demo/tracing.py: don't use flextype features. Unfortunately + it is no longer possible to change the __repr__ method of class tasklet. + - https://bitbucket.org/stackless-dev/stackless/issue/85 Fix a rare problem in the watchdog logic. diff --git a/Stackless/demo/fakechannel.py b/Stackless/demo/fakechannel.py index 0953ad06981a00..c388d1f1811619 100644 --- a/Stackless/demo/fakechannel.py +++ b/Stackless/demo/fakechannel.py @@ -19,7 +19,7 @@ def send(self, data): sender = stackless.current self.queue.append((sender, data)) self.balance += 1 - jump_off(sender) + stackless.schedule_remove() def receive(self): if self.balance > 0: @@ -31,16 +31,10 @@ def receive(self): receiver = stackless.current self.queue.append(receiver) self.balance -= 1 - jump_off(receiver) + stackless.schedule_remove() return self.temp -def jump_off(task): - stackless.tasklet().capture() - task.remove() - stackless.schedule() - - def f1(ch): for i in range(5): ch.send(i) diff --git a/Stackless/demo/fakechannel2.py b/Stackless/demo/fakechannel2.py index 570a2f11ff03a7..625664e35231c2 100644 --- a/Stackless/demo/fakechannel2.py +++ b/Stackless/demo/fakechannel2.py @@ -18,7 +18,7 @@ def send(self, data): sender = stackless.current self.queue.append(sender) self.balance += 1 - jump_off(sender, data) + stackless.schedule_remove(data) def receive(self): if self.balance > 0: @@ -32,16 +32,10 @@ def receive(self): receiver = stackless.current self.queue.append(receiver) self.balance -= 1 - retval = jump_off(receiver) + retval = stackless.schedule_remove() return retval -def jump_off(task, data=None): - stackless.tasklet().capture(data) - task.remove() - stackless.schedule() - - def f1(ch): for i in range(5): ch.send(i) diff --git a/Stackless/demo/paelike/PyOpenSteer/AbstractVehicle.py b/Stackless/demo/paelike/PyOpenSteer/AbstractVehicle.py deleted file mode 100644 index ddaf6cccfa2472..00000000000000 --- a/Stackless/demo/paelike/PyOpenSteer/AbstractVehicle.py +++ /dev/null @@ -1,93 +0,0 @@ -""" ----------------------------------------------------------------------------- - -OpenSteer -- Steering Behaviors for Autonomous Characters - -Copyright (c) 2002-2003, Sony Computer Entertainment America -Original author: Craig Reynolds - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - - ----------------------------------------------------------------------------- - -PyOpenSteer -- Port of OpenSteer to the Python(r) language - -Copyright (c) 2004 Lutz Paelike - -The license follows the original Opensteer license but must include -this additional copyright notice. ----------------------------------------------------------------------------- -""" - -from LocalSpace import AbstractLocalSpace - -class AbstractVehicle(AbstractLocalSpace): - group = [] - def mass(self): - """ """ - pass - - def setMass(self): - """ """ - pass - - def radius(self): - """ """ - pass - - def setRadius(self): - """ """ - pass - - def velocity(self): - """ """ - pass - - def speed(self): - """ """ - pass - - def setSpeed(self): - """ """ - pass -# - def predictFuturePosition(self): - """ """ - pass - - def maxForce(self): - """ """ - pass - - def setMaxForce(self): - """ """ - pass - - def velocity(self): - """ """ - pass - - def maxSpeed(self): - """ """ - pass - - def setMaxSpeed(self): - """ """ - pass diff --git a/Stackless/demo/paelike/PyOpenSteer/Camera.py b/Stackless/demo/paelike/PyOpenSteer/Camera.py deleted file mode 100644 index 66c65fc7344cb2..00000000000000 --- a/Stackless/demo/paelike/PyOpenSteer/Camera.py +++ /dev/null @@ -1,176 +0,0 @@ -""" ----------------------------------------------------------------------------- - -OpenSteer -- Steering Behaviors for Autonomous Characters - -Copyright (c) 2002-2003, Sony Computer Entertainment America -Original author: Craig Reynolds - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - - ----------------------------------------------------------------------------- - -PyOpenSteer -- Port of OpenSteer to the Python(r) language - -Copyright (c) 2004 Lutz Paelike - -The license follows the original Opensteer license but must include -this additional copyright notice. ----------------------------------------------------------------------------- -""" - -from vector import vec3 -import vector -import LocalSpace - -class Camera(LocalSpace.LocalSpace): - def __init__(self): - self.reset() - - def modeName(self): - """string naming current camera mode, used by SteerTest""" - pass - def reset(self): - """reset all camera state to default values""" - # reset camera's position and orientation - self.resetLocalSpace() - - # "look at" point, center of view - self.target = vec3(0.0) - # vehicle being tracked - self.vehicleToTrack = None - - # aim at predicted position of vehicleToTrack, this far into thefuture - self.aimLeadTime = 1.0 - - # make first update abrupt - self.smoothNextMove = False - - # relative rate at which camera transitions proceed - self.smoothMoveSpeed = 1.5 - - # select camera aiming mode - self.mode = cmFixed - - # "constant distance from vehicle" camera mode parameters - self.fixedDistDistance = 1.0 - self.fixedDistVOffset = 0.0 - - # "look straight down at vehicle" camera mode parameters - self.lookdownDistance = 30 - - # "static" camera mode parameters - self.fixedPosition = vec3(75.0, 75.0, 75.0) - self.fixedTarget = vec3(0.0) - self.fixedUp = vec3(vector.up) - - # "fixed local offset" camera mode parameters - self.fixedLocalOffset = vec3(5.0, 5.0, -5.0) - - # "offset POV" camera mode parameters - self.povOffset = vec3(0.0, 1.0, -3.0) - - def update(self,currentTime,elapsedTime,simulationPaused=False): - """per frame simulation update""" - pass - - def constDistHelper(self,elapsedTime): - """helper function for "drag behind" mode""" - pass - - def smoothCameraMove(self, newPosition, newTarget, newUp,elapsedTime): - """Smoothly move camera ...""" - pass - - def doNotSmoothNextMove(self): - """ """ - self.smoothNextMove = False - - def smoothNextMove(self): - """ """ - pass - - def smoothMoveSpeed(self): - """ """ - pass - - def mouseAdjustOffset(self): - """ """ - pass - - def mouseAdjust2(self): - """ """ - pass - - def mouseAdjustPolar(self): - """ """ - pass - - def mouseAdjustOrtho(self): - """ """ - pass - - def selectNextMode(self): - """select next camera mode, used by SteerTest""" - pass - - def successorMode(self): - """the mode that comes after the given mode (used by selectNextMode)""" - pass - - - - -def xxxls(self): - """ - # xxx since currently (10-21-02) the camera's Forward and Side basis - # xxx vectors are not being set, construct a temporary local space for - # xxx the camera view -- so as not to make the camera behave - # xxx differently (which is to say, correctly) during mouse adjustment. - """ - return LocalSpace.LocalSpace().regenerateOrthonormalBasis (target - position(), up()) - - -# marks beginning of list -cmStartMode = 0 - -# fixed global position and aimpoint -cmFixed = 1 - -# camera position is directly above (in global Up/Y) target -# camera up direction is target's forward direction -cmStraightDown = 2 - -# look at subject vehicle, adjusting camera position to be a -# constant distance from the subject -cmFixedDistanceOffset = 3 - -# camera looks at subject vehicle from a fixed offset in the -# local space of the vehicle (as if attached to the vehicle) -cmFixedLocalOffset = 4 - -# camera looks in the vehicle's forward direction, camera -# position has a fixed local offset from the vehicle. -cmOffsetPOV = 5 - -# cmFixedPositionTracking # xxx maybe? - -# marks the end of the list for cycling (to cmStartMode+1) -cmEndMode = 6 diff --git a/Stackless/demo/paelike/PyOpenSteer/Clock.py b/Stackless/demo/paelike/PyOpenSteer/Clock.py deleted file mode 100644 index a6871c11c8c37e..00000000000000 --- a/Stackless/demo/paelike/PyOpenSteer/Clock.py +++ /dev/null @@ -1,168 +0,0 @@ -""" ----------------------------------------------------------------------------- - -OpenSteer -- Steering Behaviors for Autonomous Characters - -Copyright (c) 2002-2003, Sony Computer Entertainment America -Original author: Craig Reynolds - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - - ----------------------------------------------------------------------------- - -PyOpenSteer -- Port of OpenSteer to the Python(r) language - -Copyright (c) 2004 Lutz Paelike - -The license follows the original Opensteer license but must include -this additional copyright notice. ----------------------------------------------------------------------------- -""" - -import time -import SteerTest - -class Clock: - def __init__(self): - # is simulation running or paused? - self.paused = False - - # the desired rate of frames per second, - # or zero to mean "as fast as possible" - self.targetFPS = 0 - # self.targetFPS = 30 - # self.targetFPS = 24 - - # real "wall clock" time since launch - self.totalRealTime = 0 - - # time simulation has run - self.totalSimulationTime = 0 - - # time spent paused - self.totalPausedTime = 0 - - # sum of (non-realtime driven) advances to simulation time - self.totalAdvanceTime = 0 - - # interval since last simulation time - self.elapsedSimulationTime = 0 - - # interval since last clock update time - self.elapsedRealTime = 0 - - # interval since last clock update, - # exclusive of time spent waiting for frame boundary when targetFPS>0 - self.elapsedNonWaitRealTime = 0 - - # "manually" advance clock by this amount on next update - self.newAdvanceTime = 0 - - # "Calendar time" in seconds and microseconds (obtained from - # the OS by gettimeofday) when this clock was first updated - self.baseRealTimeSec = 0 - self.baseRealTimeUsec = 0 - - def update(self): - """update this clock, called once per simulation step ("frame") to: - track passage of real time - manage passage of simulation time (modified by Paused state) - measure time elapsed between time updates ("frame rate") - optionally: "wait" for next realtime frame boundary - """ - # wait for next frame time (when required (when targetFPS>0)) - self.frameRateSync() - - # save previous real time to measure elapsed time - previousRealTime = self.totalRealTime - - # real "wall clock" time since this application was launched - self.totalRealTime = self.realTimeSinceFirstClockUpdate() - - # time since last clock update - self.elapsedRealTime = self.totalRealTime - previousRealTime - - # accumulate paused time - if (self.paused): self.totalPausedTime += self.elapsedRealTime - - # save previous simulation time to measure elapsed time - previousSimulationTime = self.totalSimulationTime - - # update total "manual advance" time - self.totalAdvanceTime += self.newAdvanceTime - - # new simulation time is total run time minus time spent paused - self.totalSimulationTime = (self.totalRealTime + self.totalAdvanceTime - self.totalPausedTime) - - # how much time has elapsed since the last simulation step? - - if self.paused: - self.elapsedSimulationTime = self.newAdvanceTime - else: - self.elapsedSimulationTime = (self.totalSimulationTime - previousSimulationTime) - - # reset advance amount - self.newAdvanceTime = 0 - - - - def frameRateSync(self): - """ - ---------------------------------------------------------------------------- - "wait" until next frame time (actually spin around this tight loop) - (xxx there are probably a smarter ways to do this (using events or - thread waits (eg usleep)) but they are likely to be unportable. xxx) - """ - - # when we are have a fixed target update rate (vs as-fast-as-possible) - if (self.targetFPS > 0): - # find next (real time) frame start time - targetStepSize = 1.0 / self.targetFPS - now = realTimeSinceFirstClockUpdate() - lastFrameCount = int((now / targetStepSize)) - nextFrameTime = (lastFrameCount + 1) * targetStepSize - - # record usage ("busy time", "non-wait time") for SteerTest app - self.elapsedNonWaitRealTime = now - self.totalRealTime - - # wait until next frame time - #do {} while (realTimeSinceFirstClockUpdate () < nextFrameTime); - # ##lp## dummy, implement something better - time.sleep(0.05) - -# ---------------------------------------------------------------------------- -# ("manually") force simulation time ahead, unrelated to the passage of -# real time, currently used only for SteerTest's "single step forward" - - - def advanceSimulationTime(self, seconds): - if (seconds < 0): - SteerTest.errorExit("negative arg to advanceSimulationTime.") - else: - self.newAdvanceTime += seconds; - - - def clockErrorExit(self): - SteerTest.errorExit("Problem reading system clock.\n") - - - def realTimeSinceFirstClockUpdate(self): - """replace this with a proper implementation """ - return 0.001 diff --git a/Stackless/demo/paelike/PyOpenSteer/ColorDefs.py b/Stackless/demo/paelike/PyOpenSteer/ColorDefs.py deleted file mode 100644 index f6a6f1219ebf11..00000000000000 --- a/Stackless/demo/paelike/PyOpenSteer/ColorDefs.py +++ /dev/null @@ -1,61 +0,0 @@ -""" ----------------------------------------------------------------------------- - -OpenSteer -- Steering Behaviors for Autonomous Characters - -Copyright (c) 2002-2003, Sony Computer Entertainment America -Original author: Craig Reynolds - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - - ----------------------------------------------------------------------------- - -PyOpenSteer -- Port of OpenSteer to the Python(r) language - -Copyright (c) 2004 Lutz Paelike - -The license follows the original Opensteer license but must include -this additional copyright notice. ----------------------------------------------------------------------------- -""" - -from vector import vec3 - -gBlack = vec3(0, 0, 0) -gWhite = vec3(1, 1, 1) - -gRed = vec3(1, 0, 0) -gYellow = vec3(1, 1, 0) -gGreen = vec3(0, 1, 0) -gCyan = vec3(0, 1, 1) -gBlue = vec3(0, 0, 1) -gMagenta = vec3(1, 0, 1) - -gOrange = vec3(1, 0.5, 0) - -gGray10 = vec3(0.1) -gGray20 = vec3(0.2) -gGray30 = vec3(0.3) -gGray40 = vec3(0.4) -gGray50 = vec3(0.5) -gGray60 = vec3(0.6) -gGray70 = vec3(0.7) -gGray80 = vec3(0.8) -gGray90 = vec3(0.9) diff --git a/Stackless/demo/paelike/PyOpenSteer/DeferredDrawing.py b/Stackless/demo/paelike/PyOpenSteer/DeferredDrawing.py deleted file mode 100644 index 0925bbeeb452b5..00000000000000 --- a/Stackless/demo/paelike/PyOpenSteer/DeferredDrawing.py +++ /dev/null @@ -1,107 +0,0 @@ -""" ----------------------------------------------------------------------------- - -OpenSteer -- Steering Behaviors for Autonomous Characters - -Copyright (c) 2002-2003, Sony Computer Entertainment America -Original author: Craig Reynolds - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - - ----------------------------------------------------------------------------- - -PyOpenSteer -- Port of OpenSteer to the Python(r) language - -Copyright (c) 2004 Lutz Paelike - -The license follows the original Opensteer license but must include -this additional copyright notice. ----------------------------------------------------------------------------- -""" - -import vector -from vector import vec3 - -index = 0 -# lutz: -# is not really necessary to have a size limit in Python(r) code -# as the list can dynamically grow -# we leave it for the moment to keep a maximum limit of deferred operations - -# Deferred operations (like drawing) would be a perfect candidate for Stackless -size = 2000 -deferredGraphicsArray = [] - -class DeferredLine: - startPoint = vec3() - endPoint = vec3() - color = vec3() - -class DeferredCircle: - radius = 1.0 - axis=vec3() - center=vec3() - color=vec3() - segments = 0 - filled = True - in3d = True - -def addDeferredLineToBuffer (s,e,c): - global index, deferredLineArray, size - if (index < size): - deferredGraphicsArray[index] = DeferredLine() - deferredGraphicsArray[index].startPoint = s - deferredGraphicsArray[index].endPoint = e - deferredGraphicsArray[index].color = c - index+=1 - else: - SteerTest.printWarning ("overflow in deferredDrawLine buffer") - -def addDeferredCircleToBuffer(radius, axis, center, color,segments, filled, in3d): - if (index < size): - deferredGraphicsArray[index] = DeferredCircle() - deferredGraphicsArray[index].radius = radius - deferredGraphicsArray[index].axis = axis - deferredGraphicsArray[index].center = center - deferredGraphicsArray[index].color = color - deferredGraphicsArray[index].segments = segments - deferredGraphicsArray[index].filled = filled - deferredGraphicsArray[index].in3d = in3d - index+=1 - else: - SteerTest.printWarning("overflow in deferredDrawCircle buffer") - - -def drawAll(): - """draw all lines in the buffer""" - global index, deferredLineArray - for i in range(index): - dg = deferredGraphicsArray[i] - if isinstance(dg,DeferredLine): - iDrawLine(dg.startPoint, dg.endPoint, dg.color) - elif isinstance(dg,DeferredCircle): - drawCircleOrDisk (dg.radius, dg.axis, dg.center, dg.color, dg.segments, dg.filled, dg.in3d) - # reset buffer index - index = 0 - -drawAllDeferredLines = drawAll -drawAllDeferredCirclesOrDisks = drawAll - -deferredDrawLine = addDeferredLineToBuffer \ No newline at end of file diff --git a/Stackless/demo/paelike/PyOpenSteer/Draw.py b/Stackless/demo/paelike/PyOpenSteer/Draw.py deleted file mode 100644 index b9d867fe83e39c..00000000000000 --- a/Stackless/demo/paelike/PyOpenSteer/Draw.py +++ /dev/null @@ -1,1066 +0,0 @@ -""" ----------------------------------------------------------------------------- - -OpenSteer -- Steering Behaviors for Autonomous Characters - -Copyright (c) 2002-2003, Sony Computer Entertainment America -Original author: Craig Reynolds - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - - ----------------------------------------------------------------------------- - -PyOpenSteer -- Port of OpenSteer to the Python(r) language - -Copyright (c) 2004 Lutz Paelike - -The license follows the original Opensteer license but must include -this additional copyright notice. ----------------------------------------------------------------------------- -""" - -from OpenGL.GL import * -from OpenGL.GLU import * -from OpenGL.GLUT import * - -from vector import vec3 -import vector - -import sys - -from Utilities import Accumulator - -##################################################### -import SteerTest -##################################################### - -from ColorDefs import gWhite - -# global vars - -appVersionName = 'PySteerTest 0.1' - -WIN_SCALE = 0.8 - -# The number of our GLUT window -windowID = 0 - -gMouseAdjustingCameraAngle = False -gMouseAdjustingCameraRadius = False -gMouseAdjustingCameraLastX = 0 -gMouseAdjustingCameraLastY= 0 - -gSmoothedFPS = Accumulator() -gSmoothedUsage = Accumulator() -gSmoothedTimerDraw = Accumulator() -gSmoothedTimerUpdate =Accumulator() -gSmoothedTimerOverhead = Accumulator() - - - -############# colors ############## - -from ColorDefs import * - -############################### -def display(): - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) - glCallList(1) - glutSwapBuffers() - -def initGL(): - """initialize GL mode settings""" - - # background = dark gray - glClearColor(0.3, 0.3, 0.3, 0) - - # enable depth buffer clears - glClearDepth (1.0) - - # select smooth shading - glShadeModel(GL_SMOOTH) - - # enable and select depth test - glDepthFunc(GL_LESS); - glEnable(GL_DEPTH_TEST) - - # turn on backface culling - glEnable(GL_CULL_FACE) - glCullFace(GL_BACK) - - # enable blending and set typical "blend into frame buffer" mode - glEnable(GL_BLEND) - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) - - # reset projection matrix - glMatrixMode(GL_PROJECTION) - glLoadIdentity() - -skipCount =10 - -def drawDisplayFPS(): - global skipCount - global gSmoothedFPS - - elapsedTime = SteerTest.clock.elapsedRealTime - if (elapsedTime > 0): - fps = 1/elapsedTime - else: - fps = 0 - - if (gSmoothedFPS == 0): - smoothRate = 1 - else: - smoothRate = (elapsedTime * 0.4) -""" - - # skip several frames to allow frame rate to settle - if (skipCount > 0): - skipCount-=1 - else: - # is there a "fixed frame rate target" or is it as-fast-as-possible? - targetFrameRate = (SteerTest.clock.targetFPS > 0) - - # "smooth" instantaneous FPS rate: start at current fps the first - # time through, then blend fps into a running average thereafter - blendIntoAccumulator(smoothRate, fps, gSmoothedFPS) - - # convert smoothed FPS value into labeled character string - if (SteerTest.clock.paused): - pausedStr = " Paused" - else: - pausedStr = "" - fpsStr = "fps: %d%s" % ( int(round (gSmoothedFPS)),pausedStr ) - - - # draw the string in white at the lower left corner of the window - lh = 16 - screenLocation1 = vec3(10, 10 + lh, 0) - draw2dTextAt2dLocation (fpsStr, screenLocation1, gWhite); - - # add "usage" message if fixed target frame rate is specified - if (targetFrameRate) - { - # run time per frame over target frame time (as a percentage) - const float usage = - ((100 * SteerTest::clock.elapsedNonWaitRealTime) / - (1.0f / SteerTest::clock.targetFPS)); - - # blend new usage value into running average - blendIntoAccumulator (smoothRate, usage, gSmoothedUsage); - - # create usage description character string - std::ostringstream usageStr; - usageStr << std::setprecision (0); - usageStr << std::setiosflags (std::ios::fixed); - usageStr << gSmoothedUsage << "% usage of 1/"; - usageStr << SteerTest::clock.targetFPS << " time step"; - usageStr << std::ends; - - # display message in lower left corner of window - # (draw in red if the instantaneous usage is 100% or more) - const Vec3 screenLocation2 (10, 10 + 2*lh, 0); - const Vec3 color = (usage >= 100) ? gRed : gGray60; - draw2dTextAt2dLocation (usageStr, screenLocation2, color); - } - - # get smoothed phase timer information - const float ptd = SteerTest::phaseTimerDraw(); - const float ptu = SteerTest::phaseTimerUpdate(); - const float pto = SteerTest::phaseTimerOverhead(); - blendIntoAccumulator (smoothRate, ptd, gSmoothedTimerDraw); - blendIntoAccumulator (smoothRate, ptu, gSmoothedTimerUpdate); - blendIntoAccumulator (smoothRate, pto, gSmoothedTimerOverhead); - - # display phase timer information - std::ostringstream timerStr; - timerStr << "update: "; - writePhaseTimerReportToStream (gSmoothedTimerUpdate, timerStr); - timerStr << "draw: "; - writePhaseTimerReportToStream (gSmoothedTimerDraw, timerStr); - timerStr << "other: "; - writePhaseTimerReportToStream (gSmoothedTimerOverhead, timerStr); - timerStr << std::ends; - const Vec3 screenLocation3 (10, lh * 7, 0); - draw2dTextAt2dLocation (timerStr, screenLocation3, gGreen); -""" - - - -def displayFunc(): - """ Main drawing function for SteerTest application, - drives simulation as a side effect""" - - # clear color and depth buffers - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) - - # run simulation and draw associated graphics - SteerTest.updateSimulationAndRedraw () - - # draw text showing (smoothed, rounded) "frames per second" rate - #drawDisplayFPS (); - - # draw the name of the selected PlugIn - drawDisplayPlugInName () - - # draw the name of the camera's current mode - drawDisplayCameraModeName () - - # draw crosshairs to indicate aimpoint (xxx for debugging only?) - drawReticle () - - # check for errors in drawing module, if so report and exit - # checkForDrawError ("SteerTest::updateSimulationAndRedraw") - - # double buffering, swap back and front buffers - glFlush () - glutSwapBuffers() - -# do all initialization related to graphics - -def keyboardFunc(key, x, y): - #std::ostringstream message; - - # ascii codes - tab_key = 9; - space_key = 32; - esc_key = 27; # escape key - """ - # reset selected PlugIn - if key=='r': - SteerTest::resetSelectedPlugIn (); - p"reset PlugIn " - << '"' << SteerTest::nameOfSelectedPlugIn () << '"' - << std::ends; - SteerTest::printMessage (message); - - # cycle selection to next vehicle - case 's': - SteerTest::printMessage ("select next vehicle/agent"); - SteerTest::selectNextVehicle (); - break; - - # camera mode cycle - case 'c': - SteerTest::camera.selectNextMode (); - message << "select camera mode " - << '"' << SteerTest::camera.modeName () << '"' << std::ends; - SteerTest::printMessage (message); - break; - - # select next PlugIn - case tab: - SteerTest::selectNextPlugIn (); - message << "select next PlugIn: " - << '"' << SteerTest::nameOfSelectedPlugIn () << '"' - << std::ends; - SteerTest::printMessage (message); - break; - - # toggle annotation state - case 'a': - SteerTest::printMessage (SteerTest::toggleAnnotationState () ? - "annotation ON" : "annotation OFF"); - break; - - # toggle run/pause state - case space: - SteerTest::printMessage (SteerTest::clock.togglePausedState () ? - "pause" : "run"); - break; - - # cycle through frame rate presets - case 'f': - message << "set frame rate to " - << selectNextPresetFrameRate () << std::ends; - SteerTest::printMessage (message); - break; - - # print minimal help for single key commands - case '?': - SteerTest::keyboardMiniHelp (); - break; - - # exit application with normal status - case esc: - glutDestroyWindow (windowID); - SteerTest::printMessage ("exit."); - SteerTest::exit (0); - - default: - message << "unrecognized single key command: " << key; - message << " (" << (int)key << ")";#xxx perhaps only for debugging? - message << std::ends; - SteerTest::printMessage (""); - SteerTest::printMessage (message); - SteerTest::keyboardMiniHelp (); - } - """ - - -def initializeGraphics(args): - global appVersionName - # initialize GLUT state based on command line arguments - glutInit(args) - - # display modes: RGB+Z and double buffered - mode = GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE - glutInitDisplayMode(mode) - - # create and initialize our window with GLUT tools - # (center window on screen with size equal to "ws" times screen size) - sw = glutGet(GLUT_SCREEN_WIDTH) - sh = glutGet(GLUT_SCREEN_HEIGHT) - ws = 0.8 # window_size / screen_size - ww = int((sw * ws)) - wh = int((sh * ws)) - glutInitWindowPosition(int(sw * (1-ws)/2), int(sh * (1-ws)/2)) - glutInitWindowSize (ww, wh) - windowID = glutCreateWindow (appVersionName) - reshapeFunc (ww, wh) - initGL() - - # register our display function, make it the idle handler too - glutDisplayFunc(displayFunc) - glutIdleFunc(displayFunc) - - # register handler for window reshaping - glutReshapeFunc(reshapeFunc) - - # register handler for keyboard events - glutKeyboardFunc(keyboardFunc) - glutSpecialFunc (specialFunc) - - # register handler for mouse button events - glutMouseFunc (mouseButtonFunc) - - # register handler to track mouse motion when any button down - glutMotionFunc (mouseMotionFunc) - - # register handler to track mouse motion when no buttons down - glutPassiveMotionFunc (mousePassiveMotionFunc) - - # register handler for when mouse enters or exists the window - glutEntryFunc (mouseEnterExitWindowFunc) - - -def specialFunc(key,x,y): - pass - - -def reshapeFunc(width,height): - #set viewport to full window - glViewport(0, 0, width, height) - # set perspective transformation - glMatrixMode (GL_PROJECTION) - #determine aspect ratio - aRatio = 1 - if height!=0: aRatio = float(width)/float(height) - #load identity matrix to reset view - glLoadIdentity() - fieldOfViewY = 45.0 - zNear = 1 - zFar = 400 - gluPerspective (fieldOfViewY, aRatio, zNear, zFar) - # leave in modelview mode - glMatrixMode(GL_MODELVIEW) - -####### mouse handlers ########### - -def mouseButtonFunc(button, state, x, y): - """This is called (by GLUT) each time a mouse button pressed or released""" - global gMouseAdjustingCameraAngle - global gMouseAdjustingCameraRadius - global gMouseAdjustingCameraLastX - global gMouseAdjustingCameraLastY - - macosx = False - - # if the mouse button has just been released - if (state == GLUT_UP): - # end any ongoing mouse-adjusting-camera session - gMouseAdjustingCameraAngle = False - gMouseAdjustingCameraRadius = False - - # if the mouse button has just been pushed down - if (state == GLUT_DOWN): - # names for relevant values of "button" and "state" - mods = glutGetModifiers () - modNone = (mods == 0) - modCtrl = (mods == GLUT_ACTIVE_CTRL) - modAlt = (mods == GLUT_ACTIVE_ALT) - modCtrlAlt = (mods == (GLUT_ACTIVE_CTRL | GLUT_ACTIVE_ALT)) - mouseL = (button == GLUT_LEFT_BUTTON) - mouseM = (button == GLUT_MIDDLE_BUTTON) - mouseR = (button == GLUT_RIGHT_BUTTON) - - - # mouse-left (with no modifiers): select vehicle - if (modNone & mouseL): - pass - # SteerTest::selectVehicleNearestScreenPosition (x, y); - - - # control-mouse-left: begin adjusting camera angle - # (on Mac OS X control-mouse maps to mouse-right for "context menu", - # this makes SteerTest's control-mouse work work the same on OS X as - # on Linux and Windows, but it precludes using a mouseR context menu) - if ((modCtrl & mouseL) | (modNone & mouseR & macosx)): - gMouseAdjustingCameraLastX = x - gMouseAdjustingCameraLastY = y - gMouseAdjustingCameraAngle = True - - - # control-mouse-middle: begin adjusting camera radius - # (same for: control-alt-mouse-left and control-alt-mouse-middle, - # and on Mac OS X it is alt-mouse-right) - if ((modCtrl & mouseM) | - (modCtrlAlt & mouseL) | - (modCtrlAlt & mouseM) | - (modAlt & mouseR & macosx)): - - gMouseAdjustingCameraLastX = x - gMouseAdjustingCameraLastY = y - gMouseAdjustingCameraRadius = True - - ########### Finish - -def mouseMotionFunc(x, y): - """called when mouse moves and any buttons are down""" - global gMouseAdjustingCameraLastX - global gMouseAdjustingCameraLastY - - # are we currently in the process of mouse-adjusting the camera? - if (gMouseAdjustingCameraAngle | gMouseAdjustingCameraRadius): - # speed factors to map from mouse movement in pixels to 3d motion - dSpeed = 0.005 - rSpeed = 0.01 - - # XY distance (in pixels) that mouse moved since last update - dx = x - gMouseAdjustingCameraLastX - dy = y - gMouseAdjustingCameraLastY - gMouseAdjustingCameraLastX = x - gMouseAdjustingCameraLastY = y - - cameraAdjustment = vec3() - - # set XY values according to mouse motion on screen space - if (gMouseAdjustingCameraAngle): - cameraAdjustment.x = dx * -1.0 * Speed - cameraAdjustment.y = dy * + dSpeed - - # set Z value according vertical to mouse motion - if (gMouseAdjustingCameraRadius): - cameraAdjustment.z = dy * rSpeed; - - # pass adjustment vector to camera's mouse adjustment routine - # SteerTest::camera.mouseAdjustOffset (cameraAdjustment); - -def mousePassiveMotionFunc(x,y): - SteerTest.mouseX = x - SteerTest.mouseY = y - -def mouseEnterExitWindowFunc(state): - """called when mouse enters or exits the window""" - if (state == GLUT_ENTERED): SteerTest.mouseInWindow = True - if (state == GLUT_LEFT): SteerTest.mouseInWindow = False - -def drawDisplayPlugInName(): - - h = glutGet(GLUT_WINDOW_HEIGHT) - - screenLocation = vec3(10, h-20, 0) - draw2dTextAt2dLocation("Python Plugin", screenLocation, gWhite) - -def drawDisplayCameraModeName(): - """raw camera mode name in lower lefthand corner of screen""" - message = "Camera %s\n" % (SteerTest.camera.modeName()) - - screenLocation =vec3(10, 10, 0) - draw2dTextAt2dLocation(message, screenLocation, gWhite) - - -def warnIfInUpdatePhase2(name): - message= "use annotation (during simulation update, do not call %s)" % (name) - SteerTest.printWarning (message); - - -################ drawing helper functions ###### -def iglVertexVec3(v): - glVertex3f (v.x, v.y, v.z) - -glVertexVec3 = iglVertexVec3 - -# - - -def iDrawLine(startPoint, endPoint, color): - """draw 3d "graphical annotation" lines, used for debugging""" - warnIfInUpdatePhase ("iDrawLine"); - glColor3f (color.x, color.y, color.z); - glBegin (GL_LINES); - glVertexVec3 (startPoint); - glVertexVec3 (endPoint); - glEnd (); - - -drawLine = iDrawLine - - -def drawLineAlpha(startPoint, endPoint, color,alpha): - """ - draw a line with alpha blending - - see also glAlphaFunc - glBlendFunc (GL_SRC_ALPHA) - glEnable (GL_BLEND) - """ - - warnIfInUpdatePhase("drawLineAlpha") - glColor4f (color.x, color.y, color.z, alpha) - glBegin (GL_LINES) - glVertexVec3(startPoint) - glVertexVec3(endPoint) - glEnd() - -def iDrawTriangle(a,b,c,color): - """ """ - warnIfInUpdatePhase("iDrawTriangle") - glColor3f(color.x, color.y, color.z) - glBegin(GL_TRIANGLES) - - glVertexVec3(a) - glVertexVec3(b) - glVertexVec3(c) - - glEnd() - -def iDrawQuadrangle(a,b,c,d,color): - """Draw a single OpenGL quadrangle given four Vec3 vertices, and color.""" - warnIfInUpdatePhase("iDrawTriangle") - glColor3f(color.x, color.y, color.z) - glBegin(GL_QUADS) - - glVertexVec3(a) - glVertexVec3(b) - glVertexVec3(c) - glVertexVec3(d) - - glEnd() - -drawQuadrangle = iDrawQuadrangle - - - - -def beginDoubleSidedDrawing(): - """ - Between matched sets of these two calls, assert that all polygons - will be drawn "double sided", that is, without back-face culling - """ - glPushAttrib(GL_ENABLE_BIT) - glDisable(GL_CULL_FACE) - - -def endDoubleSidedDrawing(): - glPopAttrib() - - -################### - - - - -def drawCircleOrDisk(radius, axis, center, color, segments, filled, in3d=True): - """ - General purpose circle/disk drawing routine. Draws circles or disks (as - specified by "filled" argument) and handles both special case 2d circles - on the XZ plane or arbitrary circles in 3d space (as specified by "in3d" - argument) - """ - ls = LocalSpace() - if (in3d): - # define a local space with "axis" as the Y/up direction - # (XXX should this be a method on LocalSpace?) - unitAxis = axis.normalize() - unitPerp = findPerpendicularIn3d(axis).normalize() - ls.setUp(unitAxis) - ls.setForward(unitPerp) - ls.setPosition(center) - ls.setUnitSideFromForwardAndUp() - - # make disks visible (not culled) from both sides - if (filled): beginDoubleSidedDrawing() - - # point to be rotated about the (local) Y axis, angular step size - pointOnCircle = vec3(radius, 0, 0) - step = (2 * M_PI) / segments - - # set drawing color - glColor3f(color.x, color.y, color.z) - - # begin drawing a triangle fan (for disk) or line loop (for circle) - if filled: - glBegin (GL_TRIANGLE_FAN) - # for the filled case, first emit the center point - if in3d: - iglVertexVec3(ls.position()) - else: - iglVertexVec3(center) - vertexCount = segments+1 - else: - glBegin (GL_LINE_LOOP) - vertexCount = segments - - - # rotate p around the circle in "segments" steps - sin=0.0 - cos=0.0 - - for i in range(vertexCount): - # emit next point on circle, either in 3d (globalized out - # of the local space), or in 2d (offset from the center) - if in3d: - iglVertexVec3(ls.globalizePosition(pointOnCircle)) - else: - iglVertexVec3((pointOnCircle + center)) - - # rotate point one more step around circle - # LP: changed interface to the Python(r) way - pointOnCircle, sin, cos = pointOnCircle.rotateAboutGlobalY(step, sin, cos) - - - # close drawing operation - glEnd() - if (filled): endDoubleSidedDrawing() - -# The Python(r) language makes it not necessary to implement draw3dCircleOrDisk properly -# we just use default parameters and make it an alias -draw3dCircleOrDisk = drawCircleOrDisk - -def drawCircleOrDisk(radius, center, color, segments, filled): - """drawing utility used by both drawXZCircle and drawXZDisk""" - - #draw a circle-or-disk on the XZ plane - drawCircleOrDisk (radius, vector.zero, center, color, segments, filled, False) - - - -def drawBasic2dCircularVehicle(vehicle,color): - """a simple 2d vehicle on the XZ plane""" - - # "aspect ratio" of body (as seen from above) - x = 0.5 - y = math.sqrt(1 - (x * x)) - - # radius and position of vehicle - r = vehicle.radius() - p = vehicle.position() - - # shape of triangular body - u = r * 0.05 * vector.up # slightly up - f = r * vehicle.forward() - s = r * vehicle.side() * x - b = r * vehicle.forward() * -y - - # draw double-sided triangle (that is: no (back) face culling) - beginDoubleSidedDrawing() - iDrawTriangle( (p + f + u), (p + b - s + u), (p + b + s + u), color) - endDoubleSidedDrawing() - - # draw the circular collision boundary - drawXZCircle (r, p + u, gWhite, 20) - -def drawBasic3dSphericalVehicle(vehicle, color): - """a simple 3d vehicle""" - #"aspect ratio" of body (as seen from above) - x = 0.5 - y = math.sqrt(1 - (x * x)) - - # radius and position of vehicle - r = vehicle.radius() - p = vehicle.position() - - # body shape parameters - f = r * vehicle.forward() - s = r * vehicle.side() * x - u = r * vehicle.up() * x * 0.5 - b = r * vehicle.forward() * -1.0 *y - - # vertex positions - nose = p + f - side1 = p + b - s - side2 = p + b + s - top = p + b + u - bottom = p + b - u - - # colors - j = 0.05 - k = -0.05 - color1 = color + Vec3 (j, j, k) - color2 = color + Vec3 (j, k, j) - color3 = color + Vec3 (k, j, j) - color4 = color + Vec3 (k, j, k) - color5 = color + Vec3 (k, k, j) - - # draw body - iDrawTriangle(nose, side1, top, color1) # top, side 1 - iDrawTriangle(nose, top, side2, color2) # top, side 2 - iDrawTriangle(nose, bottom, side1, color3) # bottom, side 1 - iDrawTriangle(nose, side2, bottom, color4) # bottom, side 2 - iDrawTriangle(side1, side2, top, color5) # top back - iDrawTriangle(side2, side1, bottom, color5) # bottom back - - - -def drawXZCheckerboardGrid (size, subsquares,center,color1,color2): - half = float(size)/2 - spacing = float(size) / subsquares - - beginDoubleSidedDrawing() - - flag1 = false - p = -half - corner = vec3() - for i in range(subsquares): - flag2 = flag1 - q = -half - for j in range(subsquares): - corner.set (p, 0, q) - corner += center - if flag2: - col = color1 - else: - col = color2 - iDrawQuadrangle (corner, corner + Vec3 (spacing, 0, 0), - corner + Vec3 (spacing, 0, spacing), - corner + Vec3 (0, 0, spacing), col ) - flag2 = not flag2 - q += spacing - - flag1 = not flag1 - p += spacing - - endDoubleSidedDrawing() - - -def drawXZLineGrid(size,subsquares,center,color): - """ - draw a square grid of lines on the XZ (horizontal) plane. - - ("size" is the length of a side of the overall grid, "subsquares" is the - number of subsquares along each edge (for example a standard checkboard - has eight), "center" is the 3d position of the center of the grid, lines - are drawn in the specified "color".) - """ - - warnIfInUpdatePhase ("drawXZLineGrid") - - half = size/2 - spacing = size / subsquares - - # set grid drawing color - glColor3f (color.x, color.y, color.z) - - # draw a square XZ grid with the given size and line count - glBegin(GL_LINES) - q = -1 * half - for i in range(subsquares + 1): - x1 = vec3(q, 0, half) # along X parallel to Z - x2 = vec3(q, 0, -1*half) - z1 = vec3(half, 0, q) # along Z parallel to X - z2 = vec3(-1*half, 0, q) - - iglVertexVec3 (x1 + center) - iglVertexVec3 (x2 + center) - iglVertexVec3 (z1 + center) - iglVertexVec3 (z2 + center) - - q += spacing - glEnd() - - - - -def drawAxes(ls,size,color): - """ - draw the three axes of a LocalSpace: three lines parallel to the - basis vectors of the space, centered at its origin, of lengths - given by the coordinates of "size". - """ - x = vec3(size.x / 2, 0, 0) - y = vec3(0, size.y / 2, 0) - z = vec3(0, 0, size.z / 2) - - iDrawLine(ls.globalizePosition(x), ls.globalizePosition (x * -1), color) - iDrawLine(ls.globalizePosition(y), ls.globalizePosition (y * -1), color) - iDrawLine(ls.globalizePosition(z), ls.globalizePosition (z * -1), color) - - -def drawBoxOutline(localSpace,size,color): - """ - draw the edges of a box with a given position, orientation, size - and color. The box edges are aligned with the axes of the given - LocalSpace, and it is centered at the origin of that LocalSpace. - "size" is the main diagonal of the box. - - use gGlobalSpace to draw a box aligned with global space - """ - - s = size / 2.0 # half of main diagonal - - a = vec3(+s.x, +s.y, +s.z) - b = vec3(+s.x, -1*s.y, +s.z) - c = vec3(-1.0*s.x, -1.0*s.y, +s.z) - d = vec3(-1.0*s.x, +s.y, +s.z) - - e = vec3(+s.x, +s.y, -1.0*s.z) - f = vec3(+s.x, -1.0*s.y, -1.0*s.z) - g = vec3(-1.0*s.x, -1.0*s.y, -1.0*s.z) - h = vec3(-1.0*s.x, +s.y, -1.0*s.z) - - A = localSpace.globalizePosition (a) - B = localSpace.globalizePosition (b) - C = localSpace.globalizePosition (c) - D = localSpace.globalizePosition (d) - - E = localSpace.globalizePosition (e) - F = localSpace.globalizePosition (f) - G = localSpace.globalizePosition (g) - H = localSpace.globalizePosition (h) - - - -def drawCameraLookAtCheck (cameraPosition,pointToLookAt,up): - """this comes up often enough to warrant its own warning function""" - view = pointToLookAt - cameraPosition - perp = view.perpendicularComponent (up) - - # LP: is this a test for object equality or for containin data - if (perp == vector.zero): - SteerTest.printWarning ("LookAt: degenerate camera") - -def drawCameraLookAt (cameraPosition,pointToLookAt,up): - """ - Define scene's camera (viewing transformation) in terms of the camera's - position, the point to look at (an "aim point" in the scene which will - end up at the center of the camera's view), and an "up" vector defining - the camera's "roll" around the "view axis" between cameraPosition and - pointToLookAt (the image of the up vector will be vertical in the - camera's view). - """ - # check for valid "look at" parameters - drawCameraLookAtCheck (cameraPosition, pointToLookAt, up) - - # use LookAt from OpenGL Utilities - glLoadIdentity() - gluLookAt(cameraPosition.x, cameraPosition.y, cameraPosition.z, - pointToLookAt.x, pointToLookAt.y, pointToLookAt.z, - up.x, up.y, up.z) - - -def draw2dLine(startPoint, endPoint, color): - """draw 2d lines in screen space: x and y are the relevant coordinates""" - originalMatrixMode = begin2dDrawing() - try: - iDrawLine(startPoint, endPoint, color) - except: - pass - end2dDrawing (originalMatrixMode) - -def drawReticle(): - """ - draw a reticle at the center of the window. Currently it is small - crosshair with a gap at the center, drawn in white with black borders - """ - - a = 10; - b = 30; - w = glutGet(GLUT_WINDOW_WIDTH) * 0.5 - h = glutGet(GLUT_WINDOW_HEIGHT) * 0.5 - - draw2dLine(vec3 (w+a, h, 0), vec3 (w+b, h, 0), gWhite) - draw2dLine(vec3 (w, h+a, 0), vec3 (w, h+b, 0), gWhite) - draw2dLine(vec3 (w-a, h, 0), vec3 (w-b, h, 0), gWhite) - draw2dLine(vec3 (w, h-a, 0), vec3 (w, h-b, 0), gWhite) - - glLineWidth(3) - draw2dLine(vec3 (w+a, h, 0), vec3 (w+b, h, 0), gBlack) - draw2dLine(vec3 (w, h+a, 0), vec3 (w, h+b, 0), gBlack) - draw2dLine(vec3 (w-a, h, 0), vec3 (w-b, h, 0), gBlack) - draw2dLine(vec3 (w, h-a, 0), vec3 (w, h-b, 0), gBlack) - glLineWidth(1) - - - - -def checkForGLError(locationDescription): - """OpenGL-specific routine for error check, report, and exit""" - # normally (when no error) just return - lastGlError = glGetError() - if (lastGlError == GL_NO_ERROR): return - - # otherwise print vaguely descriptive error message, then exit - - if lastGlError==GL_INVALID_ENUM: - errStr = "GL_INVALID_ENUM" - elif lastGlError==GL_INVALID_VALUE: - errStr = "GL_INVALID_VALUE" - elif lastGlError==GL_INVALID_OPERATION: - errStr = "GL_INVALID_OPERATION" - elif lastGlError==GL_STACK_OVERFLOW: - errStr = "GL_STACK_OVERFLOW" - elif lastGlError==GL_STACK_UNDERFLOW: - errStr = "GL_STACK_UNDERFLOW" - elif lastGlError==GL_OUT_OF_MEMORY: - errStr = "GL_OUT_OF_MEMORY" - elif lastGlError==GL_TABLE_TOO_LARGE: - errStr = "GL_TABLE_TOO_LARGE" - - - - if (locationDescription!=None & locationDescription!=""): - ld = " in " +locationDescription - else: - ld = "" - - print "SteerTest: OpenGL error ", errStr, ld - - SteerTest.exit(1) - -def checkForDrawError(locationDescription): - """check for errors during redraw, report any and then exit""" - checkForGLError (locationDescription) - -def drawGetWindowHeight(): - """accessors for GLUT's window dimensions""" - return glutGet(GLUT_WINDOW_HEIGHT) -def drawGetWindowWidth(): - """accessors for GLUT's window dimensions""" - return glutGet(GLUT_WINDOW_WIDTH) - -import DeferredLine -################ General OpenGL drawing helper functions ###### - -def begin2dDrawing(): - # store OpenGL matrix mode - originalMatrixMode = glGetIntegerv (GL_MATRIX_MODE) - - # clear projection transform - glMatrixMode(GL_PROJECTION) - glPushMatrix() - glLoadIdentity() - - # set up orthogonal projection onto window's screen space - w = glutGet(GLUT_WINDOW_WIDTH) - h = glutGet(GLUT_WINDOW_HEIGHT) - glOrtho(0.0, w, 0.0, h, -1.0, 1.0) - - # clear model transform - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glLoadIdentity() - - # return original matrix mode for saving (stacking) - return(originalMatrixMode) - -def end2dDrawing(originalMatrixMode): - # restore previous model/projection transformation state - glPopMatrix() - glMatrixMode(GL_PROJECTION) - glPopMatrix() - - # restore OpenGL matrix mode - glMatrixMode(originalMatrixMode) - - -def draw2dTextAt3dLocation (text, location, color): - import sys - # XXX NOTE: "it would be nice if" this had a 2d screenspace offset for - # the origin of the text relative to the screen space projection of - # the 3d point. - - # set text color and raster position - glColor3f(color.x, color.y, color.z) - glRasterPos3f(location.x, location.y, location.z) - - # switch into 2d screen space in case we need to handle a new-line - rasterPosition = glGetIntegerv(GL_CURRENT_RASTER_POSITION) - #originalMatrixMode = begin2dDrawing() - - #xxx uncommenting this causes the "2d" version to print the wrong thing - #xxx with it out the first line of a multi-line "3d" string jiggles - #glRasterPos2i (rasterPosition[0], rasterPosition[1]); - - fontHeight = 15 - lines = 0 - for character in text: - if character == '\n': - glRasterPos2i(x, y-(lines*fontHeight)) - lines+=1 - else: - glutBitmapCharacter(GLUT_BITMAP_9_BY_15, ord(character)); - - # loop over each character in string (until null terminator) - - # switch back out of 2d screen space - #end2dDrawing(originalMatrixMode) - - -def draw2dTextAt2dLocation (text, location, color): - originalMatrixMode = begin2dDrawing() - #print "Start: ", originalMatrixMode - - # draw text at specified location (which is now interpreted as - # relative to screen space) and color - try: - draw2dTextAt3dLocation (text, location, color) - except: - pass - end2dDrawing(originalMatrixMode) - #print "End: ", originalMatrixMode - - -def main(): - - screen_width = int(WIN_SCALE*glutGet(GLUT_SCREEN_WIDTH)) - screen_height = int(WIN_SCALE*glutGet(GLUT_SCREEN_HEIGHT)) - - glutInitWindowSize(screen_width, screen_height) - glutCreateWindow('PySteerTest') - - glutDisplayFunc(display) - - - - -def runGraphics(): - """run graphics event loop""" - glutMainLoop() - -if __name__ == '__main__': - try: - GLU_VERSION_1_2 - except: - print "Need GLU 1.2 to run this demo" - sys.exit(1) - main() - glutMainLoop() - diff --git a/Stackless/demo/paelike/PyOpenSteer/LocalSpace.py b/Stackless/demo/paelike/PyOpenSteer/LocalSpace.py deleted file mode 100644 index 5a16b164676530..00000000000000 --- a/Stackless/demo/paelike/PyOpenSteer/LocalSpace.py +++ /dev/null @@ -1,205 +0,0 @@ -""" ----------------------------------------------------------------------------- - -OpenSteer -- Steering Behaviors for Autonomous Characters - -Copyright (c) 2002-2003, Sony Computer Entertainment America -Original author: Craig Reynolds - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - - ----------------------------------------------------------------------------- - -PyOpenSteer -- Port of OpenSteer to the Python(r) language - -Copyright (c) 2004 Lutz Paelike - -The license follows the original Opensteer license but must include -this additional copyright notice. ----------------------------------------------------------------------------- -""" - -from vector import vec3 - -class AbstractLocalSpace: - def __init__(self): - pass - def side(self): - """ """ - pass - - def setSide(self): - """ """ - pass - - def up(self): - """ """ - pass - - def setUp(self,u): - """ """ - pass - - def forward(self): - """ """ - pass - - def setForward(self,f): - """ """ - pass - - def position(self): - """ """ - pass - - def setPosition(self,p): - """ """ - pass - - def rightHanded(self): - """ """ - pass - - def resetLocalSpace(self): - """ """ - pass - - def localizeDirection(self,globalDirection): - """ """ - pass - - def localizePosition(self,globalPosition): - """ """ - pass - - def globalizePosition(self,localPosition): - """ """ - pass - - def globalizeDirection(self,localDirection): - """ """ - pass - - def setUnitSideFromForwardAndUp(self): - """ """ - pass - - def regenerateOrthonormalBasisUF(self,newUnitForward): - """ """ - pass - - - def regenerateOrthonormalBasis(self,newForward,newUp=None): - """ """ - pass - - def localRotateForwardToSide(self,v): - """ """ - pass - - def globalRotateForwardToSide(self,globalForward): - """ """ - pass - -class LocalSpaceMixin: - def __init__(self, Side=None, Up=None, Forward=None,Position=None): - - # upward-pointing unit basis vector - if Up: - self._up = Up - else: - self._up = vec3() - - # forward-pointing unit basis vector - if Forward: - self._forward =Forward - else: - self._forward = vec3() - - # origin of local space - if Position: - self._position = Position - else: - self._position = vec3() - - # side-pointing unit basis vector - if Side: - self._side = Side - else: - self._side = vec3() - self.setUnitSideFromForwardAndUp() - - if (not Side) & (not Up) & (not Forward) & (not Position): - self.resetLocalSpace() - - def side(self): - """ """ - return self._side - - def up(self): - """ """ - return self._up - - def forward(self): - """ """ - return self._forward - - def position(self): - """ """ - return self._position - - def setSide(self,s): - """ """ - _side=s - return s - - def setUp(self,u): - """ """ - _up=u - return u - - def setForward(self,f): - """ """ - _forward=f - return f - - def setPosition(self,p): - """ """ - _position=p - return p - - def rightHanded(self): - """ - switch to control handedness/chirality: should - LocalSpace use a left- or right-handed coordinate system? This can be - overloaded in derived types (e.g. vehicles) to change handedness. - """ - return true - -class LocalSpace(AbstractLocalSpace, LocalSpaceMixin): - def __init__(self): - AbstractLocalSpace.__init__(self) - LocalSpaceMixin.__init__(self) - - -gGlobalSpace = LocalSpace() - - - diff --git a/Stackless/demo/paelike/PyOpenSteer/PlugIn.py b/Stackless/demo/paelike/PyOpenSteer/PlugIn.py deleted file mode 100644 index d29073eb64c960..00000000000000 --- a/Stackless/demo/paelike/PyOpenSteer/PlugIn.py +++ /dev/null @@ -1,171 +0,0 @@ -""" ----------------------------------------------------------------------------- - -OpenSteer -- Steering Behaviors for Autonomous Characters - -Copyright (c) 2002-2003, Sony Computer Entertainment America -Original author: Craig Reynolds - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - - ----------------------------------------------------------------------------- - -PyOpenSteer -- Port of OpenSteer to the Python(r) language - -Copyright (c) 2004 Lutz Paelike - -The license follows the original Opensteer license but must include -this additional copyright notice. ----------------------------------------------------------------------------- -""" - -# global variables (static in module level) - -totalSizeOfRegistry = 0 -itemsInRegistry = 0 -registry = [] - -class AbstractPlugIn: - """abstract base classe for plugins""" - - def open(self): - """open the plugin and initialize""" - pass - - def update(self,currentTime, elapsedTime): - """update action of the plugin - params: float,float""" - pass - - def redraw(self,currentTime, elapsedTime): - """redraw action of the plugin - params: float,float""" - pass - - def close(self): - """close down the plugin and deinitialize""" - pass - - def reset(self): - """reset the plugin""" - pass - - def name(self): - """returns this instance's character name as string""" - pass - - def selectionOrderSortKey(self): - """numeric sort key used to establish user-visible PlugIn ordering - ("built ins" have keys greater than 0 and less than 1)""" - pass - - def requestInitialSelection(self): - """allows a PlugIn to nominate itself as SteerTest's initially selected - (default) PlugIn, which is otherwise the first in "selection order""" - pass - - def handleFunctionKeys(self, keyNumber): - """handle function keys (which are reserved by SteerTest for PlugIns) - params: keynumber as int""" - pass - - def printMiniHelpForFunctionKeys(self): - """print "mini help" documenting function keys handled by this PlugIn""" - pass - - def allVehicles(self): - """returns a list [] of AbstractVehicle objects - (vehicles/agents/characters) defined by the PlugIn""" - pass - -class PlugIn(AbstractPlugIn): - """ - integrate this the Python(r) way ... - - typedef void (* plugInCallBackFunction) (PlugIn& clientObject); - typedef void (* voidCallBackFunction) (void); - typedef void (* timestepCallBackFunction) (const float currentTime, - const float elapsedTime); - """ - - def __init__(self): - """Init""" - pass - - def __del__(self): - """DeInit""" - pass - - def reset(self): - """default reset method is to do a close then an open""" - self.close() - self.open() - - def selectionOrderSortKey(self): - """default sort key (after the "built ins")""" - return 1.0 - - def requestInitialSelection(self): - """default is to NOT request to be initially selected""" - return False - - def handleFunctionKeys(self, keyNumber): - """default function key handler: ignore all) - params: keynumber as int""" - pass - - def printMiniHelpForFunctionKeys(self): - """default "mini help": print nothing""" - pass - - def next(self): - """ returns next PlugIn in "selection order" """ - return None - - - def __str__(self): - """convert PlugIn to string, just return the name""" - return pi.name - - - def findByName(self, name): - """search the class registry for a Plugin - with the given name and return the PlugIn obejct - """ - return None - - def applyToAll(self, plugInCallBackFunction): - """apply a given function to all PlugIns in the class registry""" - pass - - def sortBySelectionOrder(self): - """sort PlugIn registry by "selection order" """ - pass - - def findDefault(self): - """returns default PlugIn (currently, first in registry) - """ - return None - - def addToRegistry(self): - """save this instance in the class's registry of instances - """ - pass - \ No newline at end of file diff --git a/Stackless/demo/paelike/PyOpenSteer/Readme.txt b/Stackless/demo/paelike/PyOpenSteer/Readme.txt deleted file mode 100644 index 099176a456815e..00000000000000 --- a/Stackless/demo/paelike/PyOpenSteer/Readme.txt +++ /dev/null @@ -1,18 +0,0 @@ -This is a port of the OpenSteer Library to the Python(r) language -http://opensteer.sourceforge.net - -The aim is to have the Steertest application of the library -based on Stackless to provide a testbed for -agent simulation - -It's not finished yet and still work in progress so -you should leave it right now and wait until the code is polished. -Hope to finish a first working release in the next days. - -After that i will integrate stackless specific features -and optimize the code. -Actors will be implemented as Stackless Tasklets. - ---- -Lutz Paelike -lutz_p@gmx.net \ No newline at end of file diff --git a/Stackless/demo/paelike/PyOpenSteer/SimpleVehicle.py b/Stackless/demo/paelike/PyOpenSteer/SimpleVehicle.py deleted file mode 100644 index 35f36470e96104..00000000000000 --- a/Stackless/demo/paelike/PyOpenSteer/SimpleVehicle.py +++ /dev/null @@ -1,75 +0,0 @@ -""" -SimpleVehicle - -A steerable point mass with a velocity-aligned local coordinate system. -SimpleVehicle is useful for developing prototype vehicles in SteerTest, -it is the base class for vehicles in the PlugIns supplied with OpenSteer. -Note that SimpleVehicle is intended only as sample code. Your application -can use the OpenSteer library without using SimpleVehicle, as long as you -implement the AbstractVehicle protocol. - -SimpleVehicle makes use of the "mixin" concept from OOP. To quote -"Mixin-Based Programming in C++" a clear and helpful paper by Yannis -Smaragdakis and Don Batory (http:#citeseer.nj.nec.com/503808.html): - - ...The idea is simple: we would like to specify an extension without - predetermining what exactly it can extend. This is equivalent to - specifying a subclass while leaving its superclass as a parameter to be - determined later. The benefit is that a single class can be used to - express an incremental extension, valid for a variety of classes... - -In OpenSteer, vehicles are defined by an interface: an abstract base class -called AbstractVehicle. Implementations of that interface, and related -functionality (like steering behaviors and vehicle physics) are provided as -template-based mixin classes. The intent of this design is to allow you to -reuse OpenSteer code with your application's own base class. - -01-29-03 cwr: created - -""" - -import AbstractVehicle -import SteerLibrary -import Annotation - -import vector - -class SimpleVehicle(AbstractVehicle,LocalSpaceMixin,AnnotationMixin,SteerLibraryMixin,SimpleVehicle): - def __init__(self): - AbstractVehicle.__init__(self) - LocalSpaceMixin.__init__(self) - AnnotationMixin.__init__(self) - SteerLibraryMixin.__init__(self) - SimpleVehicle.__init__(self) - -def reset(self): - """reset vehicle state""" - # reset LocalSpace state - self.resetLocalSpace() - - # reset SteerLibraryMixin state - # (XXX this seems really fragile, needs to be redesigned XXX) - self.reset() - - self.setMass(1.0) # mass (defaults to 1 so acceleration=force) - self.setSpeed(0.0) # speed along Forward direction. - - self.setRadius(0.5) # size of bounding sphere - - self.setMaxForce(0.1) # steering force is clipped to this magnitude - sself.setMaxSpeed(1.0) # velocity is clipped to this magnitude - - self.smoothedAcceleration = vector.zero - - -def mass(self): - """get mass""" - return self._mass - -def setMass(self,m): - """set mass""" - self._mass = m - -def velocity(self): - """get velocity of vehicle""" - return self.forward() * self._speed \ No newline at end of file diff --git a/Stackless/demo/paelike/PyOpenSteer/SteerTest.py b/Stackless/demo/paelike/PyOpenSteer/SteerTest.py deleted file mode 100644 index ac7e7520754afd..00000000000000 --- a/Stackless/demo/paelike/PyOpenSteer/SteerTest.py +++ /dev/null @@ -1,522 +0,0 @@ -""" ----------------------------------------------------------------------------- - -OpenSteer -- Steering Behaviors for Autonomous Characters - -Copyright (c) 2002-2003, Sony Computer Entertainment America -Original author: Craig Reynolds - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - - ----------------------------------------------------------------------------- - -PyOpenSteer -- Port of OpenSteer to the Python(r) language - -Copyright (c) 2004 Lutz Paelike - -The license follows the original Opensteer license but must include -this additional copyright notice. ----------------------------------------------------------------------------- -""" - -import sys -import cgtypes - -from Clock import * -from Camera import * -from PlugIn import PlugIn -from AbstractVehicle import * - -import Utilities -import ColorDefs - -from DeferredDrawing import * -##### constants - -DRAWPHASE = 2 -UPDATEPHASE = 1 -OVERHEADPHASE = 0 - - -##### global vars (module level) - -mouseX = 0 -mouseY = 0 -mouseInWindow = False - -# some camera-related default constants -camera2dElevation = 8.0 -cameraTargetDistance = 13.0 -cameraTargetOffset = cgtypes.vec3(0.0,cameraTargetDistance,0.0) - - -########## SteerTest phase - -phaseStack = [0,0,0,0,0] -phaseStackSize = 5 -phaseStackIndex = 0 - -# list of floats -phaseTimers = [0.0,0.0,0.0,0.0] -# list of floats -phaseTimerBase = 0.0 - - - -# keeps track of both "real time" and "simulation time" -clock = Clock() - -# camera automatically tracks selected vehicle -camera = Camera() - -# currently selected plug-in (user can choose or cycle through them) -selectedPlugIn = None - -# currently selected vehicle. Generally the one the camera follows and -# for which additional information may be displayed. Clicking the mouse -# near a vehicle causes it to become the Selected Vehicle. -selectedVehicle = None -phase = OVERHEADPHASE -enableAnnotation = True - - -gDelayedResetPlugInXXX = False - -def printPlugIn(plugin): - print str(plugin) - - -def initialize(): - global selectedVehicle, phase, enableAnnotation, selectedPlugIn - # list of ints - - -def updateSimulationAndRedraw(): - """main update function: step simulation forward and redraw scene""" - # update global simulation clock - clock.update () - - # start the phase timer (XXX to accurately measure "overhead" time this - # should be in displayFunc, or somehow account for time outside this - # routine) - initPhaseTimers() - - # run selected PlugIn (with simulation's current time and step size) - updateSelectedPlugIn(clock.totalSimulationTime, clock.elapsedSimulationTime) - - # redraw selected PlugIn (based on real time) - redrawSelectedPlugIn(clock.totalRealTime, clock.elapsedRealTime) - -def errorExit(message): - """exit SteerTest with a given text message or error code""" - print message - sys.exit(10) - -def exit(exitCode): - """just exit SteerTest""" - sys.exit(exitCode) - -########## PlugIn interface ########### - -def selectDefaultPlugIn(): - """select the default PlugIn """ - PlugIn.sortBySelectionOrder() - selectedPlugIn = PlugIn.findDefault(); - -def selectNextPlugIn(): - """ select the "next" plug-in, cycling through "plug-in selection order" """ - closeSelectedPlugIn() - selectedPlugIn = selectedPlugIn.next() - openSelectedPlugIn() - -def functionKeyForPlugIn(keyNumber): - """handle function keys an a per-plug-in basis""" - selectedPlugIn.handleFunctionKeys(keyNumber) - -def nameOfSelectedPlugIn(): - """ return name of currently selected plug-in (string) """ - if selectedPlugIn: - return selectedPlugIn.name() - else: - return "no PlugIn" - -def openSelectedPlugIn(): - """open the currently selected plug-in""" - camera.reset() - selectedVehicle = None - selectedPlugIn.open() - -def updateSelectedPlugIn(currentTime,elapsedTime): - """do a simulation update for the currently selected plug-in""" - global selectedVehicle,selectedPlugIn,UPDATEPHASE - #switch to Update phase - pushPhase(UPDATEPHASE); - - # service queued reset request, if any - doDelayedResetPlugInXXX() - - # if no vehicle is selected, and some exist, select the first one - if (selectedVehicle == None): - vehicles = allVehiclesOfSelectedPlugIn() - if (vehicles): - if(len(vehicles) > 0): - selectedVehicle = vehicles[0] - - - # invoke selected PlugIn's Update method - if selectedPlugIn: - selectedPlugIn.update(currentTime, elapsedTime) - - # return to previous phase - popPhase() - -def redrawSelectedPlugIn(currentTime,elapsedTime): - """redraw graphics for the currently selected plug-in""" - global selectedPlugIn, DRAWPHASE - # switch to Draw phase - pushPhase(DRAWPHASE) - - # invoke selected PlugIn's Draw method - if selectedPlugIn: selectedPlugIn.redraw(currentTime, elapsedTime) - - # draw any annotation queued up during selected PlugIn's Update method - drawAllDeferredLines() - drawAllDeferredCirclesOrDisks () - - # return to previous phase - popPhase() - -def closeSelectedPlugIn(): - """close the currently selected plug-in""" - global selectedPlugIn,selectedVehicle - selectedPlugIn.close() - selectedVehicle = None - -def resetSelectedPlugIn(): - """reset the currently selected plug-in""" - selectedPlugIn.reset() - -def queueDelayedResetPlugInXXX(): - global gDelayedResetPlugInXXX - gDelayedResetPlugInXXX = True - - -def doDelayedResetPlugInXXX(): - global gDelayedResetPlugInXXX - if (gDelayedResetPlugInXXX): - resetSelectedPlugIn () - gDelayedResetPlugInXXX = False - - -def allVehiclesOfSelectedPlugIn(): - """returns list object with a list of all Vehicles driven by the currently selected PlugIn""" - global selectedPlugIn - if selectedPlugIn: - return selectedPlugIn.allVehicles() - else: - return None - - -def phaseIsDraw(): - """ """ - pass - -def phaseIsUpdate(): - """ """ - pass - -def phaseIsOverhead(): - """ """ - pass - -def phaseTimerDraw(): - """ """ - pass - -def phaseTimerUpdate(): - """ """ - pass - -def phaseTimerOverhead(): - """ """ - pass - -################# delayed reset XXX - -def queueDelayedResetPlugInXXX(): - """ """ - pass - -def doDelayedResetPlugInXXX(): - """ """ - pass - -################# vehicle selection - -def selectNextVehicle(): - """ """ - global selectedVehicle - if (selectedVehicle): - # get a container of all vehicles - all = allVehiclesOfSelectedPlugIn () - first = all[0] - last = all[-1] - - found = False - for i, item in enumerate(all): - if item == selectedVehicle: - found = True - if i+1 step forward one frame. - Esc exit. - - """ - print help - #allow PlugIn to print mini help for the function keys it handles - selectedPlugIn.printMiniHelpForFunctionKeys() - -def pushPhase(newPhase): - """ """ - global phaseStack,phaseStackIndex,phase - # update timer for current (old) phase: add in time since last switch - updatePhaseTimers() - - # save old phase - phaseStack[phaseStackIndex] = phase - phaseStackIndex+=1 - # set new phase - phase = newPhase; - - # check for stack overflow - if (phaseStackIndex >= phaseStackSize): errorExit("phaseStack overflow") - -def popPhase(): - """ """ - global phaseStack,phaseStackIndex,phase - #update timer for current (old) phase: add in time since last switch - updatePhaseTimers() - - #restore old phase - phaseStackIndex-=1 - phase = phaseStack[phaseStackIndex] - -def initPhaseTimers(): - """ """ - # lutz: changed initialisation behaviour - global phaseTimers,phaseTimerBase - phaseTimers = [0.0,0.0,0.0] - phaseTimerBase = clock.totalRealTime - -def updatePhaseTimers(): - """ """ - global clock, phase, phaseTimers,phaseTimerBase - currentRealTime = clock.realTimeSinceFirstClockUpdate() - phaseTimers[phase] += currentRealTime - phaseTimerBase - phaseTimerBase = currentRealTime - diff --git a/Stackless/demo/paelike/PyOpenSteer/Utilities.py b/Stackless/demo/paelike/PyOpenSteer/Utilities.py deleted file mode 100644 index 0af360c94fca68..00000000000000 --- a/Stackless/demo/paelike/PyOpenSteer/Utilities.py +++ /dev/null @@ -1,111 +0,0 @@ -import math,random - -M_PI = math.pi - -# copied from the c include -# don't know if this is correct -MAXFLOAT = 3.402823466e+38 - -def interpolate (alpha, x0, x1): - return x0 + ((x1 - x0) * alpha) - -frandom01 = random.random - - -def frandom2 (lowerBound, upperBound): - random.uniform() - -def clip (x, min, max): - """ - Constrain a given value (x) to be between two (ordered) bounds: min - and max. Returns x if it is between the bounds, otherwise returns - the nearer bound - """ - if (x < min): return min - if (x > max): return max - return x - - -def remapInterval( x, in0, in1, out0, out1): - """ - remap a value specified relative to a pair of bounding values - to the corresponding value relative to another pair of bounds. - """ - - # uninterpolate: what is x relative to the interval in0:in1? - relative = (x - in0) / (in1 - in0) - - # now interpolate between output interval based on relative x - return interpolate(relative, out0, out1) - -def remapIntervalClip( x, in0, in1, out0, out1): - """ - Like remapInterval but the result is clipped to remain between - out0 and out1 - """ - - # uninterpolate: what is x relative to the interval in0:in1? - relative = (x - in0) / (in1 - in0) - - # now interpolate between output interval based on relative x - return interpolate (clip (relative, 0, 1), out0, out1) - - -def intervalComparison(x, lowerBound, upperBound): - """ - classify a value relative to the interval between two bounds: - returns -1 when below the lower bound - returns 0 when between the bounds (inside the interval) - returns +1 when above the upper bound - """ - if (x < lowerBound): return -1 - if (x > upperBound): return 1 - return 0 - - -def scalarRandomWalk(initial, walkspeed, min, max): - next = initial + (((frandom01() * 2) - 1) * walkspeed) - if (next < min): return min - if (next > max): return max - return next - - -def square(x): - return x*x - -#################################### Accumulator - -class Accumulator(object): - def __init__(self,initialvalue=0): - self.set(initialvalue) - def accumulate(self,value): - self._value += value - - def set(self,val): - self._value = val - - def get(self): - return self._value - - -def blendIntoAccumulator(smoothRate, newValue, smoothedAccumulator): - """ - blends new values into an accumulator to produce a smoothed time series - - Modifies its third argument, a reference to the float accumulator holding - the "smoothed time series." - - The first argument (smoothRate) is typically made proportional to "dt" the - simulation time step. If smoothRate is 0 the accumulator will not change, - if smoothRate is 1 the accumulator will be set to the new value with no - smoothing. Useful values are "near zero". - - Usage: - blendIntoAccumulator (dt * 0.4f, currentFPS, smoothedFPS); - """ - - #This is just plain wrong - #rework this the Python(r) way - pass - #smoothedAccumulator.set(interpolate(clip(smoothRate, 0, 1), smoothedAccumulator.get(), newValue) - \ No newline at end of file diff --git a/Stackless/demo/paelike/PyOpenSteer/testit.py b/Stackless/demo/paelike/PyOpenSteer/testit.py deleted file mode 100644 index 142f99d16b97ff..00000000000000 --- a/Stackless/demo/paelike/PyOpenSteer/testit.py +++ /dev/null @@ -1,4 +0,0 @@ - -import Draw -Draw.initializeGraphics(['test']) -Draw.runGraphics() \ No newline at end of file diff --git a/Stackless/demo/paelike/PyOpenSteer/vector.py b/Stackless/demo/paelike/PyOpenSteer/vector.py deleted file mode 100644 index 46c047b978a0d1..00000000000000 --- a/Stackless/demo/paelike/PyOpenSteer/vector.py +++ /dev/null @@ -1,654 +0,0 @@ -import cgtypes -import types, math - -from Utilities import frandom01 - -class vec3(cgtypes.vec3): - def __init__(self, *args): - cgtypes.vec3.__init__(self,args) - - - - def __repr__(self): - return 'vec3('+`self.x`+', '+`self.y`+', '+`self.z`+')' - - def __str__(self): - fmt="%1.4f" - return '('+fmt%self.x+', '+fmt%self.y+', '+fmt%self.z+')' - - - def __eq__(self, other): - """== operator - - >>> a=vec3(1.0, 0.5, -1.8) - >>> b=vec3(-0.3, 0.75, 0.5) - >>> c=vec3(-0.3, 0.75, 0.5) - >>> print a==b - 0 - >>> print b==c - 1 - >>> print a==None - 0 - """ - if isinstance(other, vec3): - return self.x==other.x and self.y==other.y and self.z==other.z - else: - return 0 - - def __ne__(self, other): - """!= operator - - >>> a=vec3(1.0, 0.5, -1.8) - >>> b=vec3(-0.3, 0.75, 0.5) - >>> c=vec3(-0.3, 0.75, 0.5) - >>> print a!=b - 1 - >>> print b!=c - 0 - >>> print a!=None - 1 - """ - if isinstance(other, cgtypes.vec3): - return self.x!=other.x or self.y!=other.y or self.z!=other.z - else: - return 1 - - - def __add__(self, other): - """Vector addition. - - >>> a=vec3(1.0, 0.5, -1.8) - >>> b=vec3(-0.3, 0.75, 0.5) - >>> print a+b - (0.7000, 1.2500, -1.3000) - """ - if isinstance(other, cgtypes.vec3): - return vec3(self.x+other.x, self.y+other.y, self.z+other.z) - else: - raise TypeError, "unsupported operand type for +" - - def __sub__(self, other): - """Vector subtraction. - - >>> a=vec3(1.0, 0.5, -1.8) - >>> b=vec3(-0.3, 0.75, 0.5) - >>> print a-b - (1.3000, -0.2500, -2.3000) - """ - if isinstance(other, cgtypes.vec3): - return vec3(self.x-other.x, self.y-other.y, self.z-other.z) - else: - raise TypeError, "unsupported operand type for -" - - def __mul__(self, other): - """Multiplication with a scalar or dot product. - - >>> a=vec3(1.0, 0.5, -1.8) - >>> b=vec3(-0.3, 0.75, 0.5) - >>> print a*2.0 - (2.0000, 1.0000, -3.6000) - >>> print 2.0*a - (2.0000, 1.0000, -3.6000) - >>> print a*b - -0.825 - """ - - T = type(other) - # vec3*scalar - if T==types.FloatType or T==types.IntType or T==types.LongType: - return vec3(self.x*other, self.y*other, self.z*other) - # vec3*vec3 - if isinstance(other, cgtypes.vec3): - return self.x*other.x + self.y*other.y + self.z*other.z - # unsupported - else: - # Try to delegate the operation to the other operand - if getattr(other,"__rmul__",None)!=None: - return other.__rmul__(self) - else: - raise TypeError, "unsupported operand type for *" - - __rmul__ = __mul__ - - def __div__(self, other): - """Division by scalar - - >>> a=vec3(1.0, 0.5, -1.8) - >>> print a/2.0 - (0.5000, 0.2500, -0.9000) - """ - T = type(other) - # vec3/scalar - if T==types.FloatType or T==types.IntType or T==types.LongType: - return vec3(self.x/other, self.y/other, self.z/other) - # unsupported - else: - raise TypeError, "unsupported operand type for /" - - def __mod__(self, other): - """Modulo (component wise) - - >>> a=vec3(3.0, 2.5, -1.8) - >>> print a%2.0 - (1.0000, 0.5000, 0.2000) - """ - T = type(other) - # vec3%scalar - if T==types.FloatType or T==types.IntType or T==types.LongType: - return vec3(self.x%other, self.y%other, self.z%other) - # unsupported - else: - raise TypeError, "unsupported operand type for %" - - def __iadd__(self, other): - """Inline vector addition. - - >>> a=vec3(1.0, 0.5, -1.8) - >>> b=vec3(-0.3, 0.75, 0.5) - >>> a+=b - >>> print a - (0.7000, 1.2500, -1.3000) - """ - if isinstance(other, cgtypes.vec3): - self.x+=other.x - self.y+=other.y - self.z+=other.z - return self - else: - raise TypeError, "unsupported operand type for +=" - - def __isub__(self, other): - """Inline vector subtraction. - - >>> a=vec3(1.0, 0.5, -1.8) - >>> b=vec3(-0.3, 0.75, 0.5) - >>> a-=b - >>> print a - (1.3000, -0.2500, -2.3000) - """ - if isinstance(other, cgtypes.vec3): - self.x-=other.x - self.y-=other.y - self.z-=other.z - return self - else: - raise TypeError, "unsupported operand type for -=" - - def __imul__(self, other): - """Inline multiplication (only with scalar) - - >>> a=vec3(1.0, 0.5, -1.8) - >>> a*=2.0 - >>> print a - (2.0000, 1.0000, -3.6000) - """ - T = type(other) - # vec3*=scalar - if T==types.FloatType or T==types.IntType or T==types.LongType: - self.x*=other - self.y*=other - self.z*=other - return self - else: - raise TypeError, "unsupported operand type for *=" - - def __idiv__(self, other): - """Inline division with scalar - - >>> a=vec3(1.0, 0.5, -1.8) - >>> a/=2.0 - >>> print a - (0.5000, 0.2500, -0.9000) - """ - T = type(other) - # vec3/=scalar - if T==types.FloatType or T==types.IntType or T==types.LongType: - self.x/=other - self.y/=other - self.z/=other - return self - else: - raise TypeError, "unsupported operand type for /=" - - def __imod__(self, other): - """Inline modulo - - >>> a=vec3(3.0, 2.5, -1.8) - >>> a%=2.0 - >>> print a - (1.0000, 0.5000, 0.2000) - """ - T = type(other) - # vec3%=scalar - if T==types.FloatType or T==types.IntType or T==types.LongType: - self.x%=other - self.y%=other - self.z%=other - return self - else: - raise TypeError, "unsupported operand type for %=" - - def __neg__(self): - """Negation - - >>> a=vec3(3.0, 2.5, -1.8) - >>> print -a - (-3.0000, -2.5000, 1.8000) - """ - return vec3(-self.x, -self.y, -self.z) - - def __pos__(self): - """ - >>> a=vec3(3.0, 2.5, -1.8) - >>> print +a - (3.0000, 2.5000, -1.8000) - """ - return vec3(+self.x, +self.y, +self.z) - - def __abs__(self): - """Return the length of the vector. - - abs(v) is equivalent to v.length(). - - >>> a=vec3(1.0, 0.5, -1.8) - >>> print abs(a) - 2.11896201004 - """ - return math.sqrt(self*self) - - - def __len__(self): - """Length of the sequence (always 3)""" - return 3 - - def __getitem__(self, key): - """Return a component by index (0-based) - - >>> a=vec3(1.0, 0.5, -1.8) - >>> print a[0] - 1.0 - >>> print a[1] - 0.5 - >>> print a[2] - -1.8 - """ - T=type(key) - if T!=types.IntType and T!=types.LongType: - raise TypeError, "index must be integer" - - if key==0: return self.x - elif key==1: return self.y - elif key==2: return self.z - else: - raise IndexError,"index out of range" - - def __setitem__(self, key, value): - """Set a component by index (0-based) - - >>> a=vec3() - >>> a[0]=1.5; a[1]=0.7; a[2]=-0.3 - >>> print a - (1.5000, 0.7000, -0.3000) - """ - T=type(key) - if T!=types.IntType and T!=types.LongType: - raise TypeError, "index must be integer" - - if key==0: self.x = value - elif key==1: self.y = value - elif key==2: self.z = value - else: - raise IndexError,"index out of range" - - def cross(self, other): - """Cross product. - - >>> a=vec3(1.0, 0.5, -1.8) - >>> b=vec3(-0.3, 0.75, 0.5) - >>> c=a.cross(b) - >>> print c - (1.6000, 0.0400, 0.9000) - """ - - if isinstance(other, cgtypes.vec3): - return vec3(self.y*other.z-self.z*other.y, - self.z*other.x-self.x*other.z, - self.x*other.y-self.y*other.x) - else: - raise TypeError, "unsupported operand type for cross()" - - - def length(self): - """Return the length of the vector. - - v.length() is equivalent to abs(v). - - >>> a=vec3(1.0, 0.5, -1.8) - >>> print a.length() - 2.11896201004 - """ - - return math.sqrt(self*self) - - def normalize(self): - """Return normalized vector. - - >>> a=vec3(1.0, 0.5, -1.8) - >>> print a.normalize() - (0.4719, 0.2360, -0.8495) - """ - - nlen = 1.0/math.sqrt(self*self) - return vec3(self.x*nlen, self.y*nlen, self.z*nlen) - - def angle(self, other): - """Return angle (in radians) between self and other. - - >>> a=vec3(1.0, 0.5, -1.8) - >>> b=vec3(-0.3, 0.75, 0.5) - >>> print a.angle(b) - 1.99306755584 - """ - - if isinstance(other, cgtypes.vec3): - return math.acos((self*other) / (abs(self)*abs(other))) - else: - raise TypeError, "unsupported operand type for angle()" - - def reflect(self, N): - """Return the reflection vector. - - N is the surface normal which has to be of unit length. - - >>> a=vec3(1.0, 0.5, -1.8) - >>> print a.reflect(vec3(1,0,1)) - (2.6000, 0.5000, -0.2000) - """ - - return self - 2.0*(self*N)*N - - def refract(self, N, eta): - """Return the transmitted vector. - - N is the surface normal which has to be of unit length. - eta is the relative index of refraction. If the returned - vector is zero then there is no transmitted light because - of total internal reflection. - - >>> a=vec3(1.0, -1.5, 0.8) - >>> print a.refract(vec3(0,1,0), 1.33) - (1.3300, -1.7920, 1.0640) - """ - - dot = self*N - k = 1.0 - eta*eta*(1.0 - dot*dot) - if k<0: - return vec3(0.0,0.0,0.0) - else: - return eta*self - (eta*dot + math.sqrt(k))*N - - def ortho(self): - """Returns an orthogonal vector. - - Returns a vector that is orthogonal to self (where - self*self.ortho()==0). - - >>> a=vec3(1.0, -1.5, 0.8) - >>> print round(a*a.ortho(),8) - 0.0 - """ - - x=abs(self.x) - y=abs(self.y) - z=abs(self.z) - # Is z the smallest element? Then use x and y - if z<=x and z<=y: - return vec3(-self.y, self.x, 0.0) - # Is y smallest element? Then use x and z - elif y<=x and y<=z: - return vec3(-self.z, 0.0, self.x) - # x is smallest - else: - return vec3(0.0, -self.z, self.y) - - def set(self,_x,_y,_z): - self.x = _x - self.y = _y - self.z = _z - - def dot(self,v): - return self*v - - def lengthSquared(self): - """ - Just provide another name for the dot product operation - to make it more compatible to the original opensteer implementation - """ - return self*self - - def parallelComponent(self, unitBasis): - """ - return component of vector parallel to a unit basis vector - (IMPORTANT NOTE: assumes "basis" has unit magnitude (length==1)) - """ - projection = self*unitBasis - return unitBasis * projection - - def perpendicularComponent(self, unitBasis): - """ - return component of vector perpendicular to a unit basis vector - (IMPORTANT NOTE: assumes "basis" has unit magnitude (length==1)) - """ - return self - self.parallelComponent(unitBasis) - - def truncateLength(self,maxLength): - """ - clamps the length of a given vector to maxLength. If the vector is - shorter its value is returned unaltered, if the vector is longer - the value returned has length of maxLength and is paralle to the - original input. - """ - maxLengthSquared = maxLength * maxLengthSquared - vecLengthSquared = self.lengthSquared() - if (vecLengthSquared <= maxLengthSquared): - return self - else: - return self * (maxLength / math.sqrt(vecLengthSquared)) - - def setYtoZero(self): - """forces a 3d position onto the XZ (aka y=0) plane""" - return vec3(self.x,0.0,self.z) - - def rotateAboutGlobalY(self,angle, _sin=0.0,_cos=0.0): - """rotate this vector about the global Y (up) axis by the given angle""" - - if ((_sin==0.0) & (_cos==0.0)): - s = math.sin(angle) - c = math.cos(angle) - else: - # use cached values for computation - s = _sin - c = _cos - return (vec3(((self.x*c) + (self.z*s)), self.y, ((self.z*c) + (self.x*s))), s, c) - - def sphericalWrapAround(self,center,radius): - """ """ - offset = self - center - r = offset.length() - if (r > radius): - return self + ((offset/r) * radius * -2) - else: - return self - - - - def RandomVectorInUnitRadiusSphere(self): - """ - Returns a position randomly distributed inside a sphere of unit radius - centered at the origin. Orientation will be random and length will range - between 0 and 1 - """ - v = vec3() - while 1: - v.set ( (frandom01()*2) - 1, - (frandom01()*2) - 1, - (frandom01()*2) - 1) - if (v.length()>=1): - break - return v - - def randomVectorOnUnitRadiusXZDisk(self): - """ - Returns a position randomly distributed on a disk of unit radius - on the XZ (Y=0) plane, centered at the origin. Orientation will be - random and length will range between 0 and 1 - """ - v = vec3() - while 1: - v.set( ((frandom01()*2) - 1, 0, (frandom01()*2) - 1)) - if (v.length()>=1): - break - return v - - def RandomUnitVector(self): - """ - Returns a position randomly distributed on a disk of unit radius - on the XZ (Y=0) plane, centered at the origin. Orientation will be - random and length will range between 0 and 1 - """ - return self.RandomVectorInUnitRadiusSphere().normalize(); - - - - def RandomUnitVectorOnXZPlane(self): - """ - Returns a position randomly distributed on a circle of unit radius - on the XZ (Y=0) plane, centered at the origin. Orientation will be - random and length will be 1 - """ - return self.RandomVectorInUnitRadiusSphere().setYtoZero().normalize() - - - def vecLimitDeviationAngleUtility(self, insideOrOutside, source, cosineOfConeAngle, basis): - """ - Does a "ceiling" or "floor" operation on the angle by which a given vector - deviates from a given reference basis vector. Consider a cone with "basis" - as its axis and slope of "cosineOfConeAngle". The first argument controls - whether the "source" vector is forced to remain inside or outside of this - cone. Called by vecLimitMaxDeviationAngle and vecLimitMinDeviationAngle. - """ - - # immediately return zero length input vectors - sourceLength = source.length() - if (sourceLength == 0): return source - - # measure the angular deviation of "source" from "basis" - direction = source / sourceLength - cosineOfSourceAngle = direction.dot(basis) - - # Simply return "source" if it already meets the angle criteria. - # (note: we hope this top "if" gets compiled out since the flag - # is a constant when the function is inlined into its caller) - if (insideOrOutside): - # source vector is already inside the cone, just return it - if (cosineOfSourceAngle >= cosineOfConeAngle): return source - else: - # source vector is already outside the cone, just return it - if (cosineOfSourceAngle <= cosineOfConeAngle): return source - - # find the portion of "source" that is perpendicular to "basis" - perp = source.perpendicularComponent(basis) - - # normalize that perpendicular - unitPerp = perp.normalize() - - # construct a new vector whose length equals the source vector, - # and lies on the intersection of a plane (formed the source and - # basis vectors) and a cone (whose axis is "basis" and whose - # angle corresponds to cosineOfConeAngle) - perpDist = math.sqrt(1 - (cosineOfConeAngle * cosineOfConeAngle)) - c0 = basis * cosineOfConeAngle - c1 = unitPerp * perpDist - return (c0 + c1) * sourceLength - - - - - - def limitMaxDeviationAngle(self, source, cosineOfConeAngle, basis): - """ - Enforce an upper bound on the angle by which a given arbitrary vector - diviates from a given reference direction (specified by a unit basis - vector). The effect is to clip the "source" vector to be inside a cone - defined by the basis and an angle. - """ - return self.vecLimitDeviationAngleUtility( True, # force source INSIDE cone - source, - cosineOfConeAngle, - basis) - - - - def limitMinDeviationAngle(self, source, cosineOfConeAngle, basis): - """ - Enforce an lower bound on the angle by which a given arbitrary vector - diviates from a given reference direction (specified by a unit basis - vector). The effect is to clip the "source" vector to be inside a cone - defined by the basis and an angle. - """ - return vecLimitDeviationAngleUtility(True, # force source INSIDE cone - source, - cosineOfConeAngle, - basis) - - - def distanceFromLine( point, lineOrigin, lineUnitTangent): - """ - Returns the distance between a point and a line. The line is defined in - terms of a point on the line ("lineOrigin") and a UNIT vector parallel to - the line ("lineUnitTangent") - """ - offset = point - lineOrigin - perp = offset.perpendicularComponent(lineUnitTangent) - return perp.length() - - - def findPerpendicularIn3d(direction): - """ - given a vector, return a vector perpendicular to it (note that this - arbitrarily selects one of the infinitude of perpendicular vectors) - """ - - quasiPerp = vec3() - result = vec3() - - # three mutually perpendicular basis vectors - i = vec3(1.0, 0.0, 0.0) - j = vec3(0.0, 1.0, 0.0) - k = vec3(0.0, 0.0, 1.0) - - - # measure the projection of "direction" onto each of the axes - id = i.dot(direction); - jd = j.dot(direction); - kd = k.dot(direction); - - # set quasiPerp to the basis which is least parallel to "direction" - if ((id <= jd) & (id <= kd)): - quasiPerp = i # projection onto i was the smallest - else: - if ((jd <= id) & (jd <= kd)): - quasiPerp = j # projection onto j was the smallest - else: - quasiPerp = k # projection onto k was the smallest - - # return the cross product (direction x quasiPerp) - # which is guaranteed to be perpendicular to both of them - result.cross(direction, quasiPerp) - return result - -#names for frequently used vector constants -zero = vec3(0.0,0.0,0.0) -side = vec3(-1.0,0.0,0.0) -up = vec3(0.0,1.0,0.0) -forward = vec3(0.0,0.0,1.0) \ No newline at end of file diff --git a/Stackless/demo/stephan/stacklessness/chantest.py b/Stackless/demo/stephan/stacklessness/chantest.py deleted file mode 100644 index f93154cb7656a2..00000000000000 --- a/Stackless/demo/stephan/stacklessness/chantest.py +++ /dev/null @@ -1,41 +0,0 @@ -def receiver(chan, name): - while 1: - try: - data = chan.receive() - except: - print name, "** Ouch!!! **" - raise - print name, "got:", data - if data == 42: - chan.send("%s says bye" % name) - return - -import sys -import stacklessness as stackless - -chan = stackless.channel() -t1 = stackless.tasklet(receiver)(chan, "inky") -t2 = stackless.tasklet(receiver)(chan, "dinky") -stackless.run() -try: - for i in 2,3,5,7, 42: - print "sending", i - chan.send(i) - chan.send(i) - #if i==7: - # print "sending Exception" - # chan.send_exception(ValueError, i) -except ValueError: - e, v, t = sys.exc_info() - print e, v - del e, v, t -print "main done." -# -# trying to clean up things, until we have a real -# channel deallocator: -print "trying cleanup:" -while chan.balance: - if chan.balance < 0: - chan.send(42) - else: - print chan.receive() diff --git a/Stackless/demo/stephan/stacklessness/stacklessness.py b/Stackless/demo/stephan/stacklessness/stacklessness.py deleted file mode 100644 index 1cc5a48be6dd21..00000000000000 --- a/Stackless/demo/stephan/stacklessness/stacklessness.py +++ /dev/null @@ -1,280 +0,0 @@ -from threading import Event, currentThread, Lock, Thread -import time -import sys -import logging -from atexit import register - -__all__ = 'run getcurrent getmain tasklet channel schedule'.split() - -def prepareLogger(level): - import os - try: - os.unlink('stackless.log') - except:pass - logger = logging.getLogger('stackless') - hdlr = logging.FileHandler('stackless.log') - formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') - hdlr.setFormatter(formatter) - logger.addHandler(hdlr) - logger.setLevel(level) - - return logger - -log = prepareLogger(logging.INFO) - - -scheduler = None -maintasklet = None -globallock = Lock() -alltasks = [] - -def __init(): - global maintasklet - global scheduler - global globallock - mt = tasklet(None) - mt._active = True - mt._name = 'MainTask' - maintask = currentThread() - log.info(str(maintask)) - maintask.event = Event() - mt.thread = maintask - maintask.tasklet = mt - maintasklet = mt - scheduler = Scheduler() - log.info('# %s # is about to acquire the globallock' % getcurrent()) - globallock.acquire() - log.info('# %s # acquired the globallock' % getcurrent()) - - -# RuntimeError: -# possible messages: -# 'You cannot run a blocked tasklet' -class RuntimeError(Exception):pass - -def run(): - schedule() - -def getcurrent(): - ct = currentThread() - return ct.tasklet - -def getmain(): - return maintasklet - -def schedule(): - scheduler.schedule() - -class taskletwrapper(Thread): - # run is called within the new thread - def run(self): - log.info('# %s # is about to acquire the globallock' % getcurrent()) - globallock.acquire() - log.info('# %s # acquired the globallock' % getcurrent()) - try: - Thread.run(self) - finally: - self.tasklet.remove() - schedule() - -class tasklet(object): - def __init__(self,func): - self.func = func - self._active = False - self._name = 'Task%s' % str(len(alltasks) + 1) - self._shouldawake = False - - def __str__(self): - return self._name - - __repr__ = __str__ - - def __call__(self,*argl,**argd): - self.thread = taskletwrapper(target=self.func,args=argl,kwargs=argd) - self.thread.tasklet = self - self.thread.event = Event() - self.insert() - self._active = True - self.thread.start() - alltasks.append(self) - return self - - def awake(self): - log.info('%s calling %s.awake()' % (getcurrent(),self)) - self._shouldawake = True - self.thread.event.set() - - def sleep(self): - log.info('%s %s.sleep()' % (getcurrent(),self)) - self._shouldawake = False - self.thread.event.clear() - try: - log.info('# %s # about to release the globallock' % getcurrent()) - globallock.release() - except:pass - log.info('%s is going to sleep' % getcurrent()) - while (not self.thread.event.isSet()) and self._active: - log.info('%s is still waiting' % getcurrent()) - self.thread.event.wait(.01) - if self._shouldawake: - self._shouldawake = False - log.info('%s Event notification did NOT work. Waking up anyway' % getcurrent()) - break - log.info('%s is waking up' % getcurrent()) - if self._active: - log.info('\t%s still active' % self) - log.info('# %s # is about to acquire the globallock' % getcurrent()) - globallock.acquire() - log.info('# %s # acquired the globallock' % getcurrent()) - else: - log.info('\t%s not active anymore' % self) - - def run(self): - scheduler.setnexttask(self) - schedule() - - - def insert(self): - scheduler.insert(self) - - def remove(self): - self._active = False - scheduler.remove(self) - log.info('# %s # about to release the globallock' % getcurrent()) - try: - globallock.release() - except: - log.info('%s attempted to release globallock, but did not own it' % getcurrent()) - - def kill(self): - self._active = False - self.awake() - -class channel(object): - def __init__(self): - self._readq = [] - self._writeq = [] - self.balance = 0 - - def send(self,msg): - ct = getcurrent() - log.info('%s is sending %s' % (ct,msg)) - scheduler.remove(ct) - self._writeq.append((ct,msg)) - self.balance += 1 - if self._readq: - nt = self._readq[0] - del(self._readq[0]) - scheduler.priorityinsert(nt) - schedule() - - def send_exception(self,exp,msg): - ct = getcurrent() - - def receive(self): - ct = getcurrent() - log.info('%s is receiving' % ct) - if self._writeq: - log.info('\tfound something in writequeue') - wt,retval = self._writeq[0] - scheduler.priorityinsert(wt) - del(self._writeq[0]) - self.balance -= 1 - return retval - else: - log.info('\tneed to block') - self._readq.append(ct) - scheduler.remove(ct) - schedule() - return self.receive() - - -class Scheduler(object): - def __init__(self): - self.tasklist = [] - self.nexttask = None - - def empty(self): - log.info('%s Scheduler.emtpy()' % getcurrent()) - return not self.tasklist - - def __str__(self): - log.info('%s Scheduler.__str__()' % getcurrent()) - return repr(self.tasklist) + '/%s' % self.nexttask - - def insert(self,obj): - log.info('%s Scheduler.insert(%s)' % (getcurrent(),obj)) - if (obj not in self.tasklist) and obj is not maintasklet: - self.tasklist.append(obj) - if self.nexttask is None: - self.nexttask = 0 - - def priorityinsert(self,obj): - log.info('%s Scheduler.priorityinsert(%s)' % (getcurrent(),obj)) - log.info('\tbefore: %s' % self) - if obj in self.tasklist: - self.tasklist.remove(obj) - if obj is maintasklet: - return - if self.nexttask: - self.tasklist.insert(self.nexttask,obj) - else: - self.tasklist.insert(0,obj) - self.nexttask = 0 - log.info('\tafter: %s' % self) - - def remove(self,obj): - log.info('%s Scheduler.remove(%s)' % (getcurrent(),obj)) - try: - i = self.tasklist.index(obj) - del(self.tasklist[i]) - if self.nexttask > i: - self.nexttask -= 1 - if len(self.tasklist) == 0: - self.nexttask = None - except ValueError:pass - - def next(self): - log.info('%s Scheduler.next()' % getcurrent()) - if self.nexttask is not None: - obj = self.tasklist[self.nexttask] - self.nexttask += 1 - if self.nexttask == len(self.tasklist): - self.nexttask = 0 - return obj - else: - return maintasklet - - def setnexttask(self,obj): - log.info('%s Scheduler.setnexttask(%s)' % (getcurrent(),obj)) - if obj not in self.tasklist: - self.tasklist.insert(obj) - try: - i = self.tasklist.index(obj) - self.nexttask = i - except IndexError:pass - - def schedule(self): - log.info('%s Scheduler.schedule()' % getcurrent()) - log.info('\ttasklist:%s' % self) - ct = currentThread() - ctask = ct.tasklet - log.info('\tcurrent tasklet is: %s' % ctask) - nt = self.next() - if ctask == nt: - #raise RuntimeError("No task to schedule") - pass - log.info('\twaking up: %s' % nt) - nt.awake() - ctask.sleep() - -__init() - -def cleanup(): - for task in alltasks: - task.kill() - -register(cleanup) - -if __name__ == '__main__': - pass diff --git a/Stackless/demo/stephan/stacklessness/test.py b/Stackless/demo/stephan/stacklessness/test.py deleted file mode 100644 index 3e00d723b987c0..00000000000000 --- a/Stackless/demo/stephan/stacklessness/test.py +++ /dev/null @@ -1,21 +0,0 @@ -from stacklessness import * - -def f(): - print 'f1' - schedule() - print 'f2' - -def g(): - print 'g1' - schedule() - print 'g2' - -def h(): - print 'h1' - schedule() - print 'h2' - -t1 = tasklet(f)() -t2 = tasklet(g)() -t3 = tasklet(h)() -t1.run() diff --git a/Stackless/demo/stephan/stacklessness/test1.py b/Stackless/demo/stephan/stacklessness/test1.py deleted file mode 100644 index 9d5ffccc9ebd01..00000000000000 --- a/Stackless/demo/stephan/stacklessness/test1.py +++ /dev/null @@ -1,20 +0,0 @@ -from stacklessness import * - -def f(outchan): - for i in range(10): - print 'f send',i - outchan.send(i) - outchan.send(-1) - -def g(inchan): - while 1: - val = inchan.receive() - if val == -1: - break - print 'g received',val - -ch = channel() -t1 = tasklet(f)(ch) -t2 = tasklet(g)(ch) - -t1.run() diff --git a/Stackless/demo/tracing.py b/Stackless/demo/tracing.py index 72a01b89e35902..5c89fcdd2cbb8c 100644 --- a/Stackless/demo/tracing.py +++ b/Stackless/demo/tracing.py @@ -1,32 +1,27 @@ -from __future__ import print_function +from __future__ import absolute_import, print_function -from stackless import * +import sys +import stackless import traceback -def _tasklet__repr__(self): - try: - return "" % ("main" if self.is_main else self.name,) - except AttributeError: - return super(tasklet, self).__repr__() -tasklet.__repr__ = _tasklet__repr__ - - -class NamedTasklet(tasklet): - __slots__ = ["name"] +class NamedTasklet(stackless.tasklet): + __slots__ = ("name",) - def __new__(self, func, name=None): - t = tasklet.__new__(self, func) + def __init__(self, func, name=None): + stackless.tasklet.__init__(self, func) if name is None: - name = "at %08x" % (id(t)) - t.name = name - return t + name = "at %08x" % (id(self)) + self.name = name + + def __repr__(self): + return "" % (self.name) class Mutex(object): def __init__(self, capacity=1): - self.queue = channel() + self.queue = stackless.channel() self.capacity = capacity def isLocked(self): @@ -61,11 +56,11 @@ def unlock(self): def task(): - name = getcurrent().name + name = stackless.getcurrent().name print(name, "acquiring") m.lock() print(name, "switching") - schedule() + stackless.schedule() print(name, "releasing") m.unlock() @@ -91,6 +86,9 @@ def channel_cb(channel, tasklet, sending, willblock): def schedule_cb(prev, next): + # During a tasklet switch (during the execution of this function) the + # the result of stackless.getcurrent() is implementation defined. + # Therefore this function avoids any assumptions about the current tasklet. current_tf = sys.gettrace() try: sys.settrace(None) # don't trace this callback @@ -111,12 +109,9 @@ def schedule_cb(prev, next): print("%sjumping from %s to %s" % (current_info, prev, next)) # Inform about the installed trace functions - - # prev_tf = current_tf if prev.frame is current_frame else prev.trace_function next_tf = current_tf if next.frame is current_frame else next.trace_function - print(" Current trace functions: prev: %r, next: %r" % - (prev_tf, next_tf)) + print(" Current trace functions: prev: %r, next: %r" % (prev_tf, next_tf)) # Eventually set a trace function if next is not None: @@ -141,18 +136,17 @@ def schedule_cb(prev, next): sys.settrace(current_tf) if __name__ == "__main__": - import sys if len(sys.argv) > 1 and sys.argv[1] == 'hard': stackless.enable_softswitch(False) - set_channel_callback(channel_cb) - set_schedule_callback(schedule_cb) + stackless.set_channel_callback(channel_cb) + stackless.set_schedule_callback(schedule_cb) NamedTasklet(task, "tick")() NamedTasklet(task, "trick")() NamedTasklet(task, "track")() - run() + stackless.run() - set_channel_callback(None) - set_schedule_callback(None) + stackless.set_channel_callback(None) + stackless.set_schedule_callback(None)