Exemple #1
0
    def setPoints(self, pathPoints):
        threeDPathPoints = []
        for pathPoint in pathPoints:
            if len(pathPoint) == 2:
                threeDPathPoints += [(pathPoint[0], pathPoint[1], 0.0)]
            else:
                threeDPathPoints += [pathPoint]
        pathPoints = threeDPathPoints

        if pathPoints != self._pathPoints:
            while self.geometry().getNumPrimitiveSets() > 0:
                self.geometry().removePrimitiveSet(0)

            self._pathPoints = pathPoints

            vertices = []
            pointVertices = []
            textureCoords = []
            pointCoords = []

            prevPoint = None
            pathLength = 0.0
            tweak = -0.0001 * random.random()
            for pathPoint in self._pathPoints:
                if prevPoint != None:
                    pathLength += sqrt((pathPoint[0] - prevPoint[0])**2 +
                                       (pathPoint[1] - prevPoint[1])**2 +
                                       (pathPoint[2] - prevPoint[2])**2)
                vertices += [(pathPoint[0], pathPoint[1], pathPoint[2] + tweak)
                             ]
                textureCoords += [(pathLength, pathLength)]
                if pathPoint != self._pathPoints[
                        0] and pathPoint != self._pathPoints[-1]:
                    tweak *= -1.0
                    vertices += [(pathPoint[0], pathPoint[1],
                                  pathPoint[2] + tweak)]
                    textureCoords += [(pathLength, pathLength)]
                pointVertices += [
                    (pathPoint[0], pathPoint[1], pathPoint[2] - 0.0001)
                ]  # always beyond tweak
                pointCoords += [(pathLength, pathLength)]
                prevPoint = pathPoint

            self.geometry().setVertexArray(
                Shape.vectorArrayFromList(vertices + pointVertices))
            self.geometry().addPrimitiveSet(
                Shape.primitiveSetFromList(osg.PrimitiveSet.LINES,
                                           range(len(vertices))))
            self.geometry().addPrimitiveSet(
                Shape.primitiveSetFromList(
                    osg.PrimitiveSet.POINTS,
                    range(len(vertices),
                          len(vertices) + len(self._pathPoints))))
            self.geometry().setNormalArray(
                Shape.vectorArrayFromList([(0.0, 0.0, 0.0)]))
            self.geometry().setNormalBinding(osg.Geometry.BIND_OVERALL)
            self.geometry().setTexCoordArray(
                0, Shape.vectorArrayFromList(textureCoords + pointCoords))

            self.geometry().dirtyDisplayList()
Exemple #2
0
 def __init__(self, tessellation = 3, *args, **keywordArgs):
     Shape.__init__(self, *args, **keywordArgs)
     
     self.tessellation = tessellation
     vertices, normals, texCoords, faceSet = Ball._geometryAtTessellation(tessellation)
     self.geometry().setVertexArray(vertices)
     self.geometry().setNormalArray(normals)
     self.geometry().setNormalBinding(osg.Geometry.BIND_PER_VERTEX)
     self.geometry().setTexCoordArray(0, texCoords)
     self.geometry().addPrimitiveSet(faceSet)
Exemple #3
0
 def __init__(self, segments = 32, *args, **keywordArgs):
     Shape.__init__(self, *args, **keywordArgs)
     
     # TODO: use VBO's so all instances share the same data?
     # TODO: should have separate vertex per angled face so they can have face-specific normals
     
     self.segments = segments
     angleStep = 2.0 * pi / self.segments
     
     vertices = [(0.0, 0.5, 0.0)]
     vertexNormals = [(0.0, 1.0, 0.0)]
     textureCoords = [(1.0, 1.0)]
     for increment in range(0, self.segments):
         angle = increment * angleStep
         vertex = (sin(angle) * 0.5, -0.5, cos(angle) * 0.5)
         vertices += [vertex]
         vertexNormals += [(vertex[0] / .7071, 0.0, vertex[2] / .7071)]
         textureCoords += [(0.1, 0.1)]
     vertices += vertices[1:self.segments + 1]
     vertices += [(0.0, -0.5, 0.0)]
     vertexNormals += [(0.0, -1.0, 0.0)] * (self.segments + 1)
     textureCoords += textureCoords[1:self.segments + 1]
     textureCoords += [(0.0, 0.0)]
     self.geometry().setVertexArray(Shape.vectorArrayFromList(vertices))
     
     faceSet = Shape.primitiveSetFromList(osg.PrimitiveSet.TRIANGLE_FAN, range(0, self.segments + 1) + [1, 0])
     self.geometry().addPrimitiveSet(faceSet)
     faceSet = Shape.primitiveSetFromList(osg.PrimitiveSet.TRIANGLE_FAN, [self.segments * 2 + 1] + range(self.segments + 1, self.segments * 2 + 1) + [self.segments + 1, self.segments * 2 + 1])
     self.geometry().addPrimitiveSet(faceSet)
     
     self.geometry().setNormalArray(Shape.vectorArrayFromList(vertexNormals))
     self.geometry().setNormalBinding(osg.Geometry.BIND_PER_VERTEX)
     
     self.geometry().setTexCoordArray(0, Shape.vectorArrayFromList(textureCoords))
