예제 #1
0
    def generateVertices(self):
        self.vertexBuffer.setNumRows(len(self.vertices))

        vwriter = GeomVertexWriter(self.vertexBuffer, "vertex")
        cwriter = GeomVertexWriter(self.vertexBuffer, "color")
        for i in range(len(self.vertices)):
            vwriter.setData3f(self.vertices[i])
            cwriter.setData4f(self.color)

        Geometry.generateVertices(self)
예제 #2
0
    def modifyGeometryUVs(self):
        # Modifies the geometry vertex UVs in-place
        twriter = GeomVertexWriter(self.vdata, InternalName.getTexcoord())
        tanwriter = GeomVertexWriter(self.vdata, InternalName.getTangent())
        bwriter = GeomVertexWriter(self.vdata, InternalName.getBinormal())

        for i in range(len(self.vertices)):
            twriter.setData2f(self.vertices[i].uv)
            tanwriter.setData3f(self.material.tangent)
            bwriter.setData3f(self.material.binormal)
예제 #3
0
    def projectVerticesToShadow(self):

        inVertices = self.unmodifiedVertexData
        modelWorldX = self.modelWorldX
        modelWorldY = self.modelWorldY
        modelWorldZ = self.modelWorldZ
        zRotationDegrees = self.modelRotation
        lightWorldX = self.lightWorldX
        lightWorldY = self.lightWorldY
        lightWorldZ = self.lightWorldZ

        zRotationRadians = zRotationDegrees * (math.pi / 180.0)
        mathCosZRotationRadians = math.cos(zRotationRadians)
        mathSinZRotationRadians = math.sin(zRotationRadians)

        vdata = self.pandaVertexData
        vertex = GeomVertexWriter(vdata, 'vertex')

        for inVertex in inVertices:
            vertexModelX, vertexModelY, vertexModelZ = inVertex

            vertexModelOldX = vertexModelX
            vertexModelOldY = vertexModelY
            vertexModelX = vertexModelOldX * mathCosZRotationRadians - vertexModelOldY * mathSinZRotationRadians
            vertexModelY = vertexModelOldX * mathSinZRotationRadians + vertexModelOldY * mathCosZRotationRadians

            vertexWorldX = modelWorldX + vertexModelX
            vertexWorldY = modelWorldY + vertexModelY
            vertexWorldZ = modelWorldZ + vertexModelZ
            vertexLightZDiff = vertexWorldZ - lightWorldZ
            shadowVertexX = lightWorldX + (
                (vertexWorldX - lightWorldX) * -lightWorldZ / vertexLightZDiff)
            shadowVertexY = lightWorldY + (
                (vertexWorldY - lightWorldY) * -lightWorldZ / vertexLightZDiff)

            normalisedShadowVertexX = shadowVertexX - modelWorldX
            normalisedShadowVertexY = shadowVertexY - modelWorldY
            normalisedShadowVertexZ = 0

            vertex.setData3f(normalisedShadowVertexX, normalisedShadowVertexY,
                             normalisedShadowVertexZ)
예제 #4
0
파일: Mesh.py 프로젝트: tsp-team/panda3d
class Mesh:
    def __init__(self):
        self.views = []
        self.vertexBuffer = GeomVertexData('mesh-vdata',
                                           GeomVertexFormat.getV3n3t2(),
                                           GeomEnums.UHDynamic)
        self.np = NodePath("mesh")

        self.vwriter = None
        self.twriter = None
        self.nwriter = None

    def addView(self, primitiveType, drawMask, state=None):
        self.views.append(
            PolygonView(self, primitiveType, drawMask, renderState=state))

    def begin(self, numVerts):
        self.vertexBuffer.uncleanSetNumRows(numVerts)
        for view in self.views:
            view.clear()
        self.vwriter = GeomVertexWriter(self.vertexBuffer,
                                        InternalName.getVertex())
        self.twriter = GeomVertexWriter(self.vertexBuffer,
                                        InternalName.getTexcoord())
        self.nwriter = GeomVertexWriter(self.vertexBuffer,
                                        InternalName.getNormal())

    def end(self):
        self.vwriter = None
        self.nwriter = None
        self.twriter = None

    def addFace(self, meshVertices, state=RenderState.makeEmpty()):
        row = self.vwriter.getWriteRow()
        for vert in meshVertices:
            self.vwriter.setData3f(vert.pos)
            self.nwriter.setData3f(vert.normal)
            self.twriter.setData2f(vert.texcoord)
        for view in self.views:
            view.generateIndices()
