| 1 |
#!/usr/bin/env python |
|---|
| 2 |
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 3 |
##~ License |
|---|
| 4 |
##~ |
|---|
| 5 |
##- The RuneBlade Foundation library is intended to ease some |
|---|
| 6 |
##- aspects of writing intricate Jabber, XML, and User Interface (wxPython, etc.) |
|---|
| 7 |
##- applications, while providing the flexibility to modularly change the |
|---|
| 8 |
##- architecture. Enjoy. |
|---|
| 9 |
##~ |
|---|
| 10 |
##~ Copyright (C) 2002 TechGame Networks, LLC. |
|---|
| 11 |
##~ |
|---|
| 12 |
##~ This library is free software; you can redistribute it and/or |
|---|
| 13 |
##~ modify it under the terms of the BSD style License as found in the |
|---|
| 14 |
##~ LICENSE file included with this distribution. |
|---|
| 15 |
##~ |
|---|
| 16 |
##~ TechGame Networks, LLC can be reached at: |
|---|
| 17 |
##~ 3578 E. Hartsel Drive #211 |
|---|
| 18 |
##~ Colorado Springs, Colorado, USA, 80920 |
|---|
| 19 |
##~ |
|---|
| 20 |
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 21 |
|
|---|
| 22 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 23 |
#~ Imports |
|---|
| 24 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 25 |
|
|---|
| 26 |
import time |
|---|
| 27 |
import math |
|---|
| 28 |
|
|---|
| 29 |
from wxPython import wx |
|---|
| 30 |
from OpenGL import GL, GLU, GLUT |
|---|
| 31 |
import Numeric |
|---|
| 32 |
|
|---|
| 33 |
from RBSkinning import SkinXML |
|---|
| 34 |
from RBSkinning.wxTools.GLViewSetup import GLViewSetup |
|---|
| 35 |
|
|---|
| 36 |
from RBRapier.Renderer import SequenceMgr |
|---|
| 37 |
from RBRapier.Renderer.Appearance import Blending |
|---|
| 38 |
from RBRapier.Renderer.Environment import Buffers |
|---|
| 39 |
from RBRapier.Renderer.Environment import Selection |
|---|
| 40 |
from RBRapier.Renderer.View import Viewport |
|---|
| 41 |
from RBRapier.Renderer.View import Transformations |
|---|
| 42 |
|
|---|
| 43 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 44 |
#~ Constants / Variables / Etc. |
|---|
| 45 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 46 |
|
|---|
| 47 |
skinxml = """<?xml version='1.0'?> |
|---|
| 48 |
<skin:skin xmlns:skin='http://namespaces.runeblade.com/skin' xmlns:py='http://namespaces.runeblade.com/xmlPython' xmlns='http://namespaces.runeblade.com/wxPythonSkin'> |
|---|
| 49 |
<frame ctxvar='scene.frame' title='Cube Scene' show='1' pos='0,0' size='800,600'> |
|---|
| 50 |
<layout fit='0'> |
|---|
| 51 |
<panel> |
|---|
| 52 |
<layout> |
|---|
| 53 |
<glcanvas ctxvar='scene.glcanvas' sizercfg='1, wxEXPAND' attribList='[WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_MIN_ALPHA, 8, WX_GL_DEPTH_SIZE, 8]'> |
|---|
| 54 |
<event type='EVT_LEFT_DOWN' call='ctx.scene.OnMouse'/> |
|---|
| 55 |
<event type='EVT_MOTION' call='ctx.scene.OnMouse'/> |
|---|
| 56 |
</glcanvas> |
|---|
| 57 |
</layout> |
|---|
| 58 |
</panel> |
|---|
| 59 |
</layout> |
|---|
| 60 |
</frame> |
|---|
| 61 |
|
|---|
| 62 |
<!-- |
|---|
| 63 |
<frame title='Demo PyCrust' show='1' pos='850,0' size='400,800'> |
|---|
| 64 |
<layout fit='0'> |
|---|
| 65 |
<pycrust_shell sizercfg='1, wxEXPAND' locals='{"scene":context.scene}'/> |
|---|
| 66 |
</layout> |
|---|
| 67 |
</frame> |
|---|
| 68 |
--> |
|---|
| 69 |
</skin:skin> |
|---|
| 70 |
""" |
|---|
| 71 |
|
|---|
| 72 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 73 |
#~ Definitions |
|---|
| 74 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 75 |
|
|---|
| 76 |
class Cube(object): |
|---|
| 77 |
size = 0.5 |
|---|
| 78 |
color = (1., 1., 1., 1.) |
|---|
| 79 |
tx, ty, tz = 0, 0, 0 |
|---|
| 80 |
sx, sy, sz = 120, 180, 90 |
|---|
| 81 |
usecolor = None |
|---|
| 82 |
|
|---|
| 83 |
def __init__(self, size=size, (tx,ty,tz)=(tx,ty,tz), (sx,sy,sz)=(sx,sy,sz), color=color): |
|---|
| 84 |
self.size = size |
|---|
| 85 |
self.sx, self.sy, self.sz = sx,sy,sz |
|---|
| 86 |
self.tx, self.ty, self.tz = tx,ty,tz |
|---|
| 87 |
self.color = color |
|---|
| 88 |
|
|---|
| 89 |
def _time(self): |
|---|
| 90 |
return time.clock() |
|---|
| 91 |
|
|---|
| 92 |
def GLExecute(self, context): |
|---|
| 93 |
GL.glLoadIdentity() |
|---|
| 94 |
GL.glRotated((self.tx + self.sx*self._time())%360., 1, 0, 0) |
|---|
| 95 |
GL.glRotated((self.ty + self.sy*self._time())%360., 0, 1, 0) |
|---|
| 96 |
GL.glRotated((self.tz + self.sz*self._time())%360., 0, 0, 1) |
|---|
| 97 |
|
|---|
| 98 |
GL.glPushName(id(self)) |
|---|
| 99 |
GL.glColor4fv(self.usecolor or self.color) |
|---|
| 100 |
GLUT.glutWireCube(self.size) |
|---|
| 101 |
GL.glPopName() |
|---|
| 102 |
|
|---|
| 103 |
def SetSelected(self, selected): |
|---|
| 104 |
if selected: |
|---|
| 105 |
self.usecolor = (1., 0., 0., 1.) |
|---|
| 106 |
else: |
|---|
| 107 |
self.usecolor = None |
|---|
| 108 |
|
|---|
| 109 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 110 |
|
|---|
| 111 |
class CubeScene(object): |
|---|
| 112 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 113 |
#~ Constants / Variables / Etc. |
|---|
| 114 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 115 |
|
|---|
| 116 |
_fps_score = 0 |
|---|
| 117 |
fps = 0. |
|---|
| 118 |
frametitle = 'Cube Scene' |
|---|
| 119 |
Initialized = False |
|---|
| 120 |
|
|---|
| 121 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 122 |
#~ Public Methods |
|---|
| 123 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 124 |
|
|---|
| 125 |
def OnSkinInitialize(self): |
|---|
| 126 |
pass |
|---|
| 127 |
|
|---|
| 128 |
def OnSkinFinalize(self): |
|---|
| 129 |
self.viewsetup = GLViewSetup(self.glcanvas) |
|---|
| 130 |
self.viewsetup.OnRender.Add(self.Initialize) |
|---|
| 131 |
self.viewsetup.OnRender.Add(self.Render) |
|---|
| 132 |
self.viewsetup.StartRendering() |
|---|
| 133 |
|
|---|
| 134 |
def IsPickingEnabled(self): |
|---|
| 135 |
return self.Initialized and self.pickmatrix.PickEnabled |
|---|
| 136 |
|
|---|
| 137 |
def Initialize(self, glviewsetup, canvas): |
|---|
| 138 |
self.viewsetup.OnRender.Remove(self.Initialize) |
|---|
| 139 |
self.root = SequenceMgr.RootSequence() |
|---|
| 140 |
|
|---|
| 141 |
self.clearcolor = Buffers.ClearColor((0.5,0.5,1.0,0.0)) |
|---|
| 142 |
self.root.AddElement(self.clearcolor, -2) |
|---|
| 143 |
|
|---|
| 144 |
self.viewport = Viewport.Viewport() |
|---|
| 145 |
self.root.AddElement(self.viewport, -2) |
|---|
| 146 |
|
|---|
| 147 |
self.root.AddElement(Blending.Blend(), -1) |
|---|
| 148 |
|
|---|
| 149 |
self.subseq = SequenceMgr.SequenceBase() |
|---|
| 150 |
self.root.AddElement(self.subseq) |
|---|
| 151 |
|
|---|
| 152 |
self.projection = Transformations.OrthographicMgd(GL.GL_PROJECTION, True, -1, 1, -1, 1, -1, 1) |
|---|
| 153 |
self.subseq.AddElement(self.projection.GLSelect) |
|---|
| 154 |
self.subseq.AddPostElement(self.projection.GLDeselect) |
|---|
| 155 |
|
|---|
| 156 |
viewportrect = self.glcanvas.GetClientRect().asTuple() |
|---|
| 157 |
|
|---|
| 158 |
self.pickbuffer = Selection.SelectionBuffer() |
|---|
| 159 |
self.pickmatrix = Transformations.ViewBoxMappingMatrixMgd(GL.GL_PROJECTION, True) |
|---|
| 160 |
self.pickmatrix.PickEnabled = False |
|---|
| 161 |
|
|---|
| 162 |
self.pickseq = SequenceMgr.RootSequence() |
|---|
| 163 |
self.pickseq.AddElement(self.pickbuffer.GLSelect) |
|---|
| 164 |
self.pickseq.AddElement(self.pickmatrix.GLSelect) |
|---|
| 165 |
self.pickseq.AddElement(self.subseq.GLExecute) |
|---|
| 166 |
self.pickseq.AddElement(self.pickmatrix.GLDeselect) |
|---|
| 167 |
self.pickseq.AddElement(self.pickbuffer.GLDeselect) |
|---|
| 168 |
|
|---|
| 169 |
color0 = Numeric.asarray((0., 0., 0., 0.), Numeric.Float) |
|---|
| 170 |
color1 = Numeric.asarray((1., 1., 1., 1.), Numeric.Float) |
|---|
| 171 |
count = 10. |
|---|
| 172 |
self.selectables = {} |
|---|
| 173 |
for i in range(1, int(1+count)): |
|---|
| 174 |
f = i/count |
|---|
| 175 |
cube = Cube(f, (3*i, +2*i, -5*i), color=(color0*(1-f)+color1*f)) |
|---|
| 176 |
self.subseq.AddElement(cube.GLExecute) |
|---|
| 177 |
self.selectables[id(cube)] = cube |
|---|
| 178 |
|
|---|
| 179 |
self.Initialized = True |
|---|
| 180 |
|
|---|
| 181 |
def Render(self, glviewsetup, canvas): |
|---|
| 182 |
viewportrect = canvas.GetClientRect().asTuple() |
|---|
| 183 |
self.viewport.SetRectangle(viewportrect) |
|---|
| 184 |
self.projection.SetDimensionsAspectRatio(2., 2., self.viewport.GetAspectRatio()) |
|---|
| 185 |
self.root.GLExecute(None) |
|---|
| 186 |
|
|---|
| 187 |
if self.IsPickingEnabled(): |
|---|
| 188 |
self.pickseq.GLExecute(None) |
|---|
| 189 |
|
|---|
| 190 |
for each in self.selectables.itervalues(): |
|---|
| 191 |
each.SetSelected(False) |
|---|
| 192 |
for selection in self.pickbuffer.Selection: |
|---|
| 193 |
each = selection.Resolve(self.selectables) |
|---|
| 194 |
each.SetSelected(True) |
|---|
| 195 |
|
|---|
| 196 |
if time.clock() - self._fps_score >= .2: |
|---|
| 197 |
self.frame.SetTitle(self.frametitle + ' [FPS: %1.1f, |Picked|=%d]' % (self.fps, len(self.pickbuffer.Selection))) |
|---|
| 198 |
self.fps = self.root.Statistics['persecond'] |
|---|
| 199 |
self._fps_score = time.clock() |
|---|
| 200 |
|
|---|
| 201 |
def OnMouse(self, evt): |
|---|
| 202 |
evt.Skip() |
|---|
| 203 |
if not self.Initialized: |
|---|
| 204 |
return |
|---|
| 205 |
self.pickmatrix.PickEnabled = True |
|---|
| 206 |
if self.IsPickingEnabled(): |
|---|
| 207 |
x, y = evt.GetPosition() |
|---|
| 208 |
pw, ph = (2,2) |
|---|
| 209 |
pos0, pos1 = (x-pw, y-ph), (x+pw, y+ph) |
|---|
| 210 |
pos0, pos1 = self.viewport.MapPointsTo([pos0, pos1], flipy=True) |
|---|
| 211 |
self.pickmatrix.MapFrom.SetPts(pos0, pos1) |
|---|
| 212 |
|
|---|
| 213 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 214 |
#~ Main |
|---|
| 215 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 216 |
|
|---|
| 217 |
def Run(): |
|---|
| 218 |
application = wx.wxPySimpleApp() |
|---|
| 219 |
scene = CubeScene() |
|---|
| 220 |
scene.OnSkinInitialize() |
|---|
| 221 |
skin = SkinXML(skinxml, application=application, scene=scene) |
|---|
| 222 |
scene.OnSkinFinalize() |
|---|
| 223 |
skin.context.application.MainLoop() |
|---|
| 224 |
|
|---|
| 225 |
if __name__ == '__main__': |
|---|
| 226 |
Run() |
|---|
| 227 |
|
|---|