Exemple #4
0
 def setPoints(self, pathPoints):
     threeDPathPoints = []
     for pathPoint in pathPoints:
         if len(pathPoint) == 2:
             threeDPathPoints += [(pathPoint[0], pathPoint[1], 0.0)]
         else:
             threeDPathPoints += [pathPoint]
     pathPoints = threeDPathPoints
     
     if pathPoints != self._pathPoints:
         while self.geometry().getNumPrimitiveSets() > 0:
             self.geometry().removePrimitiveSet(0)
         
         self._pathPoints = pathPoints
 
         vertices = []
         pointVertices = []
         textureCoords = []
         pointCoords = []
         
         prevPoint = None
         pathLength = 0.0
         tweak = -0.0001 * random.random()
         for pathPoint in self._pathPoints:
             if prevPoint != None:
                 pathLength += sqrt((pathPoint[0] - prevPoint[0]) ** 2 + (pathPoint[1] - prevPoint[1]) ** 2 + (pathPoint[2] - prevPoint[2]) ** 2)
             vertices += [(pathPoint[0], pathPoint[1], pathPoint[2] + tweak)]
             textureCoords += [(pathLength, pathLength)]
             if pathPoint != self._pathPoints[0] and pathPoint != self._pathPoints[-1]:
                 tweak *= -1.0
                 vertices += [(pathPoint[0], pathPoint[1], pathPoint[2] + tweak)]
                 textureCoords += [(pathLength, pathLength)]
             pointVertices += [(pathPoint[0], pathPoint[1], pathPoint[2] - 0.0001)] # always beyond tweak
             pointCoords += [(pathLength, pathLength)]
             prevPoint = pathPoint
         
         self.geometry().setVertexArray(Shape.vectorArrayFromList(vertices + pointVertices))
         self.geometry().addPrimitiveSet(Shape.primitiveSetFromList(osg.PrimitiveSet.LINES, range(len(vertices))))
         self.geometry().addPrimitiveSet(Shape.primitiveSetFromList(osg.PrimitiveSet.POINTS, range(len(vertices), len(vertices) + len(self._pathPoints))))
         self.geometry().setNormalArray(Shape.vectorArrayFromList([(0.0, 0.0, 0.0)]))
         self.geometry().setNormalBinding(osg.Geometry.BIND_OVERALL)
         self.geometry().setTexCoordArray(0, Shape.vectorArrayFromList(textureCoords + pointCoords))
         
         self.geometry().dirtyDisplayList()
Exemple #5
0
 def __init__(self, *args, **keywordArgs):
     UnitShape.__init__(self, *args, **keywordArgs)
     
     # TODO: use VBO's so all instances share the same data?
     
     baseVertices = [(-0.5, -0.5, -0.5), (-0.5, -0.5,  0.5), (-0.5,  0.5, -0.5), (-0.5,  0.5,  0.5), ( 0.5, -0.5, -0.5), ( 0.5, -0.5,  0.5), ( 0.5,  0.5, -0.5), ( 0.5,  0.5,  0.5)]
     
     vertices = []
     faceNormals = []
     texCoords = []
     for (v0, v1, v2, v3, normal) in [(0, 1, 3, 2, (-1.0, 0.0, 0.0)), (2, 3, 7, 6, (0.0, 1.0, 0.0)), (6, 7, 5, 4, (1.0, 0.0, 0.0)), (4, 5, 1, 0, (0.0, -1.0, 0.0)), (3, 1, 5, 7, (0.0, 0.0, 1.0)), (0, 2, 6, 4, (0.0, 0.0, -1.0))]:
         vertices += [baseVertices[v0], baseVertices[v1], baseVertices[v2], baseVertices[v3]]
         faceNormals += [normal]
         texCoords += [(0, 1), (0, 0), (1, 0), (1, 1)]
         faceSet = Shape.primitiveSetFromList(osg.PrimitiveSet.QUADS, [len(vertices) - 4, len(vertices) - 3, len(vertices) - 2, len(vertices) - 1])
         self.geometry().addPrimitiveSet(faceSet)
     
     self.geometry().setVertexArray(Shape.vectorArrayFromList(vertices))
     self.geometry().setNormalArray(Shape.vectorArrayFromList(faceNormals))
     self.geometry().setNormalBinding(osg.Geometry.BIND_PER_PRIMITIVE_SET)
     self.geometry().setTexCoordArray(0, Shape.vectorArrayFromList(texCoords))