예제 #5
0
	def projectVerticesToShadow(self):

		inVertices=self.unmodifiedVertexData
		modelWorldX=self.modelWorldX
		modelWorldY=self.modelWorldY
		modelWorldZ=self.modelWorldZ
		zRotationDegrees=self.modelRotation
		lightWorldX=self.lightWorldX
		lightWorldY=self.lightWorldY
		lightWorldZ=self.lightWorldZ

		zRotationRadians=zRotationDegrees*(math.pi/180.0)
		mathCosZRotationRadians=math.cos(zRotationRadians)
		mathSinZRotationRadians=math.sin(zRotationRadians)

		vdata=self.pandaVertexData
		vertex = GeomVertexWriter(vdata, 'vertex')

		for inVertex in inVertices:
			vertexModelX,vertexModelY,vertexModelZ=inVertex

			vertexModelOldX=vertexModelX
			vertexModelOldY=vertexModelY
			vertexModelX=vertexModelOldX*mathCosZRotationRadians-vertexModelOldY*mathSinZRotationRadians
			vertexModelY=vertexModelOldX*mathSinZRotationRadians+vertexModelOldY*mathCosZRotationRadians

			vertexWorldX=modelWorldX+vertexModelX
			vertexWorldY=modelWorldY+vertexModelY
			vertexWorldZ=modelWorldZ+vertexModelZ
			vertexLightZDiff=vertexWorldZ-lightWorldZ
			shadowVertexX=lightWorldX+((vertexWorldX-lightWorldX)*-lightWorldZ/vertexLightZDiff)
			shadowVertexY=lightWorldY+((vertexWorldY-lightWorldY)*-lightWorldZ/vertexLightZDiff)

			normalisedShadowVertexX=shadowVertexX-modelWorldX
			normalisedShadowVertexY=shadowVertexY-modelWorldY
			normalisedShadowVertexZ=0

			vertex.setData3f(normalisedShadowVertexX,normalisedShadowVertexY,normalisedShadowVertexZ)
예제 #6
0
    def generateVertices(self):

        self.vertexBuffer.setNumRows(4)

        vwriter = GeomVertexWriter(self.vertexBuffer, "vertex")
        cwriter = GeomVertexWriter(self.vertexBuffer, "color")

        vwriter.setData3f(self.mins.x, 0, self.mins.z)
        cwriter.setData4f(self.color)

        vwriter.setData3f(self.mins.x, 0, self.maxs.z)
        cwriter.setData4f(self.color)

        vwriter.setData3f(self.maxs.x, 0, self.maxs.z)
        cwriter.setData4f(self.color)

        vwriter.setData3f(self.maxs.x, 0, self.mins.z)
        cwriter.setData4f(self.color)

        Geometry.generateVertices(self)
