Hello again,
actually it should have been a quick test, I usually don’t put runtime execution code on module level.
To avoid complications, I have put the init code into main_init function, to be called by a task. Not very nice, but way from module level. I hope the globals don’t matter.
But now I can not even correct the p3d-settings at runtime. Yesterday I’ve had a state, where I could still see the edge of geometry at start, but when I moved it completely disappered.
Now, I cannot see geometry at all. But from command-line it works well. Also, in browser-plugin the motion cannot be changed by a, s, d, w, shift or space.
Here’s the code + model:
http://skylet.de/welcome/static/flatten_approach.7z
and here the plug-in on a 5-minute-quick-hack website:
http://skylet.de/skycraft/default/index
For quick view directly the code. It’s a mess and inefficient, I know. But I’d like command-line and plugin to behave equally, at first.
from panda3d.core import Texture, GeomNode
from panda3d.core import GeomVertexFormat, GeomVertexData
from panda3d.core import Geom, GeomTriangles, GeomTristrips, GeomVertexWriter
from panda3d.core import Vec3, Vec4, Point3
from pandac.PandaModules import TextNode
from direct.directbase.DirectStart import *
from direct.showbase.DirectObject import DirectObject
from direct.task import Task
from random import choice
import time
import math
Q = 1 #: The ultimate cube edge length
LVU = Vec3(0, 0, 0)
LVO = Vec3(0, 0, Q)
RVU = Vec3(Q, 0, 0)
RVO = Vec3(Q, 0, Q)
LHU = Vec3(0, Q, 0)
LHO = Vec3(0, Q, Q)
RHU = Vec3(Q, Q, 0)
RHO = Vec3(Q, Q, Q)
v3_bg_color = Vec3(0.8, 0.8, 1)
d_map = {}
f_factor_h = -30.0
f_factor_p = 30.0
facx = 0.1
facy = 0.1
class Cube(object):
v3_center_offs = Vec3(0.5*Q, 0.5*Q, 0.5*Q) #: Offset vom node pos to center
def __init__(self, chunk, v3_pos):
self.chunk = chunk
self.v3_pos = v3_pos
self.v3_center = v3_pos + Cube.v3_center_offs
self.d_faces = {}
def create_faces(self):
for i_face_orient in xrange(6):
face = Face(cube=self, i_typ=i_face_orient)
face.make_face()
self.d_faces[i_face_orient] = face
class Face(object):
LEFT = 0
RIGHT = 1
BACK = 2
FRONT = 3
BOTTOM = 4
TOP = 5
def __init__(self, cube, i_typ):
"""Object to handle a visible face of a cube
@param cube: reference to the cube the face belongs to
@type cube: Cube
@param typ: the face type of the cube
@type typ: the ID of the represented face (Face.LEFT, Face.RIGHT, ...)
"""
self.cube = cube
self.i_typ = i_typ
self.is_drawn = False
def make_face(self):
v3 = self.cube.v3_pos
id = 1
chunk = self.cube.chunk
if self.i_typ == Face.FRONT:
v1, v2, color = v3 + RHU, v3 + LHO, 0.4
if self.i_typ == Face.BACK:
v1, v2, color = v3 + LVU, v3 + RVO, 0.8
if self.i_typ == Face.RIGHT:
v1, v2, color = v3 + RVU, v3 + RHO, 1.0
if self.i_typ == Face.LEFT:
v1, v2, color = v3 + LHU, v3 + LVO, 0.3
if self.i_typ == Face.TOP:
v1, v2, color = v3 + RHO, v3 + LVO, 0.7
if self.i_typ == Face.BOTTOM:
v1, v2, color = v3 + LHU, v3 + RVU, 0.6
x1, y1, z1 = v1
x2, y2, z2 = v2
if x1 != x2:
_v0 = chunk.vertex.getWriteRow()
chunk.vertex.addData3f(x1, y1, z1)
chunk.vertex.addData3f(x2, y1, z1)
chunk.vertex.addData3f(x2, y2, z2)
chunk.vertex.addData3f(x1, y2, z2)
else:
_v0 = chunk.vertex.getWriteRow()
chunk.vertex.addData3f(x1, y1, z1)
chunk.vertex.addData3f(x2, y2, z1)
chunk.vertex.addData3f(x2, y2, z2)
chunk.vertex.addData3f(x1, y1, z2)
chunk.color.addData4f(color, color, color, 1.0)
chunk.color.addData4f(color, color, color, 1.0)
chunk.color.addData4f(color, color, color, 1.0)
chunk.color.addData4f(color, color, color, 1.0)
if id == 1:
chunk.texcoord.addData2f(0.0, 1.0)
chunk.texcoord.addData2f(0.0, 0.0)
chunk.texcoord.addData2f(0.5, 0.0)
chunk.texcoord.addData2f(0.5, 1.0)
elif id == 2:
chunk.texcoord.addData2f(0.5, 1.0)
chunk.texcoord.addData2f(0.5, 0.0)
chunk.texcoord.addData2f(1.0, 0.0)
chunk.texcoord.addData2f(1.0, 1.0)
chunk.tristrips.addVertices(_v0, _v0 + 1, _v0 + 3, _v0 + 2)
chunk.tristrips.closePrimitive()
self.is_drawn = True
class Chunk(object):
format = GeomVertexFormat.getV3c4t2()
def __init__(self, v3_pos=Vec3(0, 0, 0), name="Chunk"):
self.d_cubes = {}
self.name = name
self.vertex_data = GeomVertexData(name, self.format, Geom.UHStatic)
self.tristrips = GeomTristrips(Geom.UHStatic)
self.vertex = GeomVertexWriter(self.vertex_data, 'vertex')
self.color = GeomVertexWriter(self.vertex_data, 'color')
self.texcoord = GeomVertexWriter(self.vertex_data, 'texcoord')
def get_geom_node(self):
geom_node = GeomNode(self.name)
mesh = Geom(self.vertex_data)
mesh.addPrimitive(self.tristrips)
geom_node.addGeom(mesh)
return geom_node
def add_cube(self, cube):
self.d_cubes[cube.v3_pos] = cube
return cube
def draw_cubes(self):
for cube in self.d_cubes.itervalues():
cube.create_faces()
class World(DirectObject):
def __init__(self):
self.d_keys = {"a":False, "s":False, "d":False,
"w":False, "shift":False, "space":False}
self.accept( "a" , self.a_down_callback )
self.accept( "d" , self.d_down_callback )
self.accept( "w" , self.w_down_callback )
self.accept( "s" , self.s_down_callback )
self.accept( "shift" , self.lshift_down_callback )
self.accept( "space" , self.space_down_callback )
self.accept( "a-up" , self.a_up_callback )
self.accept( "d-up" , self.d_up_callback )
self.accept( "w-up" , self.w_up_callback )
self.accept( "s-up" , self.s_up_callback )
self.accept( "shift-up" , self.lshift_up_callback )
self.accept( "space-up" , self.space_up_callback )
self.accept( "mouse1", self.mouse_left_callback )
self.accept( "escape", self.quit_callback )
def translate_camera_along_vec(self, scale=None):
"""Projects cam coord-system onto world coord. system before translation
@keyword vel: vector indicating the desired translation relative to the camera. If omitted, vel is created from x, y, z keyword params
@type vel: LVecBase3f | None
@keyword x: x portion of the desired translation relativ to the camera, ignored if keyword param is given and non-zero
@type x: Real number
@keyword y: y portion of the desired translation relativ to the camera, ignored if keyword param is given and non-zero
@type y: Real number
@keyword z: z portion of the desired translation relativ to the camera, ignored if keyword param is given and non-zero
@type z: Real number
@keyword scale: if given, then a copy of vec is normalized and multiplied by scale, so only vec's direction is relevant, not its total length
@type scale: Float for true division
@return: the camera gets translated
@rvalue: None
"""
if self.d_keys["a"]: v3_vel[0] = -0.4
if self.d_keys["d"]: v3_vel[0] = 0.4
if self.d_keys["s"]: v3_vel[1] = -0.5
if self.d_keys["w"]: v3_vel[1] = 0.5
if self.d_keys["shift"]: v3_vel[2] = -0.2
if self.d_keys["space"]: v3_vel[2] = 0.2
x, y, z = v3_vel
base.camera.setPos(base.camera, v3_vel)
if x >= 0:
v3_vel[0] = max(0, x-0.08)
if x < 0:
v3_vel[0] = min(0, x+0.08)
if y >= 0:
v3_vel[1] = max(0, y-0.06)
if y < 0:
v3_vel[1] = min(0, y+0.06)
if z >= 0:
v3_vel[2] = max(0, z-0.05)
if z < 0:
v3_vel[2] = min(0, z+0.05)
#base.mouseWatcherNode.setMat(mat)
#print dir(base.camera)
def a_down_callback(self): self.d_keys["a"] = True
def s_down_callback(self): self.d_keys["s"] = True
def d_down_callback(self): self.d_keys["d"] = True
def w_down_callback(self): self.d_keys["w"] = True
def lshift_down_callback(self): self.d_keys["shift"] = True
def space_down_callback(self): self.d_keys["space"] = True
def a_up_callback(self): self.d_keys["a"] = False
def s_up_callback(self): self.d_keys["s"] = False
def d_up_callback(self): self.d_keys["d"] = False
def w_up_callback(self): self.d_keys["w"] = False
def lshift_up_callback(self): self.d_keys["shift"] = False
def space_up_callback(self): self.d_keys["space"] = False
def arrow_up_callback(self):
print "up arrow pressed"
base.camera.setY(base.camera, 5)
def arrow_down_callback(self):
print "down arrow pressed"
base.camera.setY(base.camera, -5)
def mouse_left_callback(self):
print "left mouse button clicked:"
def quit_callback(self):
raise SystemExit()
def main(task):
global text, w, v3_vel, chunk
base.setBackgroundColor(v3_bg_color)
chunk = Chunk()
print "define cubes"
n=100
for x in xrange(n):
print "x:", x+1, "von", n
for y in xrange(n):
z_max = int(8*(math.sin(x*facx)+math.cos(y*facy)))
for z in xrange(z_max+1):
d_map[(x, y, z)] = 1
print "create cubes"
for pos, typ in d_map.iteritems():
c = chunk.add_cube(Cube(chunk=chunk, v3_pos=Vec3(*pos)))
print "draw cubes"
chunk.draw_cubes()
chunk_np = render.attachNewNode(chunk.get_geom_node())
chunk_np.setTexture(loader.loadTexture("tex.png"))
chunk_np.setPos(0, 0, 0)
print "cubes drawn, start copying the chunk"
i = 1
for x in xrange(i):
for y in xrange(i):
if x or y:
np = render.attachNewNode("copy")
copy = chunk_np.copyTo(np)
copy.setPos(x*n, y*n, 0)
print "finished creating"
base.camera.lookAt(0, 0, 0)
v3_vel = Vec3(0, 0, 0)
w = World()
base.win.movePointer(0, 0, 0)
##########################################################
text = TextNode('node name')
text.setText("test")
textNodePath = aspect2d.attachNewNode(text)
textNodePath.setScale(0.05)
textNodePath.setX(0)
#######################################################
if abs(base.camera.getH()) > 1000:
base.camera.setH(0)
text.setText("heading reset")
return Task.done
def findCenter():
# Querry the screen size
# and calculate the center
props = base.win.getProperties()
winX = props.getXSize()
winY = props.getYSize()
return [winX / 2, winY / 2]
def mouseTask(task):
# variable to save center coordinates
center = findCenter()
try:
# Get mouse coordinates from mouse watcher
x=base.mouseWatcherNode.getMouseX()
y=base.mouseWatcherNode.getMouseY()
move = [x,y]
text.setText("curr hpr: %s" % base.camera.getHpr() + " %s" % (base.camera.getPos())) #(base.camera.getH(), f_factor_h*x))
if x or y:
base.camera.setH(base.camera.getH() + f_factor_h*x)
f_p = base.camera.getP() + y * f_factor_p
base.camera.setP(f_p)
# Reset the cursor to the center of the screen
base.win.movePointer(0, center[0], center[1])
w.translate_camera_along_vec()
except Exception, s:
# If mouse goes outside window, catch the
# exception here and pass gracefully.
print "Exception in mouseTask:", s
return Task.cont
# Add the task and Run
taskMgr.add(main, 'maintask_init')
taskMgr.add(mouseTask, 'myTask')
base.disableMouse()
run()
Thanks, BR
Michael