Exemple #6
0
    def __init__(self, *args, **keywordArgs):
        Shape.__init__(self, *args, **keywordArgs)

        # TODO: use VBO's so all instances share the same data?

        steps = 32
        angleStep = 2.0 * pi / steps

        topVertices = []
        bottomVertices = []
        sideNormals = []
        for step in range(0, steps):
            angle = step * angleStep
            x, z = (sin(angle) * 0.5, cos(angle) * 0.5)
            topVertices += [(x, 0.5, z)]
            bottomVertices += [(x, -0.5, z)]
            sideNormals += [(x / 0.5, 0.0, z / 0.5)]
        vertices = [(0.0, 0.5, 0.0)] + topVertices
        vertexNormals = [(0.0, 1.0, 0.0)] * (steps + 1)
        textureCoords = [(1.0, 1.0)] + [(0.9, 0.9)] * steps
        for step in range(0, steps):
            vertices += [topVertices[step], bottomVertices[step]]
            vertexNormals += [sideNormals[step], sideNormals[step]]
            textureCoords += [(0.9, 0.9), (0.1, 0.1)]
        vertices += bottomVertices + [(0.0, -0.5, 0.0)]
        vertexNormals += [(0.0, -1.0, 0.0)] * (steps + 1)
        textureCoords += [(0.1, 0.1)] * steps + [(0.0, 0.0)]
        self.geometry().setVertexArray(Shape.vectorArrayFromList(vertices))

        faceSet = Shape.primitiveSetFromList(osg.PrimitiveSet.TRIANGLE_FAN,
                                             range(0, steps + 1) + [1, 0])
        self.geometry().addPrimitiveSet(faceSet)
        faceSet = Shape.primitiveSetFromList(
            osg.PrimitiveSet.QUAD_STRIP,
            range(steps + 1, 3 * steps + 1) + [steps + 1, steps + 2])
        self.geometry().addPrimitiveSet(faceSet)
        faceSet = Shape.primitiveSetFromList(
            osg.PrimitiveSet.TRIANGLE_FAN,
            [4 * steps + 1] + range(3 * steps + 1, 4 * steps + 1) +
            [3 * steps + 1, 4 * steps + 1])
        self.geometry().addPrimitiveSet(faceSet)

        self.geometry().setNormalArray(
            Shape.vectorArrayFromList(vertexNormals))
        self.geometry().setNormalBinding(osg.Geometry.BIND_PER_VERTEX)

        self.geometry().setTexCoordArray(
            0, Shape.vectorArrayFromList(textureCoords))
 def __init__(self, *args, **keywordArgs):
     Shape.__init__(self, *args, **keywordArgs)
     
     # TODO: use VBO's so all instances share the same data?
     
     steps = 32
     angleStep = 2.0 * pi / steps
     
     topVertices = []
     bottomVertices = []
     sideNormals = []
     for step in range(0, steps):
         angle = step * angleStep
         x, z = (sin(angle) * 0.5, cos(angle) * 0.5)
         topVertices += [(x, 0.5, z)]
         bottomVertices += [(x, -0.5, z)]
         sideNormals += [(x / 0.5, 0.0, z / 0.5)]
     vertices = [(0.0, 0.5, 0.0)] + topVertices
     vertexNormals = [(0.0, 1.0, 0.0)] * (steps + 1)
     textureCoords = [(1.0, 1.0)] + [(0.9, 0.9)] * steps
     for step in range(0, steps):
         vertices += [topVertices[step], bottomVertices[step]]
         vertexNormals += [sideNormals[step], sideNormals[step]]
         textureCoords += [(0.9, 0.9), (0.1, 0.1)]
     vertices += bottomVertices + [(0.0, -0.5, 0.0)]
     vertexNormals += [(0.0, -1.0, 0.0)] * (steps + 1)
     textureCoords += [(0.1, 0.1)] * steps + [(0.0, 0.0)]
     self.geometry().setVertexArray(Shape.vectorArrayFromList(vertices))
     
     faceSet = Shape.primitiveSetFromList(osg.PrimitiveSet.TRIANGLE_FAN, range(0, steps + 1) + [1, 0])
     self.geometry().addPrimitiveSet(faceSet)
     faceSet = Shape.primitiveSetFromList(osg.PrimitiveSet.QUAD_STRIP, range(steps + 1, 3 * steps + 1) + [steps + 1, steps + 2])
     self.geometry().addPrimitiveSet(faceSet)
     faceSet = Shape.primitiveSetFromList(osg.PrimitiveSet.TRIANGLE_FAN, [4 * steps + 1] + range(3 * steps + 1, 4 * steps + 1) + [3 * steps + 1, 4 * steps + 1])
     self.geometry().addPrimitiveSet(faceSet)
     
     self.geometry().setNormalArray(Shape.vectorArrayFromList(vertexNormals))
     self.geometry().setNormalBinding(osg.Geometry.BIND_PER_VERTEX)
     
     self.geometry().setTexCoordArray(0, Shape.vectorArrayFromList(textureCoords))