예제 #7
0
 def generateNode(self):        
     self.destroy()
     
     self.node = NodePath('gameobjectnode')
     self.node.setTwoSided(True)
     self.node.reparentTo(self.parent.node)
     
     if self.properties['avoidable'] == True:
         self.node.setTag("avoidable", 'true')
     else:
         self.node.setTag("avoidable", 'false')
     
     #setting scripting part
     self.node.setTag("onWalked", self.onWalked)
     self.node.setTag("onPicked", self.onPicked)
     #set unique id
     self.node.setTag("id", self.properties['id'])
     
     tex = loader.loadTexture(resourceManager.getResource(self.properties['url'])+'.png')
     tex.setWrapV(Texture.WM_clamp)
     tex.setWrapU(Texture.WM_clamp)
     
     #this is true pixel art
     #change to FTLinear for linear interpolation between pixel colors
     tex.setMagfilter(Texture.FTNearest)
     tex.setMinfilter(Texture.FTNearest)
     
     xorig = tex.getOrigFileXSize() / self.baseDimension
     yorig = tex.getOrigFileYSize() / self.baseDimension
     xscaled = (tex.getOrigFileXSize() / self.baseDimension) * self.properties['scale']
     yscaled = (tex.getOrigFileYSize() / self.baseDimension) * self.properties['scale']
     
     self.node.setTag("xscaled", str(xscaled))
     self.node.setTag("yscaled", str(yscaled))
     
     cm = CardMaker("tileobject")
     cm.setFrame(0,xorig,0,yorig)
     
     ts = TextureStage('ts')
     ts.setMode(TextureStage.MDecal)
     
     # distinguish between 3d collisions (for objects with an height and sensible self.properties['inclination'])
     # and 2d collisions for plain sprites
     if self.properties['walkable'] == 'false':
         if self.properties['collisionmode'] == "3d":
             #must handle differently objects which are small and big
             if xscaled < 1:
                 self.collisionTube = CollisionBox(LPoint3f(0.5 - xscaled/2 - self.properties['offsetwidth'],0,0),LPoint3f(0.5 + xscaled/2 + self.properties['offsetwidth'],0.1,0.3 + self.properties['offsetheight']))
                 
             if xscaled >= 1:
                 self.collisionTube = CollisionBox(LPoint3f(0 - self.properties['offsetwidth'],0,0),LPoint3f(xscaled + self.properties['offsetwidth'],0.1,0.3 + self.properties['offsetheight']))
             
             self.collisionNode = CollisionNode('objectSphere')
             self.collisionNode.addSolid(self.collisionTube)
             self.collisionNodeNp = self.node.attachNewNode(self.collisionNode)
             self.collisionNodeNp.setX(self.properties['offsethorizontal'])
             self.collisionNodeNp.setZ(self.properties['offsetvertical'])
             self.collisionNodeNp.setX(self.collisionNodeNp.getX()+self.properties['offsetcollisionh'])
             self.collisionNodeNp.setZ(self.collisionNodeNp.getZ()+self.properties['offsetcollisionv']+0.1)
             if main.editormode:
                 self.collisionNodeNp.show()
             
         elif self.properties['collisionmode'] == "2d":
             #must handle differently objects which are small and big
             if xscaled < 1:
                 self.collisionTube = CollisionBox(LPoint3f(0.5 - xscaled/2 - self.properties['offsetwidth'],0,0),LPoint3f(0.5 + xscaled/2 + self.properties['offsetwidth'],yscaled + self.properties['offsetheight'],0.3))
                 
             if xscaled >= 1:
                 self.collisionTube = CollisionBox(LPoint3f(0 - self.properties['offsetwidth'],0,0),LPoint3f(xscaled + self.properties['offsetwidth'],yscaled + self.properties['offsetheight'],0.3))
             
             self.collisionNode = CollisionNode('objectSphere')
             self.collisionNode.addSolid(self.collisionTube)
             self.collisionNodeNp = self.node.attachNewNode(self.collisionNode)
             self.collisionNodeNp.setP(-(270-int(self.properties['inclination'])))
             self.collisionNodeNp.setX(self.properties['offsethorizontal'])
             self.collisionNodeNp.setZ(self.properties['offsetvertical'])
             self.collisionNodeNp.setX(self.collisionNodeNp.getX()+self.properties['offsetcollisionh'])
             self.collisionNodeNp.setZ(self.collisionNodeNp.getZ()+self.properties['offsetcollisionv']+0.1)
             if main.editormode:
                 self.collisionNodeNp.show()
     
     geomnode = NodePath(cm.generate())
     if geomnode.node().isGeomNode():
         vdata = geomnode.node().modifyGeom(0).modifyVertexData()
         writer = GeomVertexWriter(vdata, 'vertex')
         reader = GeomVertexReader(vdata, 'vertex')
         
         '''
         this part apply rotation flattening to the perspective view
         by modifying directly structure vertices
         '''
         i = 0 #counter
         while not reader.isAtEnd():
             v = reader.getData3f()
             x = v[0]
             y = v[1]
             z = v[2]
             newx = x
             newy = y
             newz = z
             if self.properties['rotation'] == -90.0:
                 if i == 0:
                     newx = math.fabs(math.cos(math.radians(self.properties['inclination']))) * z
                     newz = 0
                     ssen = math.fabs(math.sin(math.radians(self.properties['inclination']))) * z
                     sparsen = math.fabs(math.sin(math.radians(self.properties['inclination']))) * ssen
                     spercos = math.fabs(math.cos(math.radians(self.properties['inclination']))) * ssen
                     newy -= spercos
                     newz += sparsen
                 if i == 2:
                     newx += math.fabs(math.cos(math.radians(self.properties['inclination']))) * z
                     newz = 0
                     ssen = math.fabs(math.sin(math.radians(self.properties['inclination']))) * z
                     sparsen = math.fabs(math.sin(math.radians(self.properties['inclination']))) * ssen
                     spercos = math.fabs(math.cos(math.radians(self.properties['inclination']))) * ssen
                     newy -= spercos
                     newz += sparsen
                 writer.setData3f(newx, newy, newz)
             i += 1 #increase vertex counter
     if xscaled >= 1:
         geomnode.setX(0)
     if xscaled < 1:
         geomnode.setX(0.5 - xscaled/2)
     geomnode.setScale(self.properties['scale'])
     geomnode.setX(geomnode.getX()+self.properties['offsethorizontal'])
     geomnode.setZ(geomnode.getZ()+self.properties['offsetvertical'])
     geomnode.setY(-self.properties['elevation'])
     geomnode.setP(int(self.properties['inclination'])-360)
     geomnode.setTexture(tex)
     geomnode.setTransparency(TransparencyAttrib.MAlpha)
     geomnode.reparentTo(self.node)
     self.node.setR(self.properties['rotation'])
