SheetNode and NURBS-surfaces in general are used for very compact surface-representation with kind of unlimited LOD.
As for big surfaces SheetNode is too slow because it re-tesselates the surface every frame i wrote something almost compatible.
Each update/generate is really slow but rendering is much faster.
# -*- coding: utf-8 -*-
'''
Created on 20.02.2010
@author: Praios
'''
from pandac.PandaModules import GeomVertexData, GeomVertexFormat, Geom, GeomVertexWriter, GeomTristrips, GeomNode, Vec3, PandaNode, Point3
class Sheet(PandaNode):
def __init__(self, name, nse=None):
self._clean = False
self._nse = nse
self._usub = 2
self._vsub = 2
self._uvc = False
PandaNode.__init__(self, name)
if nse is not None:
self.generate()
def getNumUSubdiv(self):
return self._usub
def getNumVSubdiv(self):
return self._vsub
def getSurface(self):
return self._nse
def setNumUSubdiv(self, n):
self._usub = n
self._clean = False
def setNumVSubdiv(self, n):
self._vsub = n
self._clean = False
def setSurface(self, nse):
self._nse = nse
self._clean = False
def setUseVertexColors(self, b):
self._uvc = bool(b)
self._clean = False
def getUseVertexColors(self):
return self._uvc
def update(self):
if self._clean:
return False
self.generate()
return True
def generate_OLD(self):
usub, vsub, nsr, uvc = self._usub * self._nse.getNumUKnots(), self._vsub * self._nse.getNumVKnots(), self._nse.evaluate(), self._uvc
self._clean = True
if uvc:
vdata = GeomVertexData('name', GeomVertexFormat.getV3n3c4t2(), Geom.UHStatic)
color = GeomVertexWriter(vdata, 'color')
else:
vdata = GeomVertexData('name', GeomVertexFormat.getV3n3t2(), Geom.UHStatic)
vertex = GeomVertexWriter(vdata, 'vertex')
normal = GeomVertexWriter(vdata, 'normal')
texcoord = GeomVertexWriter(vdata, 'texcoord')
vec = Vec3(0, 0, 0)
umin, umax = nsr.getStartU(), nsr.getEndU()
ustep = (umax - umin) / usub
vmin, vmax = nsr.getStartV(), nsr.getEndV()
vstep = (vmax - vmin) / vsub
for ui in xrange(usub):
for vi in xrange(vsub):
u, v = ui * ustep + umin, vi * vstep + vmin
nsr.evalPoint(u, v, vec)
vertex.addData3f(vec)
nsr.evalNormal(u, v, vec)
normal.addData3f(vec)
texcoord.addData2f(u, v)
if uvc:
color.addData4f([nsr.evalExtendedPoint(u, v, i) for i in (0, 1, 2, 3)])
prim = GeomTristrips(Geom.UHStatic)
for ui in xrange(usub - 1):
for vi in xrange(vsub - 1):
i = ui * vsub + vi
prim.addVertices(i, i + vsub)
prim.closePrimitive()
geom = Geom(vdata)
geom.addPrimitive(prim)
node = GeomNode('gnode')
node.addGeom(geom)
self.removeAllChildren()
self.addChild(node)
def generate(self):
result = self._nse.evaluate()
use_vertex_color = self._uvc
num_u_segments = result.getNumUSegments()
num_v_segments = result.getNumVSegments()
num_u_verts = self._usub + 1
num_v_verts = self._vsub + 1
if use_vertex_color:
format = GeomVertexFormat.getV3n3c4t2()
else:
format = GeomVertexFormat.getV3n3t2()
vdata = GeomVertexData("sheet", format, Geom.UHStatic);
vertex = GeomVertexWriter(vdata, 'vertex')
normal = GeomVertexWriter(vdata, 'normal')
texcoord = GeomVertexWriter(vdata, 'texcoord')
color = GeomVertexWriter(vdata, 'color')
strip = GeomTristrips(Geom.UHStatic)
point = Point3()
norm = Vec3()
for ui in xrange(num_u_segments):
for uni in xrange(num_u_verts):
u0 = float(uni) / num_u_verts
u1 = float(uni + 1) / num_u_verts
u0_tc = result.getSegmentU(ui, u0)
u1_tc = result.getSegmentU(ui, u1)
for vi in xrange(num_v_segments):
for vni in xrange(num_v_verts):
v = float(vni) / (num_v_verts - 1)
v_tc = result.getSegmentV(vi, v)
result.evalSegmentPoint(ui, vi, u0, v, point)
result.evalSegmentNormal(ui, vi, u0, v, norm)
vertex.addData3f(point)
normal.addData3f(norm)
texcoord.addData2f(u0_tc, v_tc)
result.evalSegmentPoint(ui, vi, u1, v, point)
result.evalSegmentNormal(ui, vi, u1, v, norm)
vertex.addData3f(point)
normal.addData3f(norm)
texcoord.addData2f(u1_tc, v_tc)
if use_vertex_color:
color.add_data4f(result.evalSegmentExtendedPoint(ui, vi, u0, v, 0, 4))
color.add_data4f(result.evalSegmentExtendedPoint(ui, vi, u1, v, 0, 4))
strip.addNextVertices(num_v_verts * 2)
strip.closePrimitive()
geom = Geom(vdata)
geom.addPrimitive(strip)
node = GeomNode('gnode')
node.addGeom(geom)
self.removeAllChildren()
self.addChild(node)
edit: better SheetNode compatibility (but slower)
edit2: removed doubled vertices in the prim-loop (i hope)
edit3: added SheetNode-stop-switch to the wishlist
edit4: started learning c++, added reimplementation from c+±code
edit5: small optimizations, marked old code ‘OLD’
edit6,7: typos
edit8: added short description of what nurbs-mean