Exemple #8
0
    def __init__(self, segments=32, *args, **keywordArgs):
        Shape.__init__(self, *args, **keywordArgs)

        # TODO: use VBO's so all instances share the same data?
        # TODO: should have separate vertex per angled face so they can have face-specific normals

        self.segments = segments
        angleStep = 2.0 * pi / self.segments

        vertices = [(0.0, 0.5, 0.0)]
        vertexNormals = [(0.0, 1.0, 0.0)]
        textureCoords = [(1.0, 1.0)]
        for increment in range(0, self.segments):
            angle = increment * angleStep
            vertex = (sin(angle) * 0.5, -0.5, cos(angle) * 0.5)
            vertices += [vertex]
            vertexNormals += [(vertex[0] / .7071, 0.0, vertex[2] / .7071)]
            textureCoords += [(0.1, 0.1)]
        vertices += vertices[1:self.segments + 1]
        vertices += [(0.0, -0.5, 0.0)]
        vertexNormals += [(0.0, -1.0, 0.0)] * (self.segments + 1)
        textureCoords += textureCoords[1:self.segments + 1]
        textureCoords += [(0.0, 0.0)]
        self.geometry().setVertexArray(Shape.vectorArrayFromList(vertices))

        faceSet = Shape.primitiveSetFromList(
            osg.PrimitiveSet.TRIANGLE_FAN,
            range(0, self.segments + 1) + [1, 0])
        self.geometry().addPrimitiveSet(faceSet)
        faceSet = Shape.primitiveSetFromList(
            osg.PrimitiveSet.TRIANGLE_FAN, [self.segments * 2 + 1] +
            range(self.segments + 1, self.segments * 2 + 1) +
            [self.segments + 1, self.segments * 2 + 1])
        self.geometry().addPrimitiveSet(faceSet)

        self.geometry().setNormalArray(
            Shape.vectorArrayFromList(vertexNormals))
        self.geometry().setNormalBinding(osg.Geometry.BIND_PER_VERTEX)

        self.geometry().setTexCoordArray(
            0, Shape.vectorArrayFromList(textureCoords))