예제 #8
0
    def regenerateGeometry(self):
        #
        # Generate vertex data
        #

        numVerts = len(self.vertices)

        vdata = GeomVertexData("SolidFace", getFaceFormat(), GeomEnums.UHStatic)
        vdata.uncleanSetNumRows(len(self.vertices))

        vwriter = GeomVertexWriter(vdata, InternalName.getVertex())
        twriter = GeomVertexWriter(vdata, InternalName.getTexcoord())
        nwriter = GeomVertexWriter(vdata, InternalName.getNormal())
        tanwriter = GeomVertexWriter(vdata, InternalName.getTangent())
        bwriter = GeomVertexWriter(vdata, InternalName.getBinormal())

        for i in range(len(self.vertices)):
            vert = self.vertices[i]
            vwriter.setData3f(vert.pos)
            twriter.setData2f(vert.uv)
            nwriter.setData3f(self.plane.getNormal())
            tanwriter.setData3f(self.material.tangent)
            bwriter.setData3f(self.material.binormal)

        #
        # Generate indices
        #

        # Triangles in 3D view
        prim3D = GeomTriangles(GeomEnums.UHStatic)
        prim3D.reserveNumVertices((numVerts - 2) * 3)
        for i in range(1, numVerts - 1):
            prim3D.addVertices(i + 1, i, 0)
            prim3D.closePrimitive()

        # Line loop in 2D view.. using line strips
        prim2D = GeomLinestrips(GeomEnums.UHStatic)
        prim2D.reserveNumVertices(numVerts + 1)
        for i in range(numVerts):
            prim2D.addVertex(i)
        # Close off the line strip with the first vertex.. creating a line loop
        prim2D.addVertex(0)
        prim2D.closePrimitive()

        #
        # Generate mesh objects
        #

        geom3D = SolidFaceGeom(vdata)
        geom3D.setDrawMask(VIEWPORT_3D_MASK)
        geom3D.setPlaneCulled(True)
        geom3D.setPlane(self.plane)
        geom3D.addPrimitive(prim3D)
        self.index3D = self.solid.addFaceGeom(geom3D, self.state3D)

        geom3DLines = SolidFaceGeom(vdata)
        geom3DLines.addPrimitive(prim2D)
        geom3DLines.setDrawMask(VIEWPORT_3D_MASK)
        geom3DLines.setDraw(False)
        self.index3DLines = self.solid.addFaceGeom(geom3DLines, self.state3DLines)

        geom2D = SolidFaceGeom(vdata)
        geom2D.addPrimitive(prim2D)
        geom2D.setDrawMask(VIEWPORT_2D_MASK)
        self.index2D = self.solid.addFaceGeom(geom2D, self.state2D)

        self.geom3D = geom3D
        self.geom3DLines = geom3DLines
        self.geom2D = geom2D

        self.vdata = vdata

        self.hasGeometry = True
