Example #1
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))
Example #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)
Example #3
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))
Example #4
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))
Example #5
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))
Example #6
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)
Example #7
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)
Example #8
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)
Example #9
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)