Exemple #9
0
    def __init__(self,
                 capiness=0.5,
                 interiorIncludesCaps=False,
                 *args,
                 **keywordArgs):
        """ Create a new capsule shape.
        
        The 'capiness' parameter controls how much of the shape is made up of the caps.  A 1.0 value would be all caps and effectively be a sphere.  A 0.0 value would be no caps and effectively be a cylinder. 
        
        The interiorIncludesCaps parameter controls whether nested shapes should extend up into the caps or should be restrained to the cylinder portion of the capsule."""

        Shape.__init__(self, *args, **keywordArgs)

        # TODO: use VBO's so all instances share the same data?
        # TODO: fix seams caused by texture coords

        self.capiness = capiness
        self.interiorIncludesCaps = interiorIncludesCaps

        steps = 32  # must be multiple of four
        angleIncrement = 2.0 * pi / steps
        capSteps = steps / 4
        azimuthIncrement = pi / 2.0 / capSteps

        topVertices = []
        topTexCoords = []
        bottomVertices = []
        bottomTexCoords = []
        for azimuthStep in range(0, capSteps):
            topAzimuth = pi / 2.0 - (azimuthStep + 1) * azimuthIncrement
            topY, topMag = (sin(topAzimuth) * (capiness / 2.0),
                            cos(topAzimuth) * 0.5)
            bottomAzimuth = -azimuthStep * azimuthIncrement
            bottomY, bottomMag = (sin(bottomAzimuth) * (capiness / 2.0),
                                  cos(bottomAzimuth) * 0.5)
            for step in range(0, steps):
                angle = pi + step * angleIncrement
                topVertices += [
                    (sin(angle) * topMag, topY + (0.5 * (1.0 - capiness)),
                     cos(angle) * topMag)
                ]
                topTexCoords += [(float(step) / steps,
                                  topVertices[-1][1] + 0.5)]
                bottomVertices += [(sin(angle) * bottomMag,
                                    -(0.5 * (1.0 - capiness)) + bottomY,
                                    cos(angle) * bottomMag)]
                bottomTexCoords += [(float(step) / steps,
                                     bottomVertices[-1][1] + 0.5)]

        vertices = [(0.0, 0.5, 0.0)
                    ] + topVertices + bottomVertices + [(0.0, -0.5, 0.0)]
        self.geometry().setVertexArray(Shape.vectorArrayFromList(vertices))

        normals = []
        for vertex in vertices:
            normals += [(vertex[0] / 2.0, vertex[1] / 2.0, vertex[2] / 2.0)]
        self.geometry().setNormalArray(Shape.vectorArrayFromList(normals))
        self.geometry().setNormalBinding(osg.Geometry.BIND_PER_VERTEX)

        texCoords = [(0.0, 1.0)] + topTexCoords + bottomTexCoords + [(0.0, 0.0)
                                                                     ]
        self.geometry().setTexCoordArray(0,
                                         Shape.vectorArrayFromList(texCoords))

        faceSet = Shape.primitiveSetFromList(osg.PrimitiveSet.TRIANGLE_FAN,
                                             range(0, steps + 1) + [1, 0])
        self.geometry().addPrimitiveSet(faceSet)
        for stripNum in range(0, 2 * capSteps - 1):
            vertexIndices = []
            baseIndex = 1 + stripNum * steps
            for step in range(steps) + [0]:
                vertexIndices += [baseIndex + step, baseIndex + steps + step]
            faceSet = Shape.primitiveSetFromList(osg.PrimitiveSet.QUAD_STRIP,
                                                 vertexIndices)
            self.geometry().addPrimitiveSet(faceSet)
        bottomFanBaseIndex = len(vertices) - steps - 1
        faceSet = Shape.primitiveSetFromList(
            osg.PrimitiveSet.TRIANGLE_FAN, [len(vertices) - 1] +
            range(bottomFanBaseIndex, bottomFanBaseIndex + steps) +
            [bottomFanBaseIndex, len(vertices) - 1])
        self.geometry().addPrimitiveSet(faceSet)
Exemple #10
0
 def __init__(self, holeSize = 1.0 / 3.0, startAngle = 0.0, endAngle = 2 * pi, *args, **keywordArgs):
     Shape.__init__(self, *args, **keywordArgs)
     
     # TODO: use VBO's so all instances share the same data?
     
     self.holeSize = holeSize
     self.startAngle = startAngle
     self.endAngle = endAngle
     self._bounds = ((-0.5, -0.5, -0.5), (0.5, 0.5, 0.5))
     
     steps = 32
     ringIncrement = (endAngle - startAngle) / steps
     segmentIncrement = 2 * pi / steps
     
     # Duplicate vertices are created at the seams to avoid texture problems so steps + 1 segments and steps + 1 vertices per segment are created.
     
     segmentRadius = (1.0 - holeSize) / 4.0
     ringRadius = 0.5 - segmentRadius
     
     vertices = []
     normals = []
     texCoords = []
     xs = []
     ys = []
     zs = []
     for ringStep in range(0, steps + 1):
         ringAngle = startAngle + ringStep * ringIncrement
         segmentCenter = (cos(ringAngle) * ringRadius, sin(ringAngle) * ringRadius, 0.0)
         for segmentStep in range(0, steps + 1):
             segmentAngle = segmentStep * segmentIncrement
             segmentMag = cos(segmentAngle) * segmentRadius
             x, y, z, zNormal = (cos(ringAngle) * (ringRadius + segmentMag), sin(ringAngle) * (ringRadius + segmentMag), sin(segmentAngle) * 0.5, sin(segmentAngle) * segmentRadius)
             vertices += [(x, y, z)]
             normal = (x - segmentCenter[0], y - segmentCenter[1], zNormal - segmentCenter[2])
             normalMag = sqrt(normal[0] ** 2 + normal[1] ** 2 + normal[2] ** 2)
             normals += [(normal[0] / normalMag, normal[1] / normalMag, normal[2] / normalMag)]
             texCoords += [(float(ringStep) / steps, float(segmentStep) / steps)]
             xs += [x]
             ys += [y]
             zs += [z]
     
     minX, maxX = (min(xs), max(xs))
     midX, sizeX = ((minX + maxX) / 2.0, maxX - minX)
     minY, maxY = (min(ys), max(ys))
     midY, sizeY = ((minY + maxY) / 2.0, maxY - minY)
     minZ, maxZ = (min(zs), max(zs))
     midZ = (minZ + maxZ) / 2.0
     self._bounds = ((minX, minY, minZ), (maxX, maxY, maxZ))
     scale = 1.0 / max(sizeX, sizeY) # size in Z will always be 1.0
     newVertices = []
     for vertex in vertices:
         newVertices += [((vertex[0] - midX) * scale, (vertex[1] - midY) * scale, (vertex[2] - midZ) * scale)]
     self.geometry().setVertexArray(Shape.vectorArrayFromList(newVertices))
     
     self.ringCenter = (-midX, -midY, -midZ)
     self.ringSize = 1.0 / scale
     
     self.geometry().setNormalArray(Shape.vectorArrayFromList(normals))
     self.geometry().setNormalBinding(osg.Geometry.BIND_PER_VERTEX)
     
     self.geometry().setTexCoordArray(0, Shape.vectorArrayFromList(texCoords))
     
     for ringStep in range(0, steps):
         baseIndex = ringStep * (steps + 1)
         vertexIndices = []
         for segmentStep in range(0, steps + 1):
             vertexIndices += [baseIndex + segmentStep, baseIndex + steps + 1 + segmentStep]
         faceSet = Shape.primitiveSetFromList(osg.PrimitiveSet.QUAD_STRIP, vertexIndices)
         self.geometry().addPrimitiveSet(faceSet)