예제 #9
0
 def interpolate_maps(self, task):
     # First, the actual interpolation
     t_index = self.last_time
     current_map = {}
     for x in range(0, self.sidelength):
         for y in range(0, self.sidelength):
             # calculate vertices
             p_1 = self.map_a[(x, y)]
             p_2 = self.map_b[(x, y)]
             v_x = p_1[0]*(1.0-t_index) + p_2[0]*t_index
             v_y = p_1[1]*(1.0-t_index) + p_2[1]*t_index
             v_z = p_1[2]*(1.0-t_index) + p_2[2]*t_index
             current_map[(x, y)] = (v_x, v_y, v_z)
     # Set up the writers
     vertex = GeomVertexWriter(self.vdata, 'vertex')
     normal = GeomVertexWriter(self.vdata, 'normal')
     # We don't use vertex readers as we don't care about the
     # current state, but if we did, it'd look like this:
     #     vertex_reader = GeomVertexReader(self.vdata, 'vertex')
     #     v = vertex_reader.getData3f()
     # Remember that all vertex readers working on a
     # GeomVertexData have to be created *after* the writers
     # working on it (due to engine internals; see the manual).
     for x in range(0, self.sidelength):
         for y in range(0, self.sidelength):
             v_x, v_y, v_z = current_map[(x, y)]
             vertex.setData3f(v_x, v_y, v_z)
             # Calculate the normal
             if x==0 and y==0:
                 s_0 = Vec3( 0.0,  1.0, v_z - current_map[(x, y+1)][2])
                 s_1 = Vec3( 1.0,  0.0, v_z - current_map[(x+1, y)][2])
                 e_0 = s_0.cross(s_1)
                 # Flip if necessary, then normalize
                 if e_0[2] < 0.0:
                     e_0 = e_0*-1.0
                 n = e_0
                 n = n/n.length()
             elif x==0 and y==(self.sidelength-1):
                 # First, we calculate the vectors to the neighbors.
                 s_1 = Vec3( 1.0,  0.0, v_z - current_map[(x+1, y)][2])
                 s_2 = Vec3( 0.0, -1.0, v_z - current_map[(x, y-1)][2])
                 e_1 = s_1.cross(s_2)
                 # Flip if necessary, then normalize
                 if e_1[2] < 0.0:
                     e_1 = e_1*-1.0
                 n = e_1
                 n = n/n.length()
             elif x==(self.sidelength-1) and y==0:
                 # First, we calculate the vectors to the neighbors.
                 s_0 = Vec3( 0.0,  1.0, v_z - current_map[(x, y+1)][2])
                 s_3 = Vec3(-1.0,  0.0, v_z - current_map[(x-1, y)][2])
                 e_3 = s_3.cross(s_0)
                 # Flip if necessary, then normalize
                 if e_3[2] < 0.0:
                     e_3 = e_3*-1.0
                 n = e_3
                 n = n/n.length()
             elif x==(self.sidelength-1) or y==(self.sidelength-1):
                 # First, we calculate the vectors to the neighbors.
                 s_2 = Vec3( 0.0, -1.0, v_z - current_map[(x, y-1)][2])
                 s_3 = Vec3(-1.0,  0.0, v_z - current_map[(x-1, y)][2])
                 e_2 = s_2.cross(s_3)
                 # Flip if necessary, then normalize
                 if e_2[2] < 0.0:
                     e_2 = e_2*-1.0
                 n = e_2
                 n = n/n.length()
             elif x==0:
                 # First, we calculate the vectors to the neighbors.
                 s_0 = Vec3( 0.0,  1.0, v_z - current_map[(x, y+1)][2])
                 s_1 = Vec3( 1.0,  0.0, v_z - current_map[(x+1, y)][2])
                 s_2 = Vec3( 0.0, -1.0, v_z - current_map[(x, y-1)][2])
                 e_0 = s_0.cross(s_1)
                 e_1 = s_1.cross(s_2)
                 # Flip if necessary, then normalize
                 if e_0[2] < 0.0:
                     e_0 = e_0*-1.0
                 if e_1[2] < 0.0:
                     e_1 = e_1*-1.0
                 n = e_0 + e_1
                 n = n/n.length()
             elif y==0:
                 # First, we calculate the vectors to the neighbors.
                 s_0 = Vec3( 0.0,  1.0, v_z - current_map[(x, y+1)][2])
                 s_1 = Vec3( 1.0,  0.0, v_z - current_map[(x+1, y)][2])
                 s_3 = Vec3(-1.0,  0.0, v_z - current_map[(x-1, y)][2])
                 e_0 = s_0.cross(s_1)
                 e_3 = s_3.cross(s_0)
                 # Flip if necessary, then normalize
                 if e_0[2] < 0.0:
                     e_0 = e_0*-1.0
                 if e_3[2] < 0.0:
                     e_3 = e_3*-1.0
                 n = e_0 + e_3
                 n = n/n.length()
             elif x==(self.sidelength-1):
                 # First, we calculate the vectors to the neighbors.
                 s_1 = Vec3( 1.0,  0.0, v_z - current_map[(x+1, y)][2])
                 s_2 = Vec3( 0.0, -1.0, v_z - current_map[(x, y-1)][2])
                 s_3 = Vec3(-1.0,  0.0, v_z - current_map[(x-1, y)][2])
                 e_1 = s_1.cross(s_2)
                 e_2 = s_2.cross(s_3)
                 # Flip if necessary, then normalize
                 if e_1[2] < 0.0:
                     e_1 = e_1*-1.0
                 if e_2[2] < 0.0:
                     e_2 = e_2*-1.0
                 n = e_1 + e_2
                 n = n/n.length()
             elif y==(self.sidelength-1):
                 # First, we calculate the vectors to the neighbors.
                 s_1 = Vec3( 1.0,  0.0, v_z - current_map[(x+1, y)][2])
                 s_2 = Vec3( 0.0, -1.0, v_z - current_map[(x, y-1)][2])
                 s_3 = Vec3(-1.0,  0.0, v_z - current_map[(x-1, y)][2])
                 e_1 = s_1.cross(s_2)
                 e_2 = s_2.cross(s_3)
                 # Flip if necessary, then normalize
                 if e_1[2] < 0.0:
                     e_1 = e_1*-1.0
                 if e_2[2] < 0.0:
                     e_2 = e_2*-1.0
                 n = e_1 + e_2
                 n = n/n.length()
             else: # This is a normal case, not an edge or corner.
                 # First, we calculate the vectors to the neighbors.
                 s_0 = Vec3( 0.0,  1.0, v_z - current_map[(x, y+1)][2])
                 s_1 = Vec3( 1.0,  0.0, v_z - current_map[(x+1, y)][2])
                 s_2 = Vec3( 0.0, -1.0, v_z - current_map[(x, y-1)][2])
                 s_3 = Vec3(-1.0,  0.0, v_z - current_map[(x-1, y)][2])
                 e_0 = s_0.cross(s_1)
                 e_1 = s_1.cross(s_2)
                 e_2 = s_2.cross(s_3)
                 e_3 = s_3.cross(s_0)
                 # Flip if necessary, then normalize
                 if e_0[2] < 0.0:
                     e_0 = e_0*-1.0
                 if e_1[2] < 0.0:
                     e_1 = e_1*-1.0
                 if e_2[2] < 0.0:
                     e_2 = e_2*-1.0
                 if e_3[2] < 0.0:
                     e_3 = e_3*-1.0
                 n = e_0 + e_1 + e_2 + e_3
                 n = n/n.length()
             normal.setData3f(n[0], n[1], n[2])
     return Task.cont
