我其實有2個問題。 1)我看到成千上萬個體素的這些渲染,但是使用八叉樹我仍然可以在屏幕上獲得大約500個體素。人們如何一次呈現如此多的體素?
import warnings,sys
sys.setrecursionlimit(50000)
class storedItem():
def __init__(self,coord,data):
self.coord = coord
self.data = data
self.node = None
def remove(self):
self.node.children.remove(self)
self.node = None
class Node():
def __init__(self,parent,lower,upper):
self.parent = parent
self.children = []
self.lowerbound = lower
self.upperbound = upper
self.setVolume()
def setVolume(self):
dx = self.upperbound[0] - self.lowerbound[0]
dy = self.upperbound[1] - self.lowerbound[1]
dz = self.upperbound[2] - self.lowerbound[2]
self.volume = dx*dy*dz
def inbound(self,coord):
if self.lowerbound[0] <= coord[0] and self.lowerbound[1] <= coord[1] and self.lowerbound[2] <= coord[2]:
if self.upperbound[0] >= coord[0] and self.upperbound[1] >= coord[1] and self.upperbound[2] >= coord[2]:
return True
return False
def returnValueOrChildnode(self,coord):
if not self.inbound(coord):
return self.parent
for child in self.children:
if child.__class__ == Node:
if child.inbound(coord):
return child
elif child.__class__ == storedItem:
if child.coord == coord:
return child
return None
def deleteOrReturnChildNode(self,coord):
if not self.inbound(coord):
return self.parent
for child in self.children:
if child.__class__ == Node:
if child.inbound(coord):
return child
elif child.__class__ == storedItem:
if child.coord == coord:
self.children.remove(child)
del(child)
return True
return None
def insertStoredItem(self,item):
if len(self.children) < 8:
self.children.append(item)
item.node = self
return True
if len(self.children) == 8:
for child in self.children:
if child.__class__ == Node:
if child.inbound(item.coord):
return child.insertStoredItem(item)
elif item.coord == child.coord:
warnings.warn('Already an item at this location, replacing it')
self.children.remove(child)
self.children.append(item)
self.breakupIntoChildren()
self.insertStoredItem(item)
def breakupIntoChildren(self):
#if self.volume == 8:
# raise Exception("Node full. Cannot add to this node")
nodes = []
delta = (self.upperbound[0] - self.lowerbound[0] +1)/2
x1,x2,x3 = (self.lowerbound[0],self.lowerbound[0]+delta -1,self.upperbound[0])
y1,y2,y3 = (self.lowerbound[1],self.lowerbound[1]+delta -1,self.upperbound[1])
z1,z2,z3 = (self.lowerbound[2],self.lowerbound[2]+delta -1,self.upperbound[2])
nodes.append(Node(self,(x1,y1,z1),(x2,y2,z2)))
nodes.append(Node(self,(x2 + 1,y1,z1),(x3,y2,z2)))
nodes.append(Node(self,(x1,y1,z2 +1),(x2,y2,z3)))
nodes.append(Node(self,(x2 + 1,y1,z2 + 1),(x3,y2,z3)))
nodes.append(Node(self,(x1,y2 + 1,z1),(x2,y3,z2)))
nodes.append(Node(self,(x2 + 1,y2 + 1,z1),(x3,y3,z2)))
nodes.append(Node(self,(x1,y2 + 1,z2 + 1),(x2,y3,z3)))
nodes.append(Node(self,(x2 + 1,y2 + 1,z2 + 1),(x3,y3,z3)))
while self.children:
child = self.children[0]
for node in nodes:
if node.inbound(child.coord):
node.insertStoredItem(child)
self.children.remove(child)
self.children = nodes
class Octree():
def __init__(self,size,maxsearch=1000):
if size % 2:
raise Exception("Size must be multiple of 2")
self.root = Node(None, (0,0,0),(size,size,size))
self.size = size
self.maxsearch=maxsearch
def search(self,coord):
searching = True
node = self.root
count = 0
while searching:
result = node.returnValueOrChildnode(coord)
if result is None:
searching = False
elif result.__class__ == storedItem:
result = result.data
searching = False
elif result.__class__ == Node:
node = result
count += 1
if count > self.maxsearch: #just incase something goes wrong
searching=False
result = None
raise Exception("Max Search depth limit reached")
return result
def insert(self,coord,data):
if not self.root.inbound(coord):
print coord, self.size, self.root.upperbound, self.root.lowerbound
raise Exception("Coordinate outside scope of octree")
item = storedItem(coord,data)
self.root.insertStoredItem(item)
def remove(self,coord):
searching = True
node = self.root
count = 0
while searching:
result = node.deleteOrReturnChildNode(coord)
if result is True:
searching = False
return True
elif result is None:
searching = False
elif result.__class__ == Node:
node = result
count += 1
if count > self.maxsearch: #just incase something goes wrong
searching=False
result = None
raise Exception("Max Search depth limit reached")
return result
def trace(frame, event, arg):
print "%s, %s:%d" % (event, frame.f_code.co_filename, frame.f_lineno)
return trace
這就是我一直在使用的八叉樹代碼。我把它從一個網站上拿下來,這個網站非常整潔。它可以很好地去除內部的立方體。雖然它只是一個空心的盒子,這很奇怪。雖然它確實大大提高了FPS。爲了渲染立方體,我使用這個小類。
class Cube(object):
def __init__(self, position, color,tree):
self.position = position
self.x = position[0]
self.y = position[1]
self.z = position[2]
self.color = color
self.tree = tree
num_faces = 6
vertices = [ (0.0, 0.0, 1.0),
(1.0, 0.0, 1.0),
(1.0, 1.0, 1.0),
(0.0, 1.0, 1.0),
(0.0, 0.0, 0.0),
(1.0, 0.0, 0.0),
(1.0, 1.0, 0.0),
(0.0, 1.0, 0.0) ]
normals = [ (0.0, 0.0, +1.0), # front
(0.0, 0.0, -1.0), # back
(+1.0, 0.0, 0.0), # right
(-1.0, 0.0, 0.0), # left
(0.0, +1.0, 0.0), # top
(0.0, -1.0, 0.0) ] # bottom
vertex_indices = [ (0, 1, 2, 3), # front
(4, 5, 6, 7), # back
(1, 5, 6, 2), # right
(0, 4, 7, 3), # left
(3, 2, 6, 7), # top
(0, 1, 5, 4) ] # bottom
def render(self):
glColor(self.color)
# Adjust all the vertices so that the cube is at self.position
vertices = [tuple(Vector3(v) + self.position) for v in self.vertices]
# Draw all 6 faces of the cube
glBegin(GL_QUADS)
for face_no in xrange(self.num_faces):
glNormal3dv(self.normals[face_no])
v1, v2, v3, v4 = self.vertex_indices[face_no]
glVertex(vertices[v1])
glVertex(vertices[v2])
glVertex(vertices[v3])
glVertex(vertices[v4])
glEnd()
def getneighbors(self):
x = self.x
y = self.y
z = self.z
return ((x,y,z+1),(x+1,y,z),(x,y+1,z),(x-1,y,z),(x,y-1,z),(x,y,z-1))
def checkneighbors(self):
if not self.tree:
return True
positions = self.getneighbors()
for pos in positions:
result = self.tree.search(pos)
if not result:
return True
return False
我可以得到約30FPS與此代碼。我認爲屏幕上有大約62,210個方格。我通常得到大約30-40 FPS(這並不壞)。
當你有兩個獨立的問題,你應該問他們獨立。我想你可以刪除第二個問題,因爲這裏有足夠的資源(例如http://stackoverflow.com/questions/4753055/perlin-noise-generation-for-terrain)。要回答你的第一個問題,你應該提供更多的細節。你現在怎麼渲染它們? – Nobody
請顯示您的代碼。如果不顯示它,爲什麼代碼不能像你期望的那樣工作是不可能的。 –
我添加了代碼。 –