Exemple #11
0
 def _tessellate(cls):
     # Code inspired by Chapter 2 of the OpenGL Red Book.
     
     if not any(Ball._vertices):
         # Start with an icosahedron
         X = .525731112119133606 * 0.5
         Z = .850650808352039932 * 0.5
         newVertices = [(-X, 0.0, Z), (X, 0.0, Z), (-X, 0.0, -Z), (X, 0.0, -Z), (0.0, Z, X), (0.0, Z, -X), (0.0, -Z, X), (0.0, -Z, -X), (Z, X, 0.0), (-Z, X, 0.0), (Z, -X, 0.0), (-Z, -X, 0.0)]
         newFaces = [(0,4,1), (0,9,4), (9,5,4), (4,5,8), (4,8,1), (8,10,1), (8,3,10), (5,3,8), (5,2,3), (2,7,3), (7,10,3), (7,6,10), (7,11,6), (11,0,6), (0,1,6), (6,1,10), (9,0,11), (9,11,2), (9,2,5), (7,2,11)]
     else:
         # Subdivide each triangular face into four triangular sub-faces by finding the midpoint of each side.
         # New vertices will be added to a copy of the existing list and a completely new set of faces will be produced.
         newVertices = list(Ball._vertices[-1])
         newFaces = []
         for face in Ball._faces[-1]:
             index0 = face[0]
             vertex0 = newVertices[index0]
             index1 = face[1]
             vertex1 = newVertices[index1]
             index2 = face[2]
             vertex2 = newVertices[index2]
             
             # Add a new vertex between vertex 0 and vertex 1.
             vertex3 = (vertex0[0] + vertex1[0], vertex0[1] + vertex1[1], vertex0[2] + vertex1[2])
             mag = sqrt(vertex3[0] ** 2 + vertex3[1] ** 2 + vertex3[2] ** 2) * 2.0
             vertex3 = (vertex3[0] / mag, vertex3[1] / mag, vertex3[2] / mag)
             try:
                 index3 = newVertices.index(vertex3)
             except:
                 newVertices += [vertex3]
                 index3 = len(newVertices) - 1
             
             # Add a new vertex between vertex 1 and vertex 2.
             vertex4 = (vertex1[0] + vertex2[0], vertex1[1] + vertex2[1], vertex1[2] + vertex2[2])
             mag = sqrt(vertex4[0] ** 2 + vertex4[1] ** 2 + vertex4[2] ** 2) * 2.0
             vertex4 = (vertex4[0] / mag, vertex4[1] / mag, vertex4[2] / mag)
             try:
                 index4 = newVertices.index(vertex4)
             except:
                 newVertices += [vertex4]
                 index4 = len(newVertices) - 1
             
             # Add a new vertex between vertex 0 and vertex 2.
             vertex5 = (vertex0[0] + vertex2[0], vertex0[1] + vertex2[1], vertex0[2] + vertex2[2])
             mag = sqrt(vertex5[0] ** 2 + vertex5[1] ** 2 + vertex5[2] ** 2) * 2.0
             vertex5 = (vertex5[0] / mag, vertex5[1] / mag, vertex5[2] / mag)
             try:
                 index5 = newVertices.index(vertex5)
             except:
                 newVertices += [vertex5]
                 index5 = len(newVertices) - 1
             
             # Add the four new faces.
             newFaces += [(index0, index3, index5), (index3, index1, index4), (index3, index4, index5), (index5, index4, index2)]
     
     Ball._vertices += [newVertices]
     Ball._vertexArray += [Shape.vectorArrayFromList(newVertices)]
     
     normals = []
     texCoords = []
     for vertex in newVertices:
         normals += [(vertex[0] * 2.0, vertex[1] * 2.0, vertex[2] * 2.0)]
         texCoords += [(vertex[0] + 0.5, vertex[2] + 0.5)] #[(atan2(vertex[2], vertex[0]) / pi / 2.0 + 0.5, atan2(vertex[2], vertex[1]) / pi / 2.0 + 0.5)]
     Ball._normalArray += [Shape.vectorArrayFromList(normals)]
     Ball._texCoordArray += [Shape.vectorArrayFromList(texCoords)]
     
     Ball._faces += [newFaces]
     faceVertices = []
     for face in newFaces:
         faceVertices += face
     Ball._faceSet += [Shape.primitiveSetFromList(osg.PrimitiveSet.TRIANGLES, faceVertices)]