예제 #10
0
    def generateVertices(self):

        if self.handleType == HandleType.Square:
            self.vertexBuffer.setNumRows(len(self.handleOrigins) * 8)
            vwriter = GeomVertexWriter(self.vertexBuffer, "vertex")
            cwriter = GeomVertexWriter(self.vertexBuffer, "color")
            radius = self.radius / self.zoom
            add = radius * 0.08

            for origin in self.handleOrigins:
                ul = Point3(origin.x - radius, 0, origin.z - radius)
                lr = Point3(origin.x + radius + add, 0,
                            origin.z + radius + add)

                # Border
                vwriter.setData3f(ul.x, 0.1, ul.z)
                cwriter.setData4f(self.Black)
                vwriter.setData3f(lr.x, 0.1, ul.z)
                cwriter.setData4f(self.Black)
                vwriter.setData3f(lr.x, 0.1, lr.z)
                cwriter.setData4f(self.Black)
                vwriter.setData3f(ul.x, 0.1, lr.z)
                cwriter.setData4f(self.Black)

                ul.x += add
                ul.z += add
                lr.x -= add
                lr.z -= add

                vwriter.setData3f(ul.x, 0, ul.z)
                cwriter.setData4f(self.White)
                vwriter.setData3f(lr.x, 0, ul.z)
                cwriter.setData4f(self.White)
                vwriter.setData3f(lr.x, 0, lr.z)
                cwriter.setData4f(self.White)
                vwriter.setData3f(ul.x, 0, lr.z)
                cwriter.setData4f(self.White)

        Geometry.generateVertices(self)
class Planetimpl():
    def __init__(self, world, size, distance, ratio, description, rotation, translation):
        self.worldOrigin = world
        self.size = size
        self.distance = distance
        self.renderRatio = ratio
        self.description = description
        self.rotation = rotation
        self.translation = translation

    def impl(self):
        # Load the Moon model
        self.planet = loader.loadModel("models/planet_sphere")
        self.chooseTexture("models/"+self.description+"_1k_tex.jpg")
        self.planet.reparentTo(self.worldOrigin)
        self.planet.setScale(self.size * self.renderRatio)
        self.planet.setPos(self.distance * self.renderRatio, 0.0, 0.0)
        self.planet.setTag('targetSize', str(self.size))
        self.planet.setTag('isPickable', '2')
        self.startstop = True
        return self.planet

    def chooseTexture(self, name):
        """
        Methode zum Setzen der Ursprungstextur
        """
        self.planet.setTexture(loader.loadTexture(name), 1)

    def line(self):
        # Create and populate the Moon orbit model using Vertices and Lines
        self.planetOrbitVertexData = GeomVertexData(self.description+'OrbitVertexData', GeomVertexFormat.getV3(), Geom.UHDynamic)
        self.planetOrbitVertexWriter = GeomVertexWriter(self.planetOrbitVertexData, 'vertex')
        self.planetOrbitNumberPoints = 360
        for i in range(self.planetOrbitNumberPoints):
            angleDegrees = i * 360 / self.planetOrbitNumberPoints
            angleRadians = angleDegrees * (pi / 180.0)
            x = -self.distance * sin(angleRadians)
            y =  self.distance * cos(angleRadians)
            self.planetOrbitVertexWriter.addData3f(x, y, 0.0)
        self.planetOrbitLines = GeomLines(Geom.UHStatic)
        for i in range(self.planetOrbitNumberPoints-1):
            self.planetOrbitLines.addVertex(i)
            self.planetOrbitLines.addVertex(i+1)
            self.planetOrbitLines.closePrimitive()
            self.planetOrbitLines.addVertex(self.planetOrbitNumberPoints-1)
            self.planetOrbitLines.addVertex(0)
        self.planetOrbitLines.closePrimitive()
        self.planetOrbitGeom = Geom(self.planetOrbitVertexData)
        self.planetOrbitGeom.addPrimitive(self.planetOrbitLines)
        self.planetOrbitNode = GeomNode(self.description+'OrbitNode')
        self.planetOrbitNode.addGeom(self.planetOrbitGeom)
        self.planetOrbitNnodePath = render.attachNewNode(self.planetOrbitNode)
        self.planetOrbitNnodePath.reparentTo(self.worldOrigin)
        return self.planetOrbitVertexWriter

    def setstartstop(self):
        self.startstop = not self.startstop
        return self.startstop

    def rotatePlanet(self, task):
        # Compute earth rotation
        frameTime = globalClock.getFrameTime()
        angleDegrees = frameTime *  self.rotation
        self.planet.setHpr(angleDegrees, 0, 0)
        # End task
        if self.startstop:
            return Task.cont
        else:
            return Task.done



    def translatePlanet(self, task):
        # Compute Moon position relative to Earth with circular orbit
        frameTime = globalClock.getFrameTime()
        angleDegrees = frameTime *  self.translation
        angleRadians = angleDegrees * (pi / 180.0)

        # Compute the Moon's position with respect to the Earth
        x = -self.distance * self.renderRatio * sin(angleRadians)
        y =  self.distance * self.renderRatio * cos(angleRadians)

        # Set the position on the model
        self.planet.setPos(x, y, 0.0)

        # Also rotate the orbit to follow the Moon and eliminate jitter effect
        self.planetOrbitVertexWriter.setRow(0)
        for i in range(self.planetOrbitNumberPoints):
            angleDegrees = angleDegrees + 360.0 / self.planetOrbitNumberPoints
            angleRadians = angleDegrees * (pi / 180.0)
            x = -self.distance * self.renderRatio * sin(angleRadians)
            y =  self.distance * self.renderRatio * cos(angleRadians)
            self.planetOrbitVertexWriter.setData3f(x, y, 0.0)

        # End task
        if self.startstop:
            return Task.cont
        else:
            return Task.done