Exemple #12
0
    def __init__(self, capiness=0.5, interiorIncludesCaps=False, *args, **keywordArgs):
        """ Create a new capsule shape.
        
        The 'capiness' parameter controls how much of the shape is made up of the caps.  A 1.0 value would be all caps and effectively be a sphere.  A 0.0 value would be no caps and effectively be a cylinder. 
        
        The interiorIncludesCaps parameter controls whether nested shapes should extend up into the caps or should be restrained to the cylinder portion of the capsule."""

        Shape.__init__(self, *args, **keywordArgs)

        # TODO: use VBO's so all instances share the same data?
        # TODO: fix seams caused by texture coords

        self.capiness = capiness
        self.interiorIncludesCaps = interiorIncludesCaps

        steps = 32  # must be multiple of four
        angleIncrement = 2.0 * pi / steps
        capSteps = steps / 4
        azimuthIncrement = pi / 2.0 / capSteps

        topVertices = []
        topTexCoords = []
        bottomVertices = []
        bottomTexCoords = []
        for azimuthStep in range(0, capSteps):
            topAzimuth = pi / 2.0 - (azimuthStep + 1) * azimuthIncrement
            topY, topMag = (sin(topAzimuth) * (capiness / 2.0), cos(topAzimuth) * 0.5)
            bottomAzimuth = -azimuthStep * azimuthIncrement
            bottomY, bottomMag = (sin(bottomAzimuth) * (capiness / 2.0), cos(bottomAzimuth) * 0.5)
            for step in range(0, steps):
                angle = pi + step * angleIncrement
                topVertices += [(sin(angle) * topMag, topY + (0.5 * (1.0 - capiness)), cos(angle) * topMag)]
                topTexCoords += [(float(step) / steps, topVertices[-1][1] + 0.5)]
                bottomVertices += [
                    (sin(angle) * bottomMag, -(0.5 * (1.0 - capiness)) + bottomY, cos(angle) * bottomMag)
                ]
                bottomTexCoords += [(float(step) / steps, bottomVertices[-1][1] + 0.5)]

        vertices = [(0.0, 0.5, 0.0)] + topVertices + bottomVertices + [(0.0, -0.5, 0.0)]
        self.geometry().setVertexArray(Shape.vectorArrayFromList(vertices))

        normals = []
        for vertex in vertices:
            normals += [(vertex[0] / 2.0, vertex[1] / 2.0, vertex[2] / 2.0)]
        self.geometry().setNormalArray(Shape.vectorArrayFromList(normals))
        self.geometry().setNormalBinding(osg.Geometry.BIND_PER_VERTEX)

        texCoords = [(0.0, 1.0)] + topTexCoords + bottomTexCoords + [(0.0, 0.0)]
        self.geometry().setTexCoordArray(0, Shape.vectorArrayFromList(texCoords))

        faceSet = Shape.primitiveSetFromList(osg.PrimitiveSet.TRIANGLE_FAN, range(0, steps + 1) + [1, 0])
        self.geometry().addPrimitiveSet(faceSet)
        for stripNum in range(0, 2 * capSteps - 1):
            vertexIndices = []
            baseIndex = 1 + stripNum * steps
            for step in range(steps) + [0]:
                vertexIndices += [baseIndex + step, baseIndex + steps + step]
            faceSet = Shape.primitiveSetFromList(osg.PrimitiveSet.QUAD_STRIP, vertexIndices)
            self.geometry().addPrimitiveSet(faceSet)
        bottomFanBaseIndex = len(vertices) - steps - 1
        faceSet = Shape.primitiveSetFromList(
            osg.PrimitiveSet.TRIANGLE_FAN,
            [len(vertices) - 1]
            + range(bottomFanBaseIndex, bottomFanBaseIndex + steps)
            + [bottomFanBaseIndex, len(vertices) - 1],
        )
        self.geometry().addPrimitiveSet(faceSet)
Exemple #13
0
    def __init__(self,
                 holeSize=1.0 / 3.0,
                 startAngle=0.0,
                 endAngle=2 * pi,
                 *args,
                 **keywordArgs):
        Shape.__init__(self, *args, **keywordArgs)

        # TODO: use VBO's so all instances share the same data?

        self.holeSize = holeSize
        self.startAngle = startAngle
        self.endAngle = endAngle
        self._bounds = ((-0.5, -0.5, -0.5), (0.5, 0.5, 0.5))

        steps = 32
        ringIncrement = (endAngle - startAngle) / steps
        segmentIncrement = 2 * pi / steps

        # Duplicate vertices are created at the seams to avoid texture problems so steps + 1 segments and steps + 1 vertices per segment are created.

        segmentRadius = (1.0 - holeSize) / 4.0
        ringRadius = 0.5 - segmentRadius

        vertices = []
        normals = []
        texCoords = []
        xs = []
        ys = []
        zs = []
        for ringStep in range(0, steps + 1):
            ringAngle = startAngle + ringStep * ringIncrement
            segmentCenter = (cos(ringAngle) * ringRadius,
                             sin(ringAngle) * ringRadius, 0.0)
            for segmentStep in range(0, steps + 1):
                segmentAngle = segmentStep * segmentIncrement
                segmentMag = cos(segmentAngle) * segmentRadius
                x, y, z, zNormal = (cos(ringAngle) * (ringRadius + segmentMag),
                                    sin(ringAngle) * (ringRadius + segmentMag),
                                    sin(segmentAngle) * 0.5,
                                    sin(segmentAngle) * segmentRadius)
                vertices += [(x, y, z)]
                normal = (x - segmentCenter[0], y - segmentCenter[1],
                          zNormal - segmentCenter[2])
                normalMag = sqrt(normal[0]**2 + normal[1]**2 + normal[2]**2)
                normals += [(normal[0] / normalMag, normal[1] / normalMag,
                             normal[2] / normalMag)]
                texCoords += [(float(ringStep) / steps,
                               float(segmentStep) / steps)]
                xs += [x]
                ys += [y]
                zs += [z]

        minX, maxX = (min(xs), max(xs))
        midX, sizeX = ((minX + maxX) / 2.0, maxX - minX)
        minY, maxY = (min(ys), max(ys))
        midY, sizeY = ((minY + maxY) / 2.0, maxY - minY)
        minZ, maxZ = (min(zs), max(zs))
        midZ = (minZ + maxZ) / 2.0
        self._bounds = ((minX, minY, minZ), (maxX, maxY, maxZ))
        scale = 1.0 / max(sizeX, sizeY)  # size in Z will always be 1.0
        newVertices = []
        for vertex in vertices:
            newVertices += [
                ((vertex[0] - midX) * scale, (vertex[1] - midY) * scale,
                 (vertex[2] - midZ) * scale)
            ]
        self.geometry().setVertexArray(Shape.vectorArrayFromList(newVertices))

        self.ringCenter = (-midX, -midY, -midZ)
        self.ringSize = 1.0 / scale

        self.geometry().setNormalArray(Shape.vectorArrayFromList(normals))
        self.geometry().setNormalBinding(osg.Geometry.BIND_PER_VERTEX)

        self.geometry().setTexCoordArray(0,
                                         Shape.vectorArrayFromList(texCoords))

        for ringStep in range(0, steps):
            baseIndex = ringStep * (steps + 1)
            vertexIndices = []
            for segmentStep in range(0, steps + 1):
                vertexIndices += [
                    baseIndex + segmentStep,
                    baseIndex + steps + 1 + segmentStep
                ]
            faceSet = Shape.primitiveSetFromList(osg.PrimitiveSet.QUAD_STRIP,
                                                 vertexIndices)
            self.geometry().addPrimitiveSet(faceSet)