Example #1
0
def create_side(x_z_top_left, x_z_bottom_right, static=True):
    x1, z1 = x_z_top_left
    x2, z2 = x_z_bottom_right
    format = GeomVertexFormat.getV3n3c4t2()
    vdata = GeomVertexData('', format, Geom.UHStatic)
    vertex = GeomVertexWriter(vdata, 'vertex')
    normal = GeomVertexWriter(vdata, 'normal')
    vertex.addData3f(x1, 0, z1) # top left
    vertex.addData3f(x2, 0, z1) # top right
    vertex.addData3f(x2, 0, z2) # bottom right
    vertex.addData3f(x1, 0, z2) # bottom left
    for _i in range(4):
        normal.addData3f(0, - 1, 0)
    if static:
        prim_hint = Geom.UHStatic
    else:
        prim_hint = Geom.UHDynamic
    prim = GeomTristrips(prim_hint)
    prim.addVertices(1, 0, 2, 3)
    prim.closePrimitive()
    geom = Geom(vdata)
    geom.addPrimitive(prim)
    node = GeomNode('')
    node.addGeom(geom)
    return (node, vdata)
Example #2
0
def create_triangle(x_z_left, x_z_top, x_z_right, static=True):
    x1,z1 = x_z_left
    x2,z2 = x_z_top
    x3,z3 = x_z_right
    format = GeomVertexFormat.getV3n3c4t2()
    vdata=GeomVertexData('', format, Geom.UHStatic)
    vertex=GeomVertexWriter(vdata, 'vertex')
    normal=GeomVertexWriter(vdata, 'normal')
    vertex.addData3f(x1, 0, z1) # left
    vertex.addData3f(x2, 0, z2) # top
    vertex.addData3f(x3, 0, z3) # right
    for _i in range(3):
        normal.addData3f(0,-1,0)
    if static:
        prim_hint = Geom.UHStatic
    else:
        prim_hint = Geom.UHDynamic
    prim = GeomTriangles(prim_hint)
    prim.addVertices(0,2,1)
    prim.closePrimitive()
    geom = Geom(vdata)
    geom.addPrimitive(prim)
    node = GeomNode('')
    node.addGeom(geom)
    return node
Example #3
0
    def __init__(self):
        # GeomNode to hold our individual geoms
        self.gnode = GeomNode('wirePrim')

        # How many times to subdivide our spheres/cylinders resulting vertices.  Keep low
        # because this is supposed to be an approximate representation
        self.subdiv = 12
Example #4
0
    def __init__(self, width=1, depth=1, height=1, origin=Point3(0, 0, 0)):

        # Create vetex data format
        gvf = GeomVertexFormat.getV3n3()
        gvd = GeomVertexData("vertexData", gvf, Geom.UHStatic)

        # Create vetex writers for each type of data we are going to store
        gvwV = GeomVertexWriter(gvd, "vertex")
        gvwN = GeomVertexWriter(gvd, "normal")

        # Write out all points
        for p in GetPointsForBox(width, depth, height):
            gvwV.addData3f(Point3(p) - origin)

        # Write out all the normals
        for n in ((-1, 0, 0), (1, 0, 0), (0, -1, 0), (0, 1, 0), (0, 0, -1), (0, 0, 1)):
            for i in range(4):
                gvwN.addData3f(n)

        geom = Geom(gvd)
        for i in range(0, gvwV.getWriteRow(), 4):

            # Create and add both triangles
            geom.addPrimitive(GetGeomTriangle(i, i + 1, i + 2))
            geom.addPrimitive(GetGeomTriangle(i, i + 2, i + 3))

        # Init the node path, wrapping the box
        geomNode = GeomNode("box")
        geomNode.addGeom(geom)
        NodePath.__init__(self, geomNode)
Example #5
0
	def init_node_path(self):
		if self.node_path:
			self.node_path.remove()
		vdata = GeomVertexData('name_me', self.format, Geom.UHStatic)
		vertex = GeomVertexWriter(vdata, 'vertex')
		color = GeomVertexWriter(vdata, 'color')
		primitive = GeomTristrips(Geom.UHStatic)
		film_size = base.cam.node().getLens().getFilmSize()
		x = film_size.getX() / 2.0
		z = x * 0.75
		vertex.addData3f(-x, 10000, z)
		vertex.addData3f(x, 10000, z)
		vertex.addData3f(-x, 10000, -z)
		vertex.addData3f(x, 10000, -z)
		color.addData4f(*[x / 255.0 for x in self.color1] + [1.0])
		color.addData4f(*[x / 255.0 for x in self.color1] + [1.0])
		color.addData4f(*[x / 255.0 for x in self.color2] + [1.0])
		color.addData4f(*[x / 255.0 for x in self.color2] + [1.0])
		primitive.addNextVertices(4)
		primitive.closePrimitive()
		geom = Geom(vdata)
		geom.addPrimitive(primitive)
		node = GeomNode('gnode')
		node.addGeom(geom)
		self.node_path = base.camera.attachNewNode(node)
def create_side(x_z_top_left, x_z_bottom_right, static=True):
    x1, z1 = x_z_top_left
    x2, z2 = x_z_bottom_right
    format = GeomVertexFormat.getV3n3c4t2()
    vdata = GeomVertexData('', format, Geom.UHStatic)
    vertex = GeomVertexWriter(vdata, 'vertex')
    normal = GeomVertexWriter(vdata, 'normal')
    vertex.addData3f(x1, 0, z1) # top left
    vertex.addData3f(x2, 0, z1) # top right
    vertex.addData3f(x2, 0, z2) # bottom right
    vertex.addData3f(x1, 0, z2) # bottom left
    for _i in range(4):
        normal.addData3f(0, - 1, 0)
    if static:
        prim_hint = Geom.UHStatic
    else:
        prim_hint = Geom.UHDynamic
    prim = GeomTristrips(prim_hint)
    prim.addVertices(1, 0, 2, 3)
    prim.closePrimitive()
    geom = Geom(vdata)
    geom.addPrimitive(prim)
    node = GeomNode('')
    node.addGeom(geom)
    return (node, vdata)
Example #7
0
	def init_node_path_line(self, light_number):
		if self.node_path_line:
			self.node_path_line.remove()
		vdata = GeomVertexData('name_me', self.format, Geom.UHStatic)
		vertex = GeomVertexWriter(vdata, 'vertex')
		color = GeomVertexWriter(vdata, 'color')
		primitive = GeomLines(Geom.UHStatic)
		vertex.addData3f(*coords_to_panda(0, 0, 0))
		vertex.addData3f(*coords_to_panda(*self.direction.coords))
		if light_number == 0:
			line_color = (0.0, 1.0, 1.0, 1.0)
		elif light_number == 1:
			line_color = (1.0, 0.0, 1.0, 1.0)
		elif light_number == 2:
			line_color = (1.0, 1.0, 0.0, 1.0)
		color.addData4f(*line_color)
		color.addData4f(*line_color)
		primitive.addNextVertices(2)
		primitive.closePrimitive()
		geom = Geom(vdata)
		geom.addPrimitive(primitive)
		node = GeomNode('gnode')
		node.addGeom(geom)
		self.node_path_line = self.parent.node_path_ui.attachNewNode(node)
		self.node_path_line.setScale(1000)
		self.node_path_line.setPos(100, 100, 0)
		self.show_line(self.parent.parent.lights_edit_window.IsShown())
def create_triangle(x_z_left, x_z_top, x_z_right, static=True):
    x1,z1 = x_z_left
    x2,z2 = x_z_top
    x3,z3 = x_z_right
    format = GeomVertexFormat.getV3n3c4t2()
    vdata=GeomVertexData('', format, Geom.UHStatic)
    vertex=GeomVertexWriter(vdata, 'vertex')
    normal=GeomVertexWriter(vdata, 'normal')
    vertex.addData3f(x1, 0, z1) # left
    vertex.addData3f(x2, 0, z2) # top
    vertex.addData3f(x3, 0, z3) # right
    for _i in range(3):
        normal.addData3f(0,-1,0)
    if static:
        prim_hint = Geom.UHStatic
    else:
        prim_hint = Geom.UHDynamic
    prim = GeomTriangles(prim_hint)
    prim.addVertices(0,2,1)
    prim.closePrimitive()
    geom = Geom(vdata)
    geom.addPrimitive(prim)
    node = GeomNode('')
    node.addGeom(geom)
    return node
Example #9
0
	def init_node_path(self):
		if self.node_path:
			self.node_path.remove()
		vdata = GeomVertexData('name_me', self.format, Geom.UHStatic)
		vertex = GeomVertexWriter(vdata, 'vertex')
		color = GeomVertexWriter(vdata, 'color')
		primitive = GeomLines(Geom.UHStatic)
		vertex.addData3f(*coords_to_panda(0, 0, 0))
		vertex.addData3f(*coords_to_panda(1000, 0, 0))
		vertex.addData3f(*coords_to_panda(0, 0, 0))
		vertex.addData3f(*coords_to_panda(0, -1000, 0))
		vertex.addData3f(*coords_to_panda(0, 0, 0))
		vertex.addData3f(*coords_to_panda(0, 0, 1000))
		color.addData4f(1.0, 0.0, 0.0, 1.0)
		color.addData4f(1.0, 0.0, 0.0, 1.0)
		color.addData4f(0.0, 1.0, 0.0, 1.0)
		color.addData4f(0.0, 1.0, 0.0, 1.0)
		color.addData4f(0.0, 0.0, 1.0, 1.0)
		color.addData4f(0.0, 0.0, 1.0, 1.0)
		primitive.addNextVertices(6)
		primitive.closePrimitive()
		geom = Geom(vdata)
		geom.addPrimitive(primitive)
		node = GeomNode('gnode')
		node.addGeom(geom)
		self.node_path = self.parent.node_path_ui.attachNewNode(node)
Example #10
0
    def generate(self):
        format = GeomVertexFormat.getV3()
        data = GeomVertexData("Data", format, Geom.UHStatic)
        vertices = GeomVertexWriter(data, "vertex")

        vertices.addData3f(-self.w, -self.h, -self.d)
        vertices.addData3f(+self.w, -self.h, -self.d)
        vertices.addData3f(-self.w, +self.h, -self.d)
        vertices.addData3f(+self.w, +self.h, -self.d)
        vertices.addData3f(-self.w, -self.h, +self.d)
        vertices.addData3f(+self.w, -self.h, +self.d)
        vertices.addData3f(-self.w, +self.h, +self.d)
        vertices.addData3f(+self.w, +self.h, +self.d)

        triangles = GeomTriangles(Geom.UHStatic)

        def addQuad(v0, v1, v2, v3):
            triangles.addVertices(v0, v1, v2)
            triangles.addVertices(v0, v2, v3)
            triangles.closePrimitive()

        addQuad(4, 5, 7, 6)  # Z+
        addQuad(0, 2, 3, 1)  # Z-
        addQuad(3, 7, 5, 1)  # X+
        addQuad(4, 6, 2, 0)  # X-
        addQuad(2, 6, 7, 3)  # Y+
        addQuad(0, 1, 5, 4)  # Y+

        geom = Geom(data)
        geom.addPrimitive(triangles)

        node = GeomNode("BoxMaker")
        node.addGeom(geom)

        return NodePath(node)
Example #11
0
 def draw(self):
     format=GeomVertexFormat.getV3n3cpt2()
     vdata=GeomVertexData('square', format, Geom.UHDynamic)
     vertex=GeomVertexWriter(vdata, 'vertex')
     normal=GeomVertexWriter(vdata, 'normal')
     color=GeomVertexWriter(vdata, 'color')
     circle=Geom(vdata)
     # Create vertices
     vertex.addData3f(self.pos)
     color.addData4f(self.color)
     for v in range(self._EDGES):
         x = self.pos.getX() + (self.size * math.cos((2*math.pi/self._EDGES)*v))
         y = self.pos.getY() + (self.size * math.sin((2*math.pi/self._EDGES)*v))
         z = self.pos.getZ()
         vertex.addData3f(x, y, z)
         color.addData4f(self.color)
     
     # Create triangles
     for t in range(self._EDGES):
         tri = GeomTriangles(Geom.UHDynamic)
         tri.addVertex(0)
         tri.addVertex(t+1)
         if (t+2) > self._EDGES:
             tri.addVertex(1)
         else:
             tri.addVertex(t+2)
         tri.closePrimitive()
         circle.addPrimitive(tri)
     
     gn = GeomNode('Circle')
     gn.addGeom(circle)
     np = NodePath(gn)
     np.setHpr(0, 90, 0)
     return np
def create_hexagon(radius):
    """ Creates a hexagon shape that is centered at (0,0,0) with the corners having a distance of radius to the center and
    the normals pointing in direction (0,-1,0). 
    Returns the tuple (PandaNode, GeomVertexData). """
    format = GeomVertexFormat.getV3n3c4t2()
    vdata=GeomVertexData('hexagon', format, Geom.UHStatic)
    vertex=GeomVertexWriter(vdata, 'vertex')
    normal=GeomVertexWriter(vdata, 'normal')
    # create the vertices
    vertex.addData3f(0,0,0)
    normal.addData3f(0,-1,0)
    # add the other vertices
    for phi in range(0,360,60):
        # right-hand-rule (with middle finger pointing upwards): the y-axis points towards the screen,
        # therefore the hexagon will be created in the x,z plane, with x-axis pointing to the right
        # and the z-axis pointing up
        # get the next vertex coordinates by rotating the point (0,0,radius) in the x,z plane
        x,z = rotate_phi_degrees_counter_clockwise(phi, (0,radius))
        #print (x,z)
        vertex.addData3f(x,0,z) 
        normal.addData3f(0,-1,0) # the normal vector points away from the screen
    # add the vertices to a geometry primitives
    prim = GeomTrifans(Geom.UHStatic)
    for i in range(7):
        prim.addVertex(i)
    prim.addVertex(1)
    prim.closePrimitive()
    geom = Geom(vdata)
    geom.addPrimitive(prim)
    hex_node = GeomNode('')
    hex_node.addGeom(geom)
    return hex_node, vdata
Example #13
0
def create_hexagon(radius):
    """ Creates a hexagon shape that is centered at (0,0,0) with the corners having a distance of radius to the center and
    the normals pointing in direction (0,-1,0). 
    Returns the tuple (PandaNode, GeomVertexData). """
    format = GeomVertexFormat.getV3n3c4t2()
    vdata=GeomVertexData('hexagon', format, Geom.UHStatic)
    vertex=GeomVertexWriter(vdata, 'vertex')
    normal=GeomVertexWriter(vdata, 'normal')
    # create the vertices
    vertex.addData3f(0,0,0)
    normal.addData3f(0,-1,0)
    # add the other vertices
    for phi in range(0,360,60):
        # right-hand-rule (with middle finger pointing upwards): the y-axis points towards the screen,
        # therefore the hexagon will be created in the x,z plane, with x-axis pointing to the right
        # and the z-axis pointing up
        # get the next vertex coordinates by rotating the point (0,0,radius) in the x,z plane
        x,z = rotate_phi_degrees_counter_clockwise(phi, (0,radius))
        #print (x,z)
        vertex.addData3f(x,0,z) 
        normal.addData3f(0,-1,0) # the normal vector points away from the screen
    # add the vertices to a geometry primitives
    prim = GeomTrifans(Geom.UHStatic)
    for i in range(7):
        prim.addVertex(i)
    prim.addVertex(1)
    prim.closePrimitive()
    geom = Geom(vdata)
    geom.addPrimitive(prim)
    hex_node = GeomNode('')
    hex_node.addGeom(geom)
    return hex_node, vdata
Example #14
0
    def createPitchLineOld(self,points=[0.5,0.25,-0.25,-0.5],
                            tick=0.00,colour=None):
        """ create a line to hint at the pitch of the aircraft on the hud """
        if colour is None:
            colour = self.colour

        l = LineNodePath(aspect2d,'pitchline',4,Vec4(colour[0],colour[1],
                                                       colour[2],colour[3]))

        plist = []
        for p in points:
            plist.append((p,0.0,0.0))
        plist.insert(0,(points[0],0.0,tick))
        plist.append((points[3],0.0,tick))

        linelist = []
        linelist = [[plist[p],plist[p+1]] for p in range(len(plist)-1)]
        linelist.pop(2)
        l.drawLines(linelist)
        l.create()

        # These lines are drawn from scratch rather than using a graphic file

        format = GeomVertexFormat.getV3()
        vdata = GeomVertexData("vertices",format,Geom.UHStatic)

        # create vertices to add to use in creating lines
        vertexWriter=GeomVertexWriter(vdata,"vertex")
        # here we define enough positions to create two separated lines
        for p in points:
            vertexWriter.addData3f(p,0.0,0.0)
        # and another two positions for the 'ticks' at the line ends
        vertexWriter.addData3f(points[0],0.0,tick)
        vertexWriter.addData3f(points[3],0.0,tick)

        # create the primitives
        line = GeomLines(Geom.UHStatic)
        line.addVertices(4,0) # the tick part
        line.addVertices(0,1) # part of the horizontal line
        line.closePrimitive()
        line2 = GeomLines(Geom.UHStatic)
        line2.addVertices(2,3) # other part of the horizontal line
        line2.addVertices(3,5) # second tick
        line2.closePrimitive()

        # add the lines to a geom object
        lineGeom = Geom(vdata)
        lineGeom.addPrimitive(line)
        lineGeom.addPrimitive(line2)

        # create the node..
        lineGN=GeomNode("splitline")
        lineGN.addGeom(lineGeom)

        # and parent the node to aspect2d
        lineNP = aspect2d.attachNewNode(lineGN)
        return lineNP
Example #15
0
    def __init__(self, name):
        GeomNode.__init__(self, name)

        ls = LineSegs()
        ls.setThickness(5)
        ls.drawTo(Point3(0, 0, 0))
        ls.drawTo(Point3(100, 100, 100))
        self.addGeomsFrom(ls.create())

        print ls
Example #16
0
	def init_node_path(self):
		if self.node_path:
			self.node_path.remove()
		polygon = self.source
		vdata = GeomVertexData('name_me', self.format, Geom.UHStatic)
		vertex = GeomVertexWriter(vdata, 'vertex')
		normal = GeomVertexWriter(vdata, 'normal')
		color = GeomVertexWriter(vdata, 'color')
		texcoord = GeomVertexWriter(vdata, 'texcoord')
		primitive = GeomTristrips(Geom.UHStatic)
		vertex.addData3f(*coords_to_panda(*polygon.A.point.coords))
		vertex.addData3f(*coords_to_panda(*polygon.B.point.coords))
		vertex.addData3f(*coords_to_panda(*polygon.C.point.coords))
		if hasattr(polygon, 'D'):
			vertex.addData3f(*coords_to_panda(*polygon.D.point.coords))
		else:
			vertex.addData3f(*coords_to_panda(*polygon.C.point.coords))
		if polygon.A.normal:
			normal.addData3f(*coords_to_panda(*polygon.A.normal.coords))
			normal.addData3f(*coords_to_panda(*polygon.B.normal.coords))
			normal.addData3f(*coords_to_panda(*polygon.C.normal.coords))
			if hasattr(polygon, 'D'):
				normal.addData3f(*coords_to_panda(*polygon.D.normal.coords))
		if polygon.A.normal:
			gray = 1.0
		else:
			gray = 0.0
		self.old_color = (gray, gray, gray, 1.0)
		color.addData4f(gray, gray, gray, 1.0)
		color.addData4f(gray, gray, gray, 1.0)
		color.addData4f(gray, gray, gray, 1.0)
		if hasattr(polygon, 'D'):
			color.addData4f(gray, gray, gray, 1.0)
		if polygon.A.texcoord:
			pal = ((polygon.texture_palette + 1) * 256)
			
			texcoord_A = uv_to_panda2(polygon, pal, *polygon.A.texcoord.coords)
			texcoord_B = uv_to_panda2(polygon, pal, *polygon.B.texcoord.coords)
			texcoord_C = uv_to_panda2(polygon, pal, *polygon.C.texcoord.coords)
			texcoord.addData2f(*texcoord_A)
			texcoord.addData2f(*texcoord_B)
			texcoord.addData2f(*texcoord_C)
			if hasattr(polygon, 'D'):
				texcoord_D = uv_to_panda2(polygon, pal, *polygon.D.texcoord.coords)
				texcoord.addData2f(*texcoord_D)
		primitive.addNextVertices(4)
		primitive.closePrimitive()
		geom = Geom(vdata)
		geom.addPrimitive(primitive)
		node = GeomNode('gnode')
		node.addGeom(geom)
		self.node_path = self.parent.node_path_mesh.attachNewNode(node)
Example #17
0
    def __init__(self, name, halfedge_mesh, color, wireframe=False):
        GeomNode.__init__(self, name)
        self._halfedge_mesh = halfedge_mesh
        self._color = color
        self._wireframe = wireframe

        self._create_vertex_data()
        self._create_geoms()

        # set visualisation parameters
        if self._wireframe:
            self.setAttrib(RenderModeAttrib.make(RenderModeAttrib.MWireframe, 2, 1))
        self.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullNone))
Example #18
0
    def __init__(self, name, points, color=(1.0,1.0,1.0,1.0)):
        GeomNode.__init__(self, name)
        self._points = points
        self._color = color

        self._create_vertex_data()
        self._create_geom_primitives()
        self._create_geoms()

        # set visualisation parameters
        #if self._wireframe:
        #    self.setAttrib(RenderModeAttrib.make(RenderModeAttrib.MWireframe, 2, 1))
        #self.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullNone))
        self.setAttrib(RenderModeAttrib.make(RenderModeAttrib.MWireframe, 2, 0))
Example #19
0
    def __init__(self, radius=1.0, height=1.0, numSegs=16, degrees=360, axis=Vec3(0, 0, 1), origin=Point3(0, 0, 0)):

        # Create vetex data format
        gvf = GeomVertexFormat.getV3n3()
        gvd = GeomVertexData("vertexData", gvf, Geom.UHStatic)

        # Create vetex writers for each type of data we are going to store
        gvwV = GeomVertexWriter(gvd, "vertex")
        gvwN = GeomVertexWriter(gvd, "normal")

        # Get the points for an arc
        points = GetPointsForArc(degrees, numSegs, True)
        for i in range(len(points) - 1):

            # Rotate the points around the desired axis
            p1 = Point3(points[i][0], points[i][1], 0) * radius
            p1 = RotatePoint3(p1, Vec3(0, 0, 1), axis) - origin
            p2 = Point3(points[i + 1][0], points[i + 1][1], 0) * radius
            p2 = RotatePoint3(p2, Vec3(0, 0, 1), axis) - origin

            cross = (p2 - axis).cross(p1 - axis)
            cross.normalize()

            gvwV.addData3f(p1)
            gvwV.addData3f(axis * height - origin)
            gvwV.addData3f(p2)
            gvwN.addData3f(cross)
            gvwN.addData3f(cross)
            gvwN.addData3f(cross)

            # Base
            gvwV.addData3f(p2)
            gvwV.addData3f(Point3(0, 0, 0) - origin)
            gvwV.addData3f(p1)
            gvwN.addData3f(-axis)
            gvwN.addData3f(-axis)
            gvwN.addData3f(-axis)

        geom = Geom(gvd)
        for i in range(0, gvwV.getWriteRow(), 3):

            # Create and add triangle
            geom.addPrimitive(GetGeomTriangle(i, i + 1, i + 2))

        # Init the node path, wrapping the box
        geomNode = GeomNode("cone")
        geomNode.addGeom(geom)
        NodePath.__init__(self, geomNode)
Example #20
0
 def __init__(self, render, camera):
     #Since we are using collision detection to do picking, we set it up like any other collision detection system with a traverser and a handler 
     self.picker = CollisionTraverser()            #Make a traverser 
     self.pq     = CollisionHandlerQueue()         #Make a handler 
     #Make a collision node for our picker ray 
     self.pickerNode = CollisionNode('mouseRay') 
     #Attach that node to the camera since the ray will need to be positioned relative to it 
     self.pickerNP = camera.attachNewNode(self.pickerNode) 
     #Everything to be picked will use bit 1. This way if we were doing other collision we could seperate it 
     self.pickerNode.setFromCollideMask(BitMask32.bit(1)) 
     self.pickerRay = CollisionRay()               #Make our ray 
     self.pickerNode.addSolid(self.pickerRay)      #Add it to the collision node 
     #Register the ray as something that can cause collisions 
     self.picker.addCollider(self.pickerNP, self.pq) 
     #self.picker.showCollisions(render) 
     
     self.pst = CollisionTraverser()            #Make a traverser 
     self.hqp     = CollisionHandlerQueue()         #Make a handler 
     #Make a collision node for our picker ray 
     
     self.pstNode = CollisionNode('mouseRaytoObj') 
     #Attach that node to the camera since the ray will need to be positioned relative to it 
     self.pstNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
     self.pstNode2 = camera.attachNewNode(self.pstNode) 
     self.pickerRayObj = CollisionRay()   
     #Everything to be picked will use bit 1. This way if we were doing other collision we could seperate it 
     #self.pstNode.setFromCollideMask(BitMask32.bit(1)) 
     self.pstNode.addSolid(self.pickerRayObj)      #Add it to the collision node 
     #Register the ray as something that can cause collisions 
     self.pst.addCollider(self.pstNode2, self.hqp) 
     #self.pst.showCollisions(render) 
Example #21
0
	def __init__ (self):
		# GeomNode to hold our individual geoms 
		self.gnode = GeomNode ('wirePrim') 
		
		# How many times to subdivide our spheres/cylinders resulting vertices.	Keep low 
		# because this is supposed to be an approximate representation 
		self.subdiv = 12 
Example #22
0
 def __init__(self,gmap,gaming_zone):
    DirectObject.__init__(self)
    #gaming zone (used for mouse movement), as a tools.Rectangle
    self.gaming_zone=gaming_zone
    #actual camera node
    self.p3dcam=base.camera
    #what the cam is oriented to
    self._target=base.render.attachNewNode('GaminCam.target')
    #range=[0,1] between min and max closeness to ground
    self.level=.7
    #
    #keys_down acts as a pool containing keys (+mouse buttons) currently down
    self.keys_down=[]
    update_list.append(self.update)
    #setup for mouse picking
    picker_node=CollisionNode('gcam_to_mouse_ray')#general collision node
    picker_node.setFromCollideMask(GeomNode.getDefaultCollideMask())
    self.picker_ray=CollisionRay()#solid ray to attach to coll node
    picker_node.addSolid(self.picker_ray)
    self.picker_np=self.p3dcam.attachNewNode(picker_node)#attach this node to gcam
    self.collision_queue=CollisionHandlerQueue()#stores collisions
    self.collision_traverser=CollisionTraverser('gcam_traverser')#actual computer
    self.collision_traverser.addCollider(self.picker_np,self.collision_queue)
    base.cTrav=self.collision_traverser
    self.gmap=gmap
    #stack of states (state=pos+zoom)
    self.states_stack=[]
    #enable the cam to move according to keyboard and mouse
    self.move_enabled=True
Example #23
0
    def createBorderRightCollisionMesh(self):
        '''
        '''
        # Creating the Vertex
        self.createVertices(self.track_points, self.street_data.border_r_coll)
        # Connect the Vertex
        self.connectVertices(self.street_data.border_r_coll)

        geom = Geom(self.vdata)
        geom.addPrimitive(self.prim)

        node = GeomNode('border_r_coll')
        node.addGeom(geom)

        # nodePath = self.render.attachNewNode(node)
        return node
Example #24
0
    def createUninterpolatedRoadMesh(self):
        '''
        '''
        # Creating the Vertex
        self.createVertices(self.track.getPoints(), self.street_data)
        # Connect the Vertex
        self.connectVertices(self.street_data)

        geom = Geom(self.vdata)
        geom.addPrimitive(self.prim)

        node = GeomNode('street')
        node.addGeom(geom)

        # nodePath = self.render.attachNewNode(node)
        return node
Example #25
0
    def __init__(self, name, surface, color, wireframe=False):
        GeomNode.__init__(self, name)
        self._surface = surface
        self._color = color
        self._wireframe = wireframe

        self._init_tables()
        self._create_vertex_data()
        self._create_geoms()

        # set visualisation parameters
        if self._wireframe:
            self.setAttrib(RenderModeAttrib.make(RenderModeAttrib.MWireframe, 2, 1))
        else:
            self.setAttrib(RenderModeAttrib.make(RenderModeAttrib.MFilledFlat, 2, 1))
        self.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullNone))
Example #26
0
	def init_node_path(self):
		if self.node_path:
			self.node_path.remove()
		vdata = GeomVertexData('name_me', self.format, Geom.UHStatic)
		vertex = GeomVertexWriter(vdata, 'vertex')
		color = GeomVertexWriter(vdata, 'color')
		primitive = GeomTristrips(Geom.UHStatic)
		y = self.height * 12 + self.depth * 12 + 1
		try:
			(slope, rotation) = slope_types[self.slope_type]
		except KeyError:
			print 'Unknown slope type:', self.slope_type
			(slope, rotation) = (flat, 0)
		if self.slope_height == 0:
			(slope, rotation) = (flat, 0)
		scale_y = self.slope_height * 12
		vertex.addData3f(*coords_to_panda(-14.0, -slope['sw'] * scale_y, -14.0))
		vertex.addData3f(*coords_to_panda(-14.0, -slope['nw'] * scale_y, 14.0))
		vertex.addData3f(*coords_to_panda(14.0, -slope['ne'] * scale_y, 14.0))
		vertex.addData3f(*coords_to_panda(14.0, -slope['se'] * scale_y, -14.0))
		vertex.addData3f(*coords_to_panda(-14.0, -slope['sw'] * scale_y, -14.0))
		tile_color = (0.5, 0.5, 1.0)
		if self.cant_walk:
			tile_color = (1.0, 0.5, 0.5)
		if self.cant_cursor:
			tile_color = (0.5, 0.0, 0.0)
		if (self.x + self.z) % 2 == 0:
			tile_color = tuple([x * 0.8 for x in tile_color])
		self.tile_color = tile_color
		color.addData4f(*tile_color + (1.0,))
		color.addData4f(*tile_color + (1.0,))
		color.addData4f(*tile_color + (1.0,))
		color.addData4f(*tile_color + (1.0,))
		color.addData4f(*tile_color + (1.0,))
		primitive.addNextVertices(5)
		primitive.closePrimitive()
		geom = Geom(vdata)
		geom.addPrimitive(primitive)
		node = GeomNode('gnode')
		node.addGeom(geom)
		self.node_path = self.parent.node_path.attachNewNode(node)
		self.node_path.setH(rotation)
		can_stand_height = 0
		if not self.cant_cursor:
			can_stand_height = 1
		self.node_path.setPos(*coords_to_panda(self.x * 28 + 14, -((self.height + self.depth) * 12 + 1 + can_stand_height), self.z * 28 + 14))
		self.node_path.setTag('terrain_xyz', '%u,%u,%u' % (self.x, self.y, self.z))
Example #27
0
    def createCentreMarkOld(self,colour=None):
        """ create a line to hint at the pitch of the aircraft on the hud """
        if colour is None:
            colour = self.colour

        # These lines are drawn from scratch rather than using a graphic file

        format = GeomVertexFormat.getV3()
        vdata = GeomVertexData("vertices",format,Geom.UHStatic)

        # create vertices to add to use in creating lines
        vertexWriter=GeomVertexWriter(vdata,"vertex")
        # essentially I am trying to create a line that gives an idea of
        #       where the forward vector of the plane is pointing which
        #       helps indicate the pitch
        # the bends in the line could be used to indicate a few angles but
        #       I am not sure how useful this really is.
        vertexWriter.addData3f(0.15,0.0,0.0)
        vertexWriter.addData3f(0.10,0.0,0.0)
        vertexWriter.addData3f(0.05,0.0,-0.025)
        vertexWriter.addData3f(0.00,0.0,0.025)
        vertexWriter.addData3f(-0.05,0.0,-0.025)
        vertexWriter.addData3f(-0.10,0.0,0.0)
        vertexWriter.addData3f(-0.15,0.0,0.0)

        # create the primitives
        line = GeomLines(Geom.UHStatic)
        line.addVertices(0,1)
        line.addVertices(1,2)
        line.addVertices(2,3)
        line.addVertices(3,4)
        line.addVertices(4,5)
        line.addVertices(5,6)
        line.closePrimitive()

        # add the lines to a geom object
        lineGeom = Geom(vdata)
        lineGeom.addPrimitive(line)

        # create the node..
        lineGN=GeomNode("centremark")
        lineGN.addGeom(lineGeom)

        # and parent the node to aspect2d
        lineNP = aspect2d.attachNewNode(lineGN)
        return lineNP
Example #28
0
def create_line(x1, z1, x2, z2):
    format = GeomVertexFormat.getV3n3c4t2()
    vdata = GeomVertexData('', format, Geom.UHStatic)
    vertex = GeomVertexWriter(vdata, 'vertex')
    normal = GeomVertexWriter(vdata, 'normal')
    vertex.addData3f(x1, 0, z1)
    vertex.addData3f(x2, 0, z2) 
    for _i in range(2):
        normal.addData3f(0, - 1, 0)
    prim_hint = Geom.UHStatic
    prim = GeomLines(prim_hint)
    prim.addVertices(0, 1)
    prim.closePrimitive()
    geom = Geom(vdata)
    geom.addPrimitive(prim)
    node = GeomNode('')
    node.addGeom(geom)
    return (node, vdata)
Example #29
0
	def init_node_path(self):
		if self.node_path:
			self.node_path.remove()
		node = GeomNode('gnode')
		self.node_path = self.parent.node_path_terrain.attachNewNode(node)
		for level in self.tiles:
			for row in level:
				for tile in row:
					tile.init_node_path()
def create_line(x1, z1, x2, z2):
    format = GeomVertexFormat.getV3n3c4t2()
    vdata = GeomVertexData('', format, Geom.UHStatic)
    vertex = GeomVertexWriter(vdata, 'vertex')
    normal = GeomVertexWriter(vdata, 'normal')
    vertex.addData3f(x1, 0, z1)
    vertex.addData3f(x2, 0, z2) 
    for _i in range(2):
        normal.addData3f(0, - 1, 0)
    prim_hint = Geom.UHStatic
    prim = GeomLines(prim_hint)
    prim.addVertices(0, 1)
    prim.closePrimitive()
    geom = Geom(vdata)
    geom.addPrimitive(prim)
    node = GeomNode('')
    node.addGeom(geom)
    return (node, vdata)
Example #31
0
	def init_node_path(self):
		if self.node_path:
			self.node_path.remove()
		vdata = GeomVertexData('name_me', self.format, Geom.UHStatic)
		vertex = GeomVertexWriter(vdata, 'vertex')
		color = GeomVertexWriter(vdata, 'color')
		primitive = GeomTristrips(Geom.UHStatic)
		vertex.addData3f(-2.0, -2.0, -2.0)
		vertex.addData3f(2.0, -2.0, -2.0)
		vertex.addData3f(0, 2.0, -2.0)
		vertex.addData3f(0, 0, 2.0)
		vertex.addData3f(-2.0, -2.0, -2.0)
		vertex.addData3f(0, 0, 2.0)
		vertex.addData3f(2.0, -2.0, -2.0)
		vertex.addData3f(0, 0, 2.0)
		vertex.addData3f(0, 2.0, -2.0)
		color_tuple = (1.0, 1.0, 1.0)
		if self.point == 'A':
			color_tuple = (1.0, 0.0, 0.0)
		elif self.point == 'B':
			color_tuple = (0.0, 1.0, 0.0)
		elif self.point == 'C':
			color_tuple = (0.0, 0.0, 1.0)
		elif self.point == 'D':
			color_tuple = (1.0, 1.0, 0.0)
		color.addData4f(*color_tuple + (1.0,))
		color.addData4f(*color_tuple + (1.0,))
		color.addData4f(*color_tuple + (1.0,))
		color.addData4f(*color_tuple + (1.0,))
		color.addData4f(*color_tuple + (1.0,))
		color.addData4f(*color_tuple + (1.0,))
		color.addData4f(*color_tuple + (1.0,))
		color.addData4f(*color_tuple + (1.0,))
		color.addData4f(*color_tuple + (1.0,))
		primitive.addNextVertices(9)
		primitive.closePrimitive()
		geom = Geom(vdata)
		geom.addPrimitive(primitive)
		node = GeomNode('gnode')
		node.addGeom(geom)
		self.node_path = self.parent.parent.node_path_ui.attachNewNode(node)
		self.node_path.setP(180)
		self.node_path.setPos(*coords_to_panda(*self.coords))
Example #32
0
 def init_collide(self):
     from pandac.PandaModules import CollisionTraverser, CollisionNode
     from pandac.PandaModules import CollisionHandlerQueue, CollisionRay
     self.cTrav = CollisionTraverser('MousePointer')
     self.cQueue = CollisionHandlerQueue()
     self.cNode = CollisionNode('MousePointer')
     self.cNodePath = base.camera.attachNewNode(self.cNode)
     self.cNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
     self.cRay = CollisionRay()
     self.cNode.addSolid(self.cRay)
     self.cTrav.addCollider(self.cNodePath, self.cQueue)
Example #33
0
    def __init__(self, name, width, height, points, normals=[], color=(1.0,1.0,1.0,1.0), wireframe=False):
        GeomNode.__init__(self, name)
        self._width = width
        self._height = height
        assert(len(points) == self._width * self._height)
        if normals:
            assert(len(normals) == self._width * self._height)
        self._points = points
        self._normals = normals
        self._color = color
        self._wireframe = wireframe

        self._create_vertex_data()
        self._create_geom_primitives()
        self._create_geoms()

        # set visualisation parameters
        if self._wireframe:
            self.setAttrib(RenderModeAttrib.make(RenderModeAttrib.MWireframe, 2, 1))
        self.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullNone))
Example #34
0
	def init_node_path(self):
		if self.node_path:
			self.node_path.remove()
		vdata = GeomVertexData('name_me', self.format, Geom.UHStatic)
		vertex = GeomVertexWriter(vdata, 'vertex')
		color = GeomVertexWriter(vdata, 'color')
		primitive = GeomLines(Geom.UHStatic)
		vertex.addData3f(*coords_to_panda(*self.vector))
		vertex.addData3f(*coords_to_panda(*[-x for x in self.vector]))
		color.addData4f((1.0, 0.0, 0.0, 1.0,))
		color.addData4f((0.0, 0.0, 1.0, 1.0,))
		primitive.addNextVertices(2)
		primitive.closePrimitive()
		geom = Geom(vdata)
		geom.addPrimitive(primitive)
		node = GeomNode('gnode')
		node.addGeom(geom)
		self.node_path = self.parent.parent.node_path_ui.attachNewNode(node)
		self.node_path.setScale(20)
		self.node_path.setPos(*coords_to_panda(*self.coords))
 def collideWithGeom(self):
     # The into collide mask is the bit pattern colliders look at
     # when deciding whether or not to test for a collision "into"
     # this collision solid.  Set to all Off so this collision solid
     # will not be considered in any collision tests
     self.collisionNode.setIntoCollideMask(BitMask32().allOff())
     # The from collide mask is the bit pattern *this* collision solid
     # compares against the into collide mask of candidate collision solids
     # Turn this mask all off since we're not testing for collisions against
     # collision solids, but we do want to test against geometry
     self.collisionNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
Example #36
0
 def create_ray(self, object, entity, name, show = False, x = 0, y = 0, z = 0,
                dx = 0, dy = 0, dz = -1):
   # create queue
   object.queue = CollisionHandlerQueue()
   # create ray
   object.rayNP = entity.attachNewNode(CollisionNode(name))
   object.ray = CollisionRay(x, y, 1, dx, dy, dz)
   object.rayNP.node().addSolid(object.ray)
   object.rayNP.node().setFromCollideMask(GeomNode.getDefaultCollideMask())
   base.cTrav.addCollider(object.rayNP, object.queue)
   if show:
     object.rayNP.show()
Example #37
0
def stripAttribs(geom, cls):
    for np in geom.findAllMatches("**/+GeomNode"):
        node = np.node()
        for i in range(node.getNumGeoms()):
            gs = node.getGeomState(i)
            node.setGeomState(i, gs.removeAttrib(cls.getClassType()))

    if geom.node().getClassType() == GeomNode.getClassType():
        node = geom.node()
        for i in range(node.getNumGeoms()):
            gs = node.getGeomState(i)
            node.setGeomState(i, gs.removeAttrib(cls.getClassType()))
def stripAttribs(geom, cls):
    for np in geom.findAllMatches('**/+GeomNode'):
        node = np.node()
        for i in range(node.getNumGeoms()):
            gs = node.getGeomState(i)
            node.setGeomState(i, gs.removeAttrib(cls.getClassType()))

    if geom.node().getClassType() == GeomNode.getClassType():
        node = geom.node()
        for i in range(node.getNumGeoms()):
            gs = node.getGeomState(i)
            node.setGeomState(i, gs.removeAttrib(cls.getClassType()))
Example #39
0
 def init_collide(self):
     # why the heck he import within method
     from pandac.PandaModules import CollisionTraverser, CollisionNode
     from pandac.PandaModules import CollisionHandlerQueue, CollisionRay
     # init and import collision for object
     self.cTrav = CollisionTraverser('MousePointer')
     self.cQueue = CollisionHandlerQueue()
     self.cNode = CollisionNode('MousePointer')
     self.cNodePath = base.camera.attachNewNode(self.cNode)
     self.cNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
     self.cRay = CollisionRay()
     self.cNode.addSolid(self.cRay)
     self.cTrav.addCollider(self.cNodePath, self.cQueue)
Example #40
0
 def createRay(
     self, obj, ent, name, show=False, x=0, y=0, z=0, dx=0, dy=0, dz=-1
 ):
     #create queue
     obj.queue = CollisionHandlerQueue()
     #create ray
     obj.rayNP = ent.attachNewNode(CollisionNode(name))
     obj.ray = CollisionRay(x, y, z, dx, dy, dz)
     obj.rayNP.node().addSolid(obj.ray)
     obj.rayNP.node().setFromCollideMask(GeomNode.getDefaultCollideMask())
     sandbox.pickTrav.addCollider(obj.rayNP, obj.queue)
     if show:
         obj.rayNP.show()
Example #41
0
    def generate(self):
        format = GeomVertexFormat.getV3()
        data = GeomVertexData("Data", format, Geom.UHStatic)
        vertices = GeomVertexWriter(data, "vertex")

        size = self.size
        vertices.addData3f(-size, -size, -size)
        vertices.addData3f(+size, -size, -size)
        vertices.addData3f(-size, +size, -size)
        vertices.addData3f(+size, +size, -size)
        vertices.addData3f(-size, -size, +size)
        vertices.addData3f(+size, -size, +size)
        vertices.addData3f(-size, +size, +size)
        vertices.addData3f(+size, +size, +size)

        triangles = GeomTriangles(Geom.UHStatic)

        def addQuad(v0, v1, v2, v3):
            triangles.addVertices(v0, v1, v2)
            triangles.addVertices(v0, v2, v3)
            triangles.closePrimitive()

        addQuad(4, 5, 7, 6) # Z+
        addQuad(0, 2, 3, 1) # Z-
        addQuad(3, 7, 5, 1) # X+
        addQuad(4, 6, 2, 0) # X-
        addQuad(2, 6, 7, 3) # Y+
        addQuad(0, 1, 5, 4) # Y+

        geom = Geom(data)
        geom.addPrimitive(triangles)

        node = GeomNode("CubeMaker")
        node.addGeom(geom)

        path = NodePath(node)
        path.setColor(1.0, 0.0, 1.0)

        return NodePath(node)
Example #42
0
    def draw(self):
        format = GeomVertexFormat.getV3n3cpt2()
        vdata = GeomVertexData('square', format, Geom.UHDynamic)
        vertex = GeomVertexWriter(vdata, 'vertex')
        normal = GeomVertexWriter(vdata, 'normal')
        color = GeomVertexWriter(vdata, 'color')
        circle = Geom(vdata)
        # Create vertices
        vertex.addData3f(self.pos)
        color.addData4f(self.color)
        for v in range(self._EDGES):
            x = self.pos.getX() + (self.size * math.cos(
                (2 * math.pi / self._EDGES) * v))
            y = self.pos.getY() + (self.size * math.sin(
                (2 * math.pi / self._EDGES) * v))
            z = self.pos.getZ()
            vertex.addData3f(x, y, z)
            color.addData4f(self.color)

        # Create triangles
        for t in range(self._EDGES):
            tri = GeomTriangles(Geom.UHDynamic)
            tri.addVertex(0)
            tri.addVertex(t + 1)
            if (t + 2) > self._EDGES:
                tri.addVertex(1)
            else:
                tri.addVertex(t + 2)
            tri.closePrimitive()
            circle.addPrimitive(tri)

        gn = GeomNode('Circle')
        gn.addGeom(circle)
        np = NodePath(gn)
        np.setHpr(0, 90, 0)
        return np
Example #43
0
	def __init__(self):
		''' Should the traverser be shared? '''
		
		LOG.debug("[Selector] Initializing")
		
		# The collision traverser does the checking of solids for collisions
		self.cTrav = CollisionTraverser()
		
		# The collision handler queue is a simple handler that records all
		# detected collisions during traversal
		self.cHandler = CollisionHandlerQueue()
		
		self.pickerNode = CollisionNode('mouseRay')
		self.pickerNP = camera.attachNewNode(self.pickerNode)
		self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
		self.pickerRay = CollisionRay()
		self.pickerNode.addSolid(self.pickerRay)
		self.cTrav.addCollider(self.pickerNP, self.cHandler)
		
		# Start listening to clicks
		self.resume()
Example #44
0
    def init_ui(self):
        self.cTrav = CollisionTraverser('ui_collision_traverser')
        self.collision_handler = CollisionHandlerQueue()
        picker_node = CollisionNode('mouse_click_ray')
        self.picker_node_path = self.camera.attachNewNode(picker_node)
        picker_node.setFromCollideMask(GeomNode.getDefaultCollideMask())
        self.picker_ray = CollisionRay()
        picker_node.addSolid(self.picker_ray)
        self.cTrav.addCollider(self.picker_node_path, self.collision_handler)

        '''
        #debug: make a visible line segment
        from pandac.PandaModules import LineSegs, LVecBase4f, NodePath
        seg_drawer = LineSegs()
        seg_drawer.setColor(LVecBase4f(1, 0, 0, 1)) #red
        seg_drawer.moveTo(0,0,0)
        seg_drawer.drawTo(0,100,0)
        NodePath(seg_drawer.create()).reparentTo(self.picker_node_path)
        '''

        self.accept('a', self.mouse_ray)
Example #45
0
    def __init__(self):
        ''' Should the traverser be shared? '''

        LOG.debug("[Selector] Initializing")

        # The collision traverser does the checking of solids for collisions
        self.cTrav = CollisionTraverser()

        # The collision handler queue is a simple handler that records all
        # detected collisions during traversal
        self.cHandler = CollisionHandlerQueue()

        self.pickerNode = CollisionNode('mouseRay')
        self.pickerNP = camera.attachNewNode(self.pickerNode)
        self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
        self.pickerRay = CollisionRay()
        self.pickerNode.addSolid(self.pickerRay)
        self.cTrav.addCollider(self.pickerNP, self.cHandler)

        # Start listening to clicks
        self.resume()
Example #46
0
 def createRay(self,
               obj,
               ent,
               name,
               show=False,
               x=0,
               y=0,
               z=0,
               dx=0,
               dy=0,
               dz=-1):
     #create queue
     obj.queue = CollisionHandlerQueue()
     #create ray
     obj.rayNP = ent.attachNewNode(CollisionNode(name))
     obj.ray = CollisionRay(x, y, z, dx, dy, dz)
     obj.rayNP.node().addSolid(obj.ray)
     obj.rayNP.node().setFromCollideMask(GeomNode.getDefaultCollideMask())
     sandbox.pickTrav.addCollider(obj.rayNP, obj.queue)
     if show:
         obj.rayNP.show()
Example #47
0
 def __init__(self, blocks, mapInfo):        
     self.destroyedBlocks = []
     self.addedBlocks = []
     self.hasChanged = 0
     self.node = GeomNode('gnode') 
     self.chunks = [] 
     self.collisionGeom = 0
     self.blocks = blocks
     self.mapInfo = mapInfo   
     
     self.xmax = self.mapInfo.GetSize()[0]
     self.ymax = self.mapInfo.GetSize()[1]
     self.zmax = self.mapInfo.GetSize()[2]
     
     self.InitializeChunks()
                 
     terrain = render.attachNewNode(self.node) 
     #terrain.flattenStrong()
     #terrain.setRenderModeWireframe() 
     terrain.analyze()
     
     if(not Settings.IS_SERVER):
         self.SetupLights()
from pandac.PandaModules import CollisionRay
from pandac.PandaModules import CollisionHandlerQueue
from pandac.PandaModules import CollisionTraverser
from pandac.PandaModules import GeomNode
from pandac.PandaModules import LineSegs
from pandac.PandaModules import NodePath
from pandac.PandaModules import Point3
from pandac.PandaModules import Vec3

import math
from math import sqrt

wallRayNP = render.attachNewNode(CollisionNode("wall ray collision node"))
wallRayNP.node().addSolid(CollisionRay(0,0,0,0,1,0))
wallRayNP.node().setIntoCollideMask(BitMask32.allOff())
wallRayNP.node().setFromCollideMask(BitMask32.allOn() & ~GeomNode.getDefaultCollideMask())
wallRayNP.node().setFromCollideMask(wallRayNP.node().getFromCollideMask() & ~BitMask32.bit(1))
#wallRayNP.show()

collisionHandler = CollisionHandlerQueue()
collisionTraverser = CollisionTraverser("pathfinder's collisionTraverser")
collisionTraverser.addCollider(wallRayNP, collisionHandler)
collisionTraverser.setRespectPrevTransform(True)

class PathFinder():
    
##    def __init__(self, position, ID = -1):
##        NodePath.__init__(self, "Waypoint")
##        self.position = position
##        self.texture = loader.loadTexture("textures/blue.jpg")
##        self.costToThisNode = 0
Example #49
0
    def visualize(self,
                  parentNodePath,
                  highlightVerts=[],
                  pathVerts=[],
                  visitedVerts=[]):
        '''
        XXX Should move this into a product-specific class.
        '''
        gFormat = GeomVertexFormat.getV3cp()
        self.visVertexData = GeomVertexData("OMGVERTEXDATA2", gFormat,
                                            Geom.UHDynamic)
        self.visVertexWriter = GeomVertexWriter(self.visVertexData, "vertex")
        self.visVertexColorWriter = GeomVertexWriter(self.visVertexData,
                                                     "color")

        vertToWriterIndex = {}
        currIndex = 0

        for v in self.vertexCoords.keys():
            vertToWriterIndex[v] = currIndex
            x = self.vertexCoords[v][0]
            y = self.vertexCoords[v][1]
            z = self.vertexCoords[v][2]
            self.visVertexWriter.addData3f(x, y, z + 0.5)
            if v in highlightVerts:
                self.visVertexColorWriter.addData4f(1.0, 0.0, 0.0, 1.0)
            elif v in visitedVerts:
                self.visVertexColorWriter.addData4f(0.0, 0.0, 1.0, 1.0)
            else:
                self.visVertexColorWriter.addData4f(1.0, 1.0, 0.0, 1.0)
            currIndex += 1

        pathOffsetIntoIndex = currIndex

        for v in pathVerts:
            self.visVertexWriter.addData3f(v[0], v[1], v[2] + 0.5)
            self.visVertexColorWriter.addData4f(0.0, 1.0, 0.0, 1.0)
            currIndex += 1

        lines = GeomLinestrips(Geom.UHStatic)

        for p in self.polyToVerts.keys():
            for v in self.polyToVerts[p]:
                lines.addVertex(vertToWriterIndex[v])
            lines.addVertex(vertToWriterIndex[self.polyToVerts[p][0]])
            lines.closePrimitive()

        if len(pathVerts) > 0:
            for i in xrange(len(pathVerts)):
                lines.addVertex(pathOffsetIntoIndex + i)
            lines.closePrimitive()

        self.visGeom = Geom(self.visVertexData)
        self.visGeom.addPrimitive(lines)

        self.visGN = GeomNode("NavMeshVis")
        self.visGN.addGeom(self.visGeom)

        self.visNodePath = parentNodePath.attachNewNode(self.visGN)

        self.visNodePath.setTwoSided(True)
Example #50
0
class NavMesh(object):

    notify = directNotify.newCategory("NavMesh")

    def __init__(self, filepath=None, filename=None):
        if filename is not None:
            self._initFromFilename(filepath, filename)

    def initFromPolyData(self, polyToVerts, vertToPolys, polyToAngles,
                         vertexCoords, environmentHash):
        '''
        Initialize the mesh from a set of polygons.

        polyToVerts:     Dictionary mapping a polygon ID to a set of N vertex IDs
        vertToPolys:     Dictionary mapping a vertex ID to a set of poly IDs (of every poly that includes it)
        polyToAngles:    Dictionary mapping a polygon ID to a set of N angles (in vertex order)
        vertexCoords:    Dictionary mapping a vertex ID to the coordinates of the vertex in worldspace
        environmentHash: Hash value derived from the same collision geometry as the other arguments.  See AreaMapper.getEnvironmentHash().
        '''
        self.polyToVerts = polyToVerts
        self.vertToPolys = vertToPolys
        self.polyToAngles = polyToAngles
        self.vertexCoords = vertexCoords
        self.environmentHash = environmentHash

        self.connectionLookup = {}

        self.connections = []

        self._discoverInitialConnectivity()

        self.optimizeMesh()

    def visualize(self,
                  parentNodePath,
                  highlightVerts=[],
                  pathVerts=[],
                  visitedVerts=[]):
        '''
        XXX Should move this into a product-specific class.
        '''
        gFormat = GeomVertexFormat.getV3cp()
        self.visVertexData = GeomVertexData("OMGVERTEXDATA2", gFormat,
                                            Geom.UHDynamic)
        self.visVertexWriter = GeomVertexWriter(self.visVertexData, "vertex")
        self.visVertexColorWriter = GeomVertexWriter(self.visVertexData,
                                                     "color")

        vertToWriterIndex = {}
        currIndex = 0

        for v in self.vertexCoords.keys():
            vertToWriterIndex[v] = currIndex
            x = self.vertexCoords[v][0]
            y = self.vertexCoords[v][1]
            z = self.vertexCoords[v][2]
            self.visVertexWriter.addData3f(x, y, z + 0.5)
            if v in highlightVerts:
                self.visVertexColorWriter.addData4f(1.0, 0.0, 0.0, 1.0)
            elif v in visitedVerts:
                self.visVertexColorWriter.addData4f(0.0, 0.0, 1.0, 1.0)
            else:
                self.visVertexColorWriter.addData4f(1.0, 1.0, 0.0, 1.0)
            currIndex += 1

        pathOffsetIntoIndex = currIndex

        for v in pathVerts:
            self.visVertexWriter.addData3f(v[0], v[1], v[2] + 0.5)
            self.visVertexColorWriter.addData4f(0.0, 1.0, 0.0, 1.0)
            currIndex += 1

        lines = GeomLinestrips(Geom.UHStatic)

        for p in self.polyToVerts.keys():
            for v in self.polyToVerts[p]:
                lines.addVertex(vertToWriterIndex[v])
            lines.addVertex(vertToWriterIndex[self.polyToVerts[p][0]])
            lines.closePrimitive()

        if len(pathVerts) > 0:
            for i in xrange(len(pathVerts)):
                lines.addVertex(pathOffsetIntoIndex + i)
            lines.closePrimitive()

        self.visGeom = Geom(self.visVertexData)
        self.visGeom.addPrimitive(lines)

        self.visGN = GeomNode("NavMeshVis")
        self.visGN.addGeom(self.visGeom)

        self.visNodePath = parentNodePath.attachNewNode(self.visGN)

        self.visNodePath.setTwoSided(True)

    def _discoverInitialConnectivity(self):
        print "Building initial connectivity graph..."
        for pId in self.polyToVerts.keys():
            verts = self.polyToVerts[pId]

            numVerts = len(verts)
            candidates = []
            neighborPolys = []

            for v in verts:
                candidates += [
                    p for p in self.vertToPolys[v]
                    if (p not in candidates) and (p != pId)
                ]

            for vNum in xrange(numVerts):
                neighbor = [p for p in candidates if ((verts[vNum] in self.polyToVerts[p]) and \
                                                      (verts[(vNum+1)%numVerts] in self.polyToVerts[p]))]
                if len(neighbor) == 0:
                    neighborPolys.append(None)
                elif len(neighbor) == 1:
                    neighborPolys.append(neighbor[0])
                else:
                    raise "Two neighbors found for the same edge?!?!"

            self.connectionLookup[pId] = neighborPolys

    # --------- Begin stitching code ---------

    def _attemptToMergePolys(self, polyA, polyB):
        newVerts = []
        newAngles = []
        newConnections = []

        vertsA = self.polyToVerts[polyA]
        vertsB = self.polyToVerts[polyB]

        lenA = len(vertsA)
        lenB = len(vertsB)

        anglesA = self.polyToAngles[polyA]
        anglesB = self.polyToAngles[polyB]

        sharedVerts = [v for v in vertsA if (v in vertsB)]

        locA = 0

        while vertsA[locA] not in sharedVerts:
            locA += 1

        while vertsA[locA] in sharedVerts:
            locA = (locA - 1) % lenA

        locA = (locA + 1) % lenA

        CCWmost = vertsA[locA]
        CCWmostLocA = locA

        while vertsA[locA] in sharedVerts:
            locA = (locA + 1) % lenA

        locA = (locA - 1) % lenA

        CWmost = vertsA[locA]
        CWmostLocA = locA

        # Convexity Check.
        # Verify that removing the edge preserves convexity and bail out if not.

        locA = 0
        locB = 0
        while vertsA[locA] != CCWmost:
            locA += 1
        while vertsB[locB] != CCWmost:
            locB += 1
        CCWmostAngleSum = anglesA[locA] + anglesB[locB]
        CCWmostLocB = locB
        if CCWmostAngleSum > 180:
            return False

        locA = 0
        locB = 0
        while vertsA[locA] != CWmost:
            locA += 1
        while vertsB[locB] != CWmost:
            locB += 1
        CWmostAngleSum = anglesA[locA] + anglesB[locB]
        if CWmostAngleSum > 180:
            return False

        # We've found the CW-most vert of the shared edge.
        # Now walk A clockwise until we hit the CCW-most vert of the shared edge.

        newVerts.append(CWmost)
        newAngles.append(CWmostAngleSum)
        newConnections.append(self.connectionLookup[polyA][locA])
        locA = (locA + 1) % lenA

        while vertsA[locA] != CCWmost:
            newVerts.append(vertsA[locA])
            newAngles.append(anglesA[locA])
            newConnections.append(self.connectionLookup[polyA][locA])
            locA = (locA + 1) % lenA

        # Now we've hit the CCW-most vert of the shared edge.
        # Walk B clockwise until we get back to the CW-most vert of the shared edge.

        locB = CCWmostLocB

        newVerts.append(CCWmost)
        newAngles.append(CCWmostAngleSum)
        neighbor = self.connectionLookup[polyB][locB]
        newConnections.append(neighbor)
        if neighbor is not None:
            for i in xrange(len(self.connectionLookup[neighbor])):
                if self.connectionLookup[neighbor][i] == polyB:
                    self.connectionLookup[neighbor][i] = polyA

        locB = (locB + 1) % lenB

        while vertsB[locB] != CWmost:
            newVerts.append(vertsB[locB])
            newAngles.append(anglesB[locB])
            neighbor = self.connectionLookup[polyB][locB]
            newConnections.append(neighbor)
            if neighbor is not None:
                for i in xrange(len(self.connectionLookup[neighbor])):
                    if self.connectionLookup[neighbor][i] == polyB:
                        self.connectionLookup[neighbor][i] = polyA
            locB = (locB + 1) % lenB

        # We've added every vertex, its proper angle, and connectivity info
        # to the new polygon.  Now replace A with the new guy and remove B.

        self.polyToVerts[polyA] = newVerts
        self.polyToAngles[polyA] = newAngles
        self.connectionLookup[polyA] = newConnections

        # Make sure we have vertex->poly pointers for all the new verts we added to A.
        for v in newVerts:
            if polyA not in self.vertToPolys[v]:
                self.vertToPolys[v].append(polyA)

        # Clean up all of B's old vertices.
        for v in vertsB:
            self.vertToPolys[v].remove(polyB)
            if len(self.vertToPolys[v]) == 0:
                # No one's using this vertex anymore, remove it
                del self.vertToPolys[v]
                del self.vertexCoords[v]

        del self.polyToVerts[polyB]
        del self.polyToAngles[polyB]
        del self.connectionLookup[polyB]

        return True

    def _attemptToGrowPoly(self, pId):
        for neighbor in self.connectionLookup.get(pId, []):
            if (neighbor is not None) and self._attemptToMergePolys(
                    pId, neighbor):
                return True
        return False

    def _growEachPolyOnce(self):
        grewAtLeastOne = False

        for pId in self.connectionLookup.keys():
            if self._attemptToGrowPoly(pId):
                grewAtLeastOne = True

        return grewAtLeastOne

    def optimizeMesh(self):
        '''
        Takes a mesh that is already functionally complete and optimizes it for better performance.
        Reduces poly count and cuts out redundant vertices.
        Also compacts the polygon IDs into a contiguous range from 0 to N.
        No need to do the same for vertex IDs yet.
        '''
        '''print "Stitching polygons: %s -> " % (len(self.polyToVerts)),
        orig = len(self.polyToVerts)
        numPasses = 1
        while self._growEachPolyOnce():
            print "%s -> " % (len(self.polyToVerts)),
            numPasses += 1
        print "Done!\nPoly count reduced to %0.1f%% of original." % (len(self.polyToVerts)/float(orig)*100.0)'''

        self._pruneExtraVerts()

        self._compactPolyIds()

        self.numNodes = len(self.connections)

        biggest = 0
        biggestPoly = -1
        for p in self.polyToVerts:
            if len(self.polyToVerts[p]) > biggest:
                biggest = len(self.polyToVerts[p])
                biggestPoly = p

        print "Most verts in a single poly: ", biggest
        assert biggest < 256

    def _cleanPoly(self, polyId):
        verts = self.polyToVerts[polyId]
        angles = self.polyToAngles[polyId]
        neighbors = self.connectionLookup[polyId]
        numVerts = len(verts)

        newVerts = []
        newAngles = []
        newNeighbors = []

        for i in xrange(numVerts):
            if (angles[i] != 180) or \
               (len(self.vertToPolys.get(verts[i],[])) > 2) or \
               (neighbors[i] != neighbors[(i-1)%numVerts]):
                # Keep vertex
                newVerts.append(verts[i])
                newAngles.append(angles[i])
                newNeighbors.append(neighbors[i])
            else:
                # Remove vertex, this will happen twice so pop it
                self.vertToPolys.pop(verts[i], None)
                self.vertexCoords.pop(verts[i], None)

        if len(verts) != len(newVerts):
            self.polyToVerts[polyId] = newVerts
            self.polyToAngles[polyId] = newAngles
            self.connectionLookup[polyId] = newNeighbors

        assert len(newVerts) < 256

    def _pruneExtraVerts(self):
        print "Pruning extra vertices..."
        print "Starting verts: %s" % len(self.vertToPolys)
        for polyId in self.connectionLookup.keys():
            self._cleanPoly(polyId)
        print "Ending verts: %s" % len(self.vertToPolys)

    def _compactPolyIds(self):
        polyList = self.polyToVerts.keys()
        polyList.sort()

        oldToNewId = {None: None}

        newPolyToVerts = {}
        newPolyToAngles = {}
        self.connections = []

        currId = 0

        for oldId in polyList:
            oldToNewId[oldId] = currId
            self.connections.append([])
            currId += 1

        for oldId in polyList:
            newPolyToVerts[oldToNewId[oldId]] = self.polyToVerts[oldId]
            newPolyToAngles[oldToNewId[oldId]] = self.polyToAngles[oldId]
            #self.connections[oldToNewId[oldId]] = []
            for edgeNum in xrange(len(self.connectionLookup[oldId])):
                self.connections[oldToNewId[oldId]].append(
                    oldToNewId[self.connectionLookup[oldId][edgeNum]])

        self.polyToVerts = newPolyToVerts
        self.polyToAngles = newPolyToAngles
        del self.connectionLookup

    # --------- Begin pathfinding code ---------

    def _findCentroid(self, polyId):
        verts = self.polyToVerts[polyId]
        numVerts = len(verts)
        x = 0
        y = 0
        z = 0
        for v in verts:
            x += self.vertexCoords[v][0]
            y += self.vertexCoords[v][1]
            z += self.vertexCoords[v][2]

        x /= numVerts
        y /= numVerts
        z /= numVerts

        return (x, y, z)

##     def _estimateDistanceBetweenPolys(self, polyA, polyB):
##         centroidA = self._findCentroid(polyA)
##         centroidB = self._findCentroid(polyB)

##         dx = centroidA[0] - centroidB[0]
##         dy = centroidA[1] - centroidB[1]
##         dz = centroidA[2] - centroidB[2]

##         return math.sqrt(dx*dx + dy*dy + dz*dz)

    def _walkToNeighbor(self, currPoly, neighborPoly):
        currVerts = self.polyToVerts[currPoly]
        neighborVerts = self.polyToVerts[neighborPoly]

        lenCurr = len(currVerts)

        sharedVerts = [v for v in currVerts if (v in neighborVerts)]

        loc = 0

        while currVerts[loc] not in sharedVerts:
            loc += 1

        while currVerts[loc] in sharedVerts:
            loc = (loc - 1) % lenCurr

        loc = (loc + 1) % lenCurr

        CCWmost = currVerts[loc]
        CCWmostLoc = loc

        while currVerts[loc] in sharedVerts:
            loc = (loc + 1) % lenCurr

        loc = (loc - 1) % lenCurr

        CWmost = currVerts[loc]

        CCWmostCoords = self.vertexCoords[CCWmost]
        CWmostCoords = self.vertexCoords[CWmost]

        # For now, walk to the midpoint of the connecting edge

        departingEdge = CCWmostLoc  # Don't need this with goal->start search

        neighborsEdge = 0
        while self.connections[neighborPoly][neighborsEdge] != currPoly:
            neighborsEdge += 1

        return (neighborsEdge, ((CWmostCoords[0] + CCWmostCoords[0]) / 2.0,
                                (CWmostCoords[1] + CCWmostCoords[1]) / 2.0,
                                (CWmostCoords[2] + CCWmostCoords[2]) / 2.0))

##     def _remakePath(self,walkBack,currNode):
##         if currNode in walkBack:
##             p = self._remakePath(walkBack,walkBack[currNode])
##             return p + [currNode,]
##         return [currNode,]

##     def findRoute(self, startNode, goalNode):
##         '''
##         So much love for A*.
##         '''
##         nodeToF = {}
##         nodeToG = {}
##         nodeToH = {}

##         walkBack = {}

##         #nodeToEntryPoint = {}
##         self.nodeToEntryPoint[startNode] = self._findCentroid(startNode)

##         nodeToG[startNode] = 0
##         nodeToH[startNode] = self._estimateDistanceBetweenPolys(startNode,goalNode)
##         nodeToF[startNode] = nodeToG[startNode] + nodeToH[startNode]

##         closedSet = {}
##         openSet = {}
##         openQueue = PriQueue() # Priority = F score

##         openSet[startNode] = 1
##         openQueue.push((nodeToF[startNode],startNode))

##         goalPoint = self._findCentroid(goalNode)

##         while len(openSet) > 0:
##             f,currNode = openQueue.pop(0)
##             del openSet[currNode]

##             self.aStarWasHere[currNode] = 1

##             if currNode == goalNode:
##                 return self._remakePath(walkBack,currNode)

##             closedSet[currNode] = 1

##             currPoint = self.nodeToEntryPoint[currNode]

##             for neighbor in self.connections[currNode]:
##                 if (neighbor is not None) and (neighbor not in closedSet):
##                     departingEdge,newEntryPoint = self._walkToNeighbor(currNode,currPoint,neighbor)
##                     newG = nodeToG[currNode] + math.sqrt((newEntryPoint[0] - currPoint[0])**2 + \
##                                                          (newEntryPoint[1] - currPoint[1])**2 + \
##                                                          (newEntryPoint[2] - currPoint[2])**2)
##                     gotHereFasterThanBefore = False

##                     if neighbor not in openSet:
##                         openSet[neighbor] = 1
##                         gotHereFasterThanBefore = True
##                     elif newG < nodeToG[neighbor]:
##                         openQueue.remove((nodeToF[neighbor],neighbor))
##                         gotHereFasterThanBefore = True

##                     if gotHereFasterThanBefore:
##                         walkBack[neighbor] = currNode
##                         self.nodeToEntryPoint[neighbor] = newEntryPoint
##                         nodeToH[neighbor] = math.sqrt((goalPoint[0] - newEntryPoint[0])**2 + \
##                                                       (goalPoint[1] - newEntryPoint[1])**2 + \
##                                                       (goalPoint[2] - newEntryPoint[2])**2)
##                         nodeToG[neighbor] = newG
##                         nodeToF[neighbor] = nodeToG[neighbor] + nodeToH[neighbor]
##                         openQueue.push((nodeToF[neighbor],neighbor))

##         raise "No path found!  D:"

    def _findAllRoutesToGoal(self, goalNode):
        '''
        Find the shortest path from ALL start nodes to the given goal node.  (Djikstra)
        
        After running, self.pathData[startNode][goalNode] == outgoing edge from startNode to the next node
        for the given value of goalNode and ALL values of startNode.
        '''
        nodeToG = {}

        walkBack = {}

        nodeDeparturePoint = {}
        nodeDeparturePoint[goalNode] = self._findCentroid(goalNode)

        nodeToG[goalNode] = 0

        closedSet = {}
        openSet = {}
        openQueue = PriQueue()

        openSet[goalNode] = 1
        openQueue.push((nodeToG[goalNode], goalNode))

        walkBack[goalNode] = (0, goalNode)

        while len(openSet) > 0:
            f, currNode = openQueue.pop(0)
            del openSet[currNode]

            closedSet[currNode] = 1

            currPoint = nodeDeparturePoint[currNode]

            for neighbor in self.connections[currNode]:
                if (neighbor is not None) and (neighbor not in closedSet):
                    neighborsEdge, newPoint = self._walkToNeighbor(
                        currNode, neighbor)
                    newG = nodeToG[currNode] + math.sqrt((newPoint[0] - currPoint[0])**2 + \
                                                         (newPoint[1] - currPoint[1])**2 + \
                                                         (newPoint[2] - currPoint[2])**2)
                    gotHereFasterThanBefore = False

                    if neighbor not in openSet:
                        openSet[neighbor] = 1
                        gotHereFasterThanBefore = True
                    elif newG < nodeToG[neighbor]:
                        openQueue.remove((nodeToG[neighbor], neighbor))
                        gotHereFasterThanBefore = True

                    if gotHereFasterThanBefore:
                        walkBack[neighbor] = (neighborsEdge, currNode)
                        nodeDeparturePoint[neighbor] = newPoint
                        nodeToG[neighbor] = newG
                        openQueue.push((nodeToG[neighbor], neighbor))

        for startNode in xrange(len(self.connections)):
            departingEdge = walkBack[startNode][0]

            assert self.pathData[startNode][goalNode] is None

            self.pathData[startNode][goalNode] = departingEdge

    def generatePathData(self, rowRange=None):
        '''
        Entry point for path preprocessing.
        Solves all pairs shortest path for this mesh.
        Stores the result in self.pathData.
        SLOW.  Expect 8-10 minutes on Port Royal alone.

        Currently runs Djikstra on every possible start node.
        There are faster approaches for APSP, but...
        '''
        if rowRange is None:
            rowRange = (0, self.numNodes)

        self.initPathData()

        for goalNode in xrange(rowRange[0], rowRange[1]):
            self._findAllRoutesToGoal(goalNode)

    def createPathTable(self):
        '''
        Takes a 2D array self.pathData and changes it in place.
        Each row is changed into a run-length encoded string.
        Then, feeds the data into a new PathTable instance.
        '''
        for row in self.pathData:
            for val in row:
                if val == None:
                    raise "Incomplete path data!"

        shortestPathLookup = self.pathData

        self.pathData = []

        # Run-Length Encode the whole thing!
        for start in xrange(self.numNodes):
            row = []
            lastVal = None
            nodesInRow = 0
            for goal in xrange(self.numNodes):
                val = shortestPathLookup[start][goal]
                if val != lastVal:
                    row.append([goal, val])
                    lastVal = val
                    nodesInRow += 1
                else:
                    nodesInRow += 1

            assert nodesInRow == self.numNodes

            stringsRow = []

            # Convert row to a bytestring to save space
            for item in row:
                assert item[0] < 65536
                assert item[1] < 256

                stringsRow.append(
                    chr(item[0] / 256) + chr(item[0] % 256) + chr(item[1]))

                assert len(stringsRow[-1]) == 3

            rowString = string.join(stringsRow, "")

            self.pathData.append(rowString)

        self.pathTable = PathTable(self.pathData, self.connections)

    def printPathData(self):
        '''
        Outputs the pickled path table to stdout.
        '''
        import sys
        sys.stdout.write(pickle.dumps(self.pathData, protocol=0))

    def initPathData(self):
        self.pathData = []

        for i in xrange(self.numNodes):
            self.pathData.append([
                None,
            ] * self.numNodes)

    def addPaths(self, partialData):
        for i in xrange(len(partialData)):
            for j in xrange(len(partialData[i])):
                if partialData[i][j] is not None:
                    assert self.pathData[i][j] is None
                    self.pathData[i][j] = partialData[i][j]

##     def pathTableLookup(self, startNode, goalNode):
##         '''
##         Look up the equivalent of pathData[goalNode][startNode] in our run-length encoded data.
##         '''
##         if startNode >= self.numNodes or goalNode >= self.numNodes:
##             raise "Invalid node ID.  Must be less than self.numNodes (%s)." % self.numNodes

##         str = self.pathData[startNode]

##         pos = 0

##         while (pos < len(str)) and (256*ord(str[pos]) + ord(str[pos+1]) <= goalNode):
##             #print pos, ": ",256*ord(str[pos]) + ord(str[pos+1])
##             pos += 3

##         pos -= 3

##         return ord(str[pos+2])

    def findRoute(self, startNode, goalNode):
        '''
        Returns the node-by-node route from startNode to goalNode.
        '''
        return self.pathTable.findRoute(startNode, goalNode)

    def makeNodeLocator(self, environment):
        meshNode = CollisionNode("NavMeshNodeLocator")
        meshNode.setFromCollideMask(BitMask32.allOff())
        meshNode.setIntoCollideMask(OTPGlobals.PathFindingBitmask)

        self.polyHashToPID = {}

        for pId in self.polyToAngles:
            vertCount = 0
            corners = []
            for angle in self.polyToAngles[pId]:
                if angle != 180:
                    # It's a corner
                    corners.append(vertCount)
                vertCount += 1

            # XXX this code only works for square nodes at present
            # Unfortunately we can only make triangle or square CollisionPolygons on the fly
            assert len(corners) == 4

            #import pdb
            #pdb.set_trace()

            verts = []

            for vert in corners:
                verts.append(
                    (self.vertexCoords[self.polyToVerts[pId][vert]][0],
                     self.vertexCoords[self.polyToVerts[pId][vert]][1], 0))

            #import pdb
            #pdb.set_trace()

            poly = CollisionPolygon(verts[0], verts[1], verts[2], verts[3])

            assert poly not in self.polyHashToPID

            self.polyHashToPID[poly] = pId

            meshNode.addSolid(poly)

        ray = CollisionRay()
        ray.setDirection(0, 0, -1)
        ray.setOrigin(0, 0, 0)

        rayNode = CollisionNode("NavMeshRay")
        rayNode.setFromCollideMask(OTPGlobals.PathFindingBitmask)
        rayNode.setIntoCollideMask(BitMask32.allOff())
        rayNode.addSolid(ray)

        self.meshNodePath = environment.attachNewNode(meshNode)
        self.rayNodePath = environment.attachNewNode(rayNode)

        self.meshNodePath.setTwoSided(True)

        self.chq = CollisionHandlerQueue()
        self.traverser = CollisionTraverser()
        self.traverser.addCollider(self.rayNodePath, self.chq)

    def findNodeFromPos(self, environment, x, y):
        self.rayNodePath.setPos(environment, x, y, 50000)
        self.chq.clearEntries()

        self.traverser.traverse(self.meshNodePath)

        if self.chq.getNumEntries() != 1:
            self.notify.warning("No node found at position: %s, %s in %s" %
                                (x, y, environment))
            return 0

        e = self.chq.getEntry(0)

        assert e.hasInto()
        if not e.hasInto():
            self.notify.warning("No into found for collision %s" % (e))

        pId = self.polyHashToPID[e.getInto()]

        return pId

    # --------- Begin long-term storage code ---------

    def writeToFile(self, filename, storePathTable=True):
        '''
        Output the contents of this mesh to the file specified.
        Saving to a file lets us avoid doing expensive precomputation every time a mesh instance is required.
        '''
        if self.environmentHash is None:
            raise "Attempted write to file without valid environment hash!"

        if storePathTable and not self.pathData:
            raise "Attempted to write empty pathData.  Call NavMesh.generatePathTable() first!"

        f = open(filename, 'wb')

        if storePathTable:
            pickle.dump([
                self.environmentHash, self.polyToVerts, self.polyToAngles,
                self.vertexCoords, self.connections, self.pathData
            ],
                        f,
                        protocol=2)
            f.close()
            self.pathData = None
        else:
            pickle.dump([
                self.environmentHash, self.polyToVerts, self.polyToAngles,
                self.vertexCoords, self.connections, None
            ],
                        f,
                        protocol=2)
            f.close()

        print "Successfully wrote to file %s." % filename

    def _initFromString(self, str):
        contents = pickle.loads(str)

        self.environmentHash = contents[0]
        self.polyToVerts = contents[1]
        self.polyToAngles = contents[2]
        self.vertexCoords = contents[3]
        self.connections = contents[4]
        self.pathData = contents[5]

        if self.pathData is not None:
            self.pathTable = PathTable(self.pathData, self.connections)
            self.pathData = None

        self.numNodes = len(self.connections)

    def _initFromFilename(self, filepath, filename):
        vfs = VirtualFileSystem.getGlobalPtr()
        filename = Filename(filename)
        searchPath = DSearchPath()
        #searchPath.appendDirectory(Filename('.'))
        #searchPath.appendDirectory(Filename('etc'))
        #searchPath.appendDirectory(Filename.fromOsSpecific(os.path.expandvars('~')))
        #searchPath.appendDirectory(Filename.fromOsSpecific(os.path.expandvars('$HOME')))
        searchPath.appendDirectory(
            Filename.fromOsSpecific(os.path.expandvars(filepath)))

        found = vfs.resolveFilename(filename, searchPath)

        if not found:
            raise IOError, "File not found!"

        str = vfs.readFile(filename, 1)

        self._initFromString(str)

    def checkHash(self, envHash):
        '''
        "Does this mesh represent the environment I think it does?"
        If this check fails, the mesh is out of date (or being used with the wrong environment).
        In either case, whoever generated this instance should discard it and create a new mesh from scratch.
        '''
        return envHash == self.environmentHash
Example #51
0
 def addGeometry(self, geomData):
   debugGui = dict()
   
   format = GeomVertexFormat.getV3n3t2()
   vdata = GeomVertexData('name', format, Geom.UHStatic)
   vertex = GeomVertexWriter(vdata, 'vertex')
   normal = GeomVertexWriter(vdata, 'normal')
   texcoord = GeomVertexWriter(vdata, 'texcoord')
   prim = GeomTriangles(Geom.UHStatic)
   
   postphonedTriangles = list()
   vtxTargetId0 = vtxTargetId1 = vtxTargetId2 = None
   vtxDataCounter = 0
   for vtxSourceId0, vtxSourceId1, vtxSourceId2 in geomData.triangles:
     vx0,vy0,vz0 = v0 = geomData.getVertex(vtxSourceId0)
     vx1,vy1,vz1 = v1 = geomData.getVertex(vtxSourceId1)
     vx2,vy2,vz2 = v2 = geomData.getVertex(vtxSourceId2)
     # prepare the vertices
     uvx0, uvy0 = uv0 = geomData.getUv(vtxSourceId0)
     uvx1, uvy1 = uv1 = geomData.getUv(vtxSourceId1)
     uvx2, uvy2 = uv2 = geomData.getUv(vtxSourceId2)
     #
     n0 = geomData.getNormal(vtxSourceId0)
     n1 = geomData.getNormal(vtxSourceId1)
     n2 = geomData.getNormal(vtxSourceId2)
     
     # make it wrap nicely
     if min(uvx0,uvx1,uvx2) < .25 and max(uvx0,uvx1,uvx2) > 0.75:
       if uvx0 < 0.25: uvx0 += 1.0
       if uvx1 < 0.25: uvx1 += 1.0
       if uvx2 < 0.25: uvx2 += 1.0
     
     vertex.addData3f(*v0)
     normal.addData3f(*n0)
     texcoord.addData2f(*uv0)
     vtxTargetId0 = vtxDataCounter
     vtxDataCounter += 1
   
     vertex.addData3f(*v1)
     normal.addData3f(*n1)
     texcoord.addData2f(*uv1)
     vtxTargetId1 = vtxDataCounter
     vtxDataCounter += 1
   
     vertex.addData3f(*v2)
     normal.addData3f(*n2)
     texcoord.addData2f(*uv2)
     vtxTargetId2 = vtxDataCounter
     vtxDataCounter += 1
     
     prim.addVertex(vtxTargetId0)
     prim.addVertex(vtxTargetId1)
     prim.addVertex(vtxTargetId2)
     prim.closePrimitive()
     
     if False:
       if vtxSourceId0 not in debugGui:
         i = InfoTextBillaboarded(render)
         i.setScale(0.05)
         i.billboardNodePath.setPos(Vec3(x0,y0,z0)*1.1)
         i.setText('%i: %.1f %.1f %.1f\n%.1f %.1f' % (vtxSourceId0, x0,y0,z0, nx0, ny0))
         debugGui[vtxSourceId0] = i
       if vtxSourceId1 not in debugGui:
         i = InfoTextBillaboarded(render)
         i.setScale(0.05)
         i.billboardNodePath.setPos(Vec3(x1,y1,z1)*1.1)
         i.setText('%i: %.1f %.1f %.1f\n%.1f %.1f' % (vtxSourceId1, x1,y1,z1, nx1, ny1))
         debugGui[vtxSourceId1] = i
       if vtxSourceId2 not in debugGui:
         i = InfoTextBillaboarded(render)
         i.setScale(0.05)
         i.billboardNodePath.setPos(Vec3(x2,y2,z2)*1.1)
         i.setText('%i: %.1f %.1f %.1f\n%.1f %.1f' % (vtxSourceId2, x2,y2,z2, nx2, ny2))
         debugGui[vtxSourceId2] = i
   
   geom = Geom(vdata)
   geom.addPrimitive(prim)
   
   node = GeomNode('gnode')
   node.addGeom(geom)
   
   nodePath = self.attachNewNode(node)
   return nodePath
Example #52
0
class WireGeom:
    def __init__(self):
        # GeomNode to hold our individual geoms
        self.gnode = GeomNode('wirePrim')

        # How many times to subdivide our spheres/cylinders resulting vertices.  Keep low
        # because this is supposed to be an approximate representation
        self.subdiv = 12

    def drawLine(self, start, end):

        # since we're doing line segments, just vertices in our geom
        format = GeomVertexFormat.getV3()

        # build our data structure and get a handle to the vertex column
        vdata = GeomVertexData('', format, Geom.UHStatic)
        vertices = GeomVertexWriter(vdata, 'vertex')

        # build a linestrip vertex buffer
        lines = GeomLinestrips(Geom.UHStatic)

        vertices.addData3f(start[0], start[1], start[2])
        vertices.addData3f(end[0], end[1], end[2])

        lines.addVertices(0, 1)

        lines.closePrimitive()

        geom = Geom(vdata)
        geom.addPrimitive(lines)
        # Add our primitive to the geomnode
        self.gnode.addGeom(geom)

    def drawCircle(self, radius, axis, offset):

        # since we're doing line segments, just vertices in our geom
        format = GeomVertexFormat.getV3()

        # build our data structure and get a handle to the vertex column
        vdata = GeomVertexData('', format, Geom.UHStatic)
        vertices = GeomVertexWriter(vdata, 'vertex')

        # build a linestrip vertex buffer
        lines = GeomLinestrips(Geom.UHStatic)

        for i in range(0, self.subdiv):
            angle = i / float(self.subdiv) * 2.0 * math.pi
            ca = math.cos(angle)
            sa = math.sin(angle)
            if axis == "x":
                vertices.addData3f(0, radius * ca, radius * sa + offset)
            if axis == "y":
                vertices.addData3f(radius * ca, 0, radius * sa + offset)
            if axis == "z":
                vertices.addData3f(radius * ca, radius * sa, offset)

        for i in range(1, self.subdiv):
            lines.addVertices(i - 1, i)
        lines.addVertices(self.subdiv - 1, 0)

        lines.closePrimitive()

        geom = Geom(vdata)
        geom.addPrimitive(lines)
        # Add our primitive to the geomnode
        self.gnode.addGeom(geom)

    def drawCapsule(self, radius, length, axis):

        # since we're doing line segments, just vertices in our geom
        format = GeomVertexFormat.getV3()

        # build our data structure and get a handle to the vertex column
        vdata = GeomVertexData('', format, Geom.UHStatic)
        vertices = GeomVertexWriter(vdata, 'vertex')

        # build a linestrip vertex buffer
        lines = GeomLinestrips(Geom.UHStatic)

        # draw upper dome
        for i in range(0, self.subdiv / 2 + 1):
            angle = i / float(self.subdiv) * 2.0 * math.pi
            ca = math.cos(angle)
            sa = math.sin(angle)
            if axis == "x":
                vertices.addData3f(0, radius * ca, radius * sa + (length / 2))
            if axis == "y":
                vertices.addData3f(radius * ca, 0, radius * sa + (length / 2))

        # draw lower dome
        for i in range(0, self.subdiv / 2 + 1):
            angle = -math.pi + i / float(self.subdiv) * 2.0 * math.pi
            ca = math.cos(angle)
            sa = math.sin(angle)
            if axis == "x":
                vertices.addData3f(0, radius * ca, radius * sa - (length / 2))
            if axis == "y":
                vertices.addData3f(radius * ca, 0, radius * sa - (length / 2))

        for i in range(1, self.subdiv + 1):
            lines.addVertices(i - 1, i)
        lines.addVertices(self.subdiv + 1, 0)

        lines.closePrimitive()

        geom = Geom(vdata)
        geom.addPrimitive(lines)
        # Add our primitive to the geomnode
        self.gnode.addGeom(geom)

    def drawRect(self, width, height, axis):

        # since we're doing line segments, just vertices in our geom
        format = GeomVertexFormat.getV3()

        # build our data structure and get a handle to the vertex column
        vdata = GeomVertexData('', format, Geom.UHStatic)
        vertices = GeomVertexWriter(vdata, 'vertex')

        # build a linestrip vertex buffer
        lines = GeomLinestrips(Geom.UHStatic)

        # draw a box
        if axis == "x":
            vertices.addData3f(0, -width, -height)
            vertices.addData3f(0, width, -height)
            vertices.addData3f(0, width, height)
            vertices.addData3f(0, -width, height)
        if axis == "y":
            vertices.addData3f(-width, 0, -height)
            vertices.addData3f(width, 0, -height)
            vertices.addData3f(width, 0, height)
            vertices.addData3f(-width, 0, height)
        if axis == "z":
            vertices.addData3f(-width, -height, 0)
            vertices.addData3f(width, -height, 0)
            vertices.addData3f(width, height, 0)
            vertices.addData3f(-width, height, 0)

        for i in range(1, 3):
            lines.addVertices(i - 1, i)
        lines.addVertices(3, 0)

        lines.closePrimitive()

        geom = Geom(vdata)
        geom.addPrimitive(lines)
        # Add our primitive to the geomnode
        self.gnode.addGeom(geom)

    def generate(self, type, radius=1.0, length=1.0, extents=Point3(1, 1, 1)):

        if type == 'sphere':
            # generate a simple sphere
            self.drawCircle(radius, "x", 0)
            self.drawCircle(radius, "y", 0)
            self.drawCircle(radius, "z", 0)

        if type == 'capsule':
            # generate a simple capsule
            self.drawCapsule(radius, length, "x")
            self.drawCapsule(radius, length, "y")
            self.drawCircle(radius, "z", -length / 2)
            self.drawCircle(radius, "z", length / 2)

        if type == 'box':
            # generate a simple box
            self.drawRect(extents[1], extents[2], "x")
            self.drawRect(extents[0], extents[2], "y")
            self.drawRect(extents[0], extents[1], "z")

        if type == 'cylinder':
            # generate a simple cylinder
            self.drawLine((0, -radius, -length / 2), (0, -radius, length / 2))
            self.drawLine((0, radius, -length / 2), (0, radius, length / 2))
            self.drawLine((-radius, 0, -length / 2), (-radius, 0, length / 2))
            self.drawLine((radius, 0, -length / 2), (radius, 0, length / 2))
            self.drawCircle(radius, "z", -length / 2)
            self.drawCircle(radius, "z", length / 2)

        if type == 'ray':
            # generate a ray
            self.drawCircle(length / 10, "x", 0)
            self.drawCircle(length / 10, "z", 0)
            self.drawLine((0, 0, 0), (0, 0, length))
            self.drawLine((0, 0, length), (0, -length / 10, length * 0.9))
            self.drawLine((0, 0, length), (0, length / 10, length * 0.9))

        if type == 'plane':
            # generate a plane
            length = 3.0
            self.drawRect(1.0, 1.0, "z")
            self.drawLine((0, 0, 0), (0, 0, length))
            self.drawLine((0, 0, length), (0, -length / 10, length * 0.9))
            self.drawLine((0, 0, length), (0, length / 10, length * 0.9))

        # rename ourselves to wirePrimBox, etc.
        name = self.gnode.getName()
        self.gnode.setName(name + type.capitalize())

        NP = NodePath(self.gnode)  # Finally, make a nodepath to our geom
        NP.setColor(0.0, 1.0, 0.0)  # Set default color

        return NP
Example #53
0
    def pandaRender(self):
        frameList = []
        for node in self.compositeFrames.getiterator('composite-frame'):
            if node.tag == "composite-frame" and node.attrib.get("id") == str(self.internalFrameIndex):
                for frameCallNode in node:
                    for frameNode in self.frames.getiterator('frame'):
                        if frameNode.tag == "frame" and frameNode.attrib.get("id") == frameCallNode.attrib.get("id"):
                            offsetX = 0 if frameCallNode.attrib.get("offset-x") == None else float(frameCallNode.attrib.get("offset-x"))
                            offsetY = 0 if frameCallNode.attrib.get("offset-y") == None else float(frameCallNode.attrib.get("offset-y"))
                            tweenId = frameCallNode.attrib.get("tween")
                            frameInTween = 0 if frameCallNode.attrib.get("frame-in-tween") == None else int(frameCallNode.attrib.get("frame-in-tween"))
                            addWidth = 0 if frameNode.attrib.get("w") == None else float(frameNode.attrib.get("w"))
                            addHeight = 0 if frameNode.attrib.get("h") == None else float(frameNode.attrib.get("h"))
                            sInPixels = 0 if frameNode.attrib.get("s") == None else float(frameNode.attrib.get("s"))
                            tInPixels = 0 if frameNode.attrib.get("t") == None else float(frameNode.attrib.get("t"))
                            swInPixels = sInPixels + addWidth
                            thInPixels = tInPixels + addHeight
                            s = (sInPixels / self.baseWidth)
                            t = 1 - (tInPixels / self.baseHeight) # Complemented to deal with loading image upside down.
                            S = (swInPixels / self.baseWidth)
                            T = 1 - (thInPixels / self.baseHeight) # Complemented to deal with loading image upside down.
                            blend = "overwrite" if frameCallNode.attrib.get("blend") == None else frameCallNode.attrib.get("blend")
                            scaleX = 1 if frameCallNode.attrib.get("scale-x") == None else float(frameCallNode.attrib.get("scale-x"))
                            scaleY = 1 if frameCallNode.attrib.get("scale-y") == None else float(frameCallNode.attrib.get("scale-y"))
                            color = Color(1,1,1,1)
                            tweenHasColor = False
                            frameCallHasColor = False
                            frameCallColorName = frameCallNode.attrib.get("color-name")
                            if frameCallColorName != None:
                                # Get color at frame call as first resort.
                                frameCallHasColor = True
                                for colorNode in self.colors.getiterator('color'):
                                    if colorNode.tag == 'color' and colorNode.attrib.get("name") == frameCallColorName:
                                        R = 1 if colorNode.attrib.get("r") == None else float(colorNode.attrib.get("r"))
                                        G = 1 if colorNode.attrib.get("g") == None else float(colorNode.attrib.get("g"))
                                        B = 1 if colorNode.attrib.get("b") == None else float(colorNode.attrib.get("b"))
                                        A = 1 if colorNode.attrib.get("a") == None else float(colorNode.attrib.get("a"))
                                        color = Color(R, G, B, A)
                                        break # leave for loop when we find the correct color
                                pass

                            if tweenId != None and tweenId != "0":
                                # Get color at tween frame as second resort.
                                thisTween = None
                                frameLength = 1
                                advancementFunction = "linear"
                                foundTween = False
                                pointList = []
                                colorList = []
                                for tweenNode in self.tweens.getiterator('motion-tween'):
                                    if tweenNode.tag == "motion-tween" and tweenNode.attrib.get("id") == tweenId:
                                        foundTween = True
                                        frameLength = 1 if tweenNode.attrib.get("length-in-frames") == None else tweenNode.attrib.get("length-in-frames")
                                        advancementFunction = "linear" if tweenNode.attrib.get("advancement-function") == None else tweenNode.attrib.get("advancement-function")
                                        for pointOrColorNode in tweenNode.getiterator():
                                            if pointOrColorNode.tag == "point":
                                                pX = 0 if pointOrColorNode.attrib.get("x") == None else float(pointOrColorNode.attrib.get("x"))
                                                pY = 0 if pointOrColorNode.attrib.get("y") == None else float(pointOrColorNode.attrib.get("y"))
                                                pointList.append(Point(pX, pY, 0))
                                            elif pointOrColorNode.tag == "color-state":
                                                colorName = "white" if pointOrColorNode.attrib.get("name") == None else pointOrColorNode.attrib.get("name")
                                                for colorNode in self.colors.getiterator('color'):
                                                    if colorNode.tag == 'color' and colorNode.attrib.get("name") == colorName:
                                                        R = 1 if colorNode.attrib.get("r") == None else float(colorNode.attrib.get("r"))
                                                        G = 1 if colorNode.attrib.get("g") == None else float(colorNode.attrib.get("g"))
                                                        B = 1 if colorNode.attrib.get("b") == None else float(colorNode.attrib.get("b"))
                                                        A = 1 if colorNode.attrib.get("a") == None else float(colorNode.attrib.get("a"))
                                                        colorList.append(Color(R, G, B, A))
                                                        break # leave for loop when we find the correct color reference
                                            pass # Run through all child nodes of selected tween
                                        break # Exit after finding correct tween
                                pass
                                if foundTween:
                                    thisTween = Tween(frameLength, advancementFunction, pointList, colorList)
                                    offset = thisTween.XYFromFrame(frameInTween);
                                    offsetFromTweenX = int(offset.X);
                                    offsetFromTweenY = int(offset.Y);
                                    offsetX += int(offset.X);
                                    offsetY += int(offset.Y);
                                    if thisTween.hasColorComponent():
                                        tweenHasColor = True;
                                        if frameCallHasColor == False:
                                            color = thisTween.colorFromFrame(frameInTween);
                                    pass
                            if frameNode.attrib.get("color-name") != None and frameCallHasColor == False and tweenHasColor == False:
                                # Get color at frame definition as last resort.
                                for colorNode in colors.getiterator('color'):
                                    if colorNode.tag == 'color' and colorNode.attrib.get("name") == frameNode.attrib.get("color-name"):
                                        R = 1 if colorNode.attrib.get("r") == None else float(colorNode.attrib.get("r"))
                                        G = 1 if colorNode.attrib.get("g") == None else float(colorNode.attrib.get("g"))
                                        B = 1 if colorNode.attrib.get("b") == None else float(colorNode.attrib.get("b"))
                                        A = 1 if colorNode.attrib.get("a") == None else float(colorNode.attrib.get("a"))
                                        color = Color(R, G, B, A)
                                        break # leave for loop when we find the correct color
                                pass
                            rotationZ = 0 if frameCallNode.attrib.get("rotation-z") == None else float(frameCallNode.attrib.get("rotation-z"))
                            frameList.append(Frame(Bound(offsetX, offsetY, addWidth, addHeight), s, t, S, T, blend, scaleX, scaleY, color, rotationZ))
                    pass 
                break # Leave once we've found the appropriate frame

        # Prepare tracking list of consumed nodes.
        self.clearNodesForDrawing()
        # Make an identifier to tack onto primitive names in Panda3d's scene graph.
        frameIndexForName = 1
                
        # Loop through loaded frames that make up composite frame.
        for loadedFrame in frameList:              
            # For debugging purposes, print the object.
            if False:
                loadedFrame.printAsString()
            
            # Set up place to store primitive 3d object; note: requires vertex data made by GeomVertexData
            squareMadeByTriangleStrips = GeomTristrips(Geom.UHDynamic)
              
            # Set up place to hold 3d data and for the following coordinates:
            #   square's points (V3: x, y, z), 
            #   the colors at each point of the square (c4: r, g, b, a), and
            #   for the UV texture coordinates at each point of the square     (t2: S, T).
            vertexData = GeomVertexData('square-'+str(frameIndexForName), GeomVertexFormat.getV3c4t2(), Geom.UHDynamic)
            vertex = GeomVertexWriter(vertexData, 'vertex')
            color = GeomVertexWriter(vertexData, 'color')
            texcoord = GeomVertexWriter(vertexData, 'texcoord') 
              
            # Add the square's data
            # Upper-Left corner of square
            vertex.addData3f(-loadedFrame.bound.Width / 2.0, 0, -loadedFrame.bound.Height / 2.0)
            color.addData4f(loadedFrame.color.R,loadedFrame.color.G,loadedFrame.color.B,loadedFrame.color.A)
            texcoord.addData2f(loadedFrame.s, loadedFrame.T)

            # Upper-Right corner of square
            vertex.addData3f(loadedFrame.bound.Width / 2.0, 0, -loadedFrame.bound.Height / 2.0)
            color.addData4f(loadedFrame.color.R,loadedFrame.color.G,loadedFrame.color.B,loadedFrame.color.A)
            texcoord.addData2f(loadedFrame.S, loadedFrame.T)
            
            # Lower-Left corner of square
            vertex.addData3f(-loadedFrame.bound.Width / 2.0, 0, loadedFrame.bound.Height / 2.0)
            color.addData4f(loadedFrame.color.R,loadedFrame.color.G,loadedFrame.color.B,loadedFrame.color.A)
            texcoord.addData2f(loadedFrame.s, loadedFrame.t)
            
            # Lower-Right corner of square
            vertex.addData3f(loadedFrame.bound.Width / 2.0, 0, loadedFrame.bound.Height / 2.0)
            color.addData4f(loadedFrame.color.R,loadedFrame.color.G,loadedFrame.color.B,loadedFrame.color.A)
            texcoord.addData2f(loadedFrame.S, loadedFrame.t)

            # Pass data to primitive
            squareMadeByTriangleStrips.addNextVertices(4)
            squareMadeByTriangleStrips.closePrimitive()
            square = Geom(vertexData)
            square.addPrimitive(squareMadeByTriangleStrips)
            # Pass primtive to drawing node
            drawPrimitiveNode=GeomNode('square-'+str(frameIndexForName))    
            drawPrimitiveNode.addGeom(square)
            # Pass node to scene (effect camera)
            nodePath = self.effectCameraNodePath.attachNewNode(drawPrimitiveNode)
            # Linear dodge:
            if loadedFrame.blendMode == "darken":
                nodePath.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OOneMinusFbufferColor, ColorBlendAttrib.OOneMinusIncomingColor))
                pass
            elif loadedFrame.blendMode == "multiply":
                nodePath.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OFbufferColor, ColorBlendAttrib.OZero))
                pass
            elif loadedFrame.blendMode == "color-burn":
                nodePath.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OZero, ColorBlendAttrib.OOneMinusIncomingColor))
                pass
            elif loadedFrame.blendMode == "linear-burn":
                nodePath.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OZero, ColorBlendAttrib.OIncomingColor))
                pass
            elif loadedFrame.blendMode == "lighten":
                nodePath.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MMax, ColorBlendAttrib.OIncomingColor, ColorBlendAttrib.OFbufferColor))
                pass
            elif loadedFrame.blendMode == "color-dodge":
                nodePath.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OOne, ColorBlendAttrib.OOne))
                pass
            elif loadedFrame.blendMode == "linear-dodge":
                nodePath.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OOne, ColorBlendAttrib.OOneMinusIncomingColor))
                pass
            else: # Overwrite:
                nodePath.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OIncomingAlpha, ColorBlendAttrib.OOneMinusIncomingAlpha))
                pass
            nodePath.setDepthTest(False)
            # Apply texture
            nodePath.setTexture(self.tex)
            # Apply translation, then rotation, then scaling to node.
            nodePath.setPos((loadedFrame.bound.X + loadedFrame.bound.Width / 2.0, 1, -loadedFrame.bound.Y - loadedFrame.bound.Height / 2.0))
            nodePath.setR(loadedFrame.rotationZ)
            nodePath.setScale(loadedFrame.scaleX, 1, loadedFrame.scaleY)
            nodePath.setTwoSided(True)
            self.consumedNodesList.append(nodePath)
            frameIndexForName = frameIndexForName + 1
        # Loop continues on through each frame called in the composite frame.
        pass
Example #54
0
    def draw(self):
        format = GeomVertexFormat.getV3n3cpt2()
        vdata = GeomVertexData('square', format, Geom.UHStatic)

        vertex = GeomVertexWriter(vdata, 'vertex')
        normal = GeomVertexWriter(vdata, 'normal')
        color = GeomVertexWriter(vdata, 'color')
        texcoord = GeomVertexWriter(vdata, 'texcoord')

        #make sure we draw the sqaure in the right plane
        #if x1!=x2:
        vertex.addData3f(self.x1, self.y1, self.z1)
        vertex.addData3f(self.x2, self.y1, self.z1)
        vertex.addData3f(self.x2, self.y2, self.z2)
        vertex.addData3f(self.x1, self.y2, self.z2)

        normal.addData3f(
            Vec3(2 * self.x1 - 1, 2 * self.y1 - 1,
                 2 * self.z1 - 1).normalize())
        normal.addData3f(
            Vec3(2 * self.x2 - 1, 2 * self.y1 - 1,
                 2 * self.z1 - 1).normalize())
        normal.addData3f(
            Vec3(2 * self.x2 - 1, 2 * self.y2 - 1,
                 2 * self.z2 - 1).normalize())
        normal.addData3f(
            Vec3(2 * self.x1 - 1, 2 * self.y2 - 1,
                 2 * self.z2 - 1).normalize())

        #adding different colors to the vertex for visibility
        color.addData4f(self.r, self.g, self.b, self.a)
        color.addData4f(self.r, self.g, self.b, self.a)
        color.addData4f(self.r, self.g, self.b, self.a)
        color.addData4f(self.r, self.g, self.b, self.a)

        texcoord.addData2f(0.0, 1.0)
        texcoord.addData2f(0.0, 0.0)
        texcoord.addData2f(1.0, 0.0)
        texcoord.addData2f(1.0, 1.0)

        #quads arent directly supported by the Geom interface
        #you might be interested in the CardMaker class if you are
        #interested in rectangle though
        tri1 = GeomTriangles(Geom.UHStatic)
        tri2 = GeomTriangles(Geom.UHStatic)

        tri1.addVertex(0)
        tri1.addVertex(1)
        tri1.addVertex(3)

        tri2.addConsecutiveVertices(1, 3)

        tri1.closePrimitive()
        tri2.closePrimitive()

        square = Geom(vdata)
        square.addPrimitive(tri1)
        square.addPrimitive(tri2)
        #square.setIntoCollideMask(BitMask32.bit(1))

        self.squareNP = NodePath(GeomNode('square gnode'))
        self.squareNP.node().addGeom(square)
        self.squareNP.setTransparency(1)
        self.squareNP.setAlphaScale(.5)
        self.squareNP.setTwoSided(True)
        #squareNP.setCollideMask(BitMask32.bit(1))
        self.squareNP.reparentTo(self.parent)

        return self.squareNP
Example #55
0
    def __setupCollisionHandling(self, collisionHandler, collisionTraverser):
        if not collisionTraverser.getRespectPrevTransform():
            collisionTraverser.setRespectPrevTransform(True)
            
        # We do this so we don't take into account the actual model, but the collision sphere
        self.actor.setCollideMask(BitMask32.allOff())
            
        self.node().getPhysicsObject().setMass(self.massKg) 
        base.physicsMgr.attachPhysicalNode(self.node())
        fromObject = self.attachNewNode(CollisionNode(self.name + " collision node"))
        fromObject.node().setIntoCollideMask(fromObject.node().getIntoCollideMask() & ~GeomNode.getDefaultCollideMask())
        fromObject.node().setFromCollideMask(self.collisionMask)
        fromObject.node().addSolid(CollisionSphere(0, 0, 2.5, 2.5))
        

        collisionHandler.addCollider(fromObject, self)
        collisionTraverser.addCollider(fromObject, collisionHandler)
Example #56
0
  def draw_body(self, position, vector_list, radius = 1, keep_drawing = True, num_vertices = 8):
    circle_geom = Geom(self.vdata)

    vertex_writer = GeomVertexWriter(self.vdata, "vertex")
    color_writer = GeomVertexWriter(self.vdata, "color")
    normal_writer = GeomVertexWriter(self.vdata, "normal")
    draw_rewriter = GeomVertexRewriter(self.vdata, "drawFlag")
    tex_rewriter = GeomVertexRewriter(self.vdata, "texcoord")

    start_row = self.vdata.getNumRows()
    vertex_writer.setRow(start_row)
    color_writer.setRow(start_row)
    normal_writer.setRow(start_row)

    sCoord = 0

    if start_row != 0:
      tex_rewriter.setRow(start_row - num_vertices)
      sCoord = tex_rewriter.getData2f().getX() + 1

      draw_rewriter.setRow(start_row - num_vertices)
      if draw_rewriter.getData1f() == False:
        sCoord -= 1

    draw_rewriter.setRow(start_row)
    tex_rewriter.setRow(start_row)

    angle_slice = 2 * math.pi / num_vertices
    current_angle = 0

    perp1 = vector_list[1]
    perp2 = vector_list[2]

    # write vertex information
    for i in range(num_vertices):
      adjacent_circle = position + (perp1 * math.cos(current_angle) + perp2 * math.sin(current_angle)) * radius
      normal = perp1 * math.cos(current_angle) + perp2 * math.sin(current_angle)
      normal_writer.addData3f(normal)
      vertex_writer.addData3f(adjacent_circle)
      tex_rewriter.addData2f(sCoord, (i + 0.001) / (num_vertices - 1))
      color_writer.addData4f(0.5, 0.5, 0.5, 1.0)
      draw_rewriter.addData1f(keep_drawing)
      current_angle += angle_slice

    draw_reader = GeomVertexReader(self.vdata, "drawFlag")
    draw_reader.setRow(start_row - num_vertices)

    # we can't draw quads directly so use Tristrips
    if start_row != 0 and draw_reader.getData1f() != False:
      lines = GeomTristrips(Geom.UHStatic)
      half = int(num_vertices * 0.5)
      for i in range(num_vertices):
        lines.addVertex(i + start_row)
        if i < half:
          lines.addVertex(i + start_row - half)
        else:
          lines.addVertex(i + start_row - half - num_vertices)

      lines.addVertex(start_row)
      lines.addVertex(start_row - half)
      lines.closePrimitive()
      lines.decompose()
      circle_geom.addPrimitive(lines)

      circle_geom_node = GeomNode("Debug")
      circle_geom_node.addGeom(circle_geom)

      circle_geom_node.setAttrib(CullFaceAttrib.makeReverse(), 1)

      self.get_model().attachNewNode(circle_geom_node)
Example #57
0
  def make_layer(self, i, a, b):
    # get data
    data = self.subdata[a][b]

    # set color + alpha of vertex texture
    def ap(n):
      alpha = 0
      if i == n:
        alpha = 1.0
      return alpha
    def tp(n):
      list = [0, 0, 0, 0]
      if i == n:
        list = [1, 1, 1, 0.75]
      return list

    # set vertex data
    vdata = GeomVertexData('plane', GeomVertexFormat.getV3n3c4t2(), Geom.UHStatic)
    vertex = GeomVertexWriter(vdata, 'vertex')
    normal = GeomVertexWriter(vdata, 'normal')
    color = GeomVertexWriter(vdata, 'color')
    uv = GeomVertexWriter(vdata, 'texcoord')

    # set vertices
    number = 0
    for x in range(0, len(data) - 1):
      for y in range(0, len(data[x]) - 1):
        # get vertex data
        v1 = Vec3(x, y, data[x][y]['h'])
        c1 = data[x][y]['c']
        t1 = data[x][y]['texnum']
        v2 = Vec3(x+1, y, data[x+1][y]['h'])
        c2 = data[x+1][y]['c']
        t2 = data[x+1][y]['texnum']
        v3 = Vec3(x+1, y+1, data[x+1][y+1]['h'])
        c3 = data[x+1][y+1]['c']
        t3 = data[x+1][y+1]['texnum']
        v4 = Vec3(x, y+1, data[x][y+1]['h'])
        c4 = data[x][y+1]['c']
        t4 = data[x][y+1]['texnum']
        n=(0, 0, 1) # normal

        # assign vertex colors + alpha
        a1, a2, a3, a4 = ap(t1), ap(t2), ap(t3), ap(t4)
        t1, t2, t3, t4 = tp(t1), tp(t2), tp(t3), tp(t4)

        if v1[2]==0:
          t1 = [data[x][y]['c'][0], data[x][y]['c'][1], data[x][y]['c'][2],
                a1]
        if v2[2]==0:
          t2 = [data[x+1][y]['c'][0], data[x+1][y]['c'][1],
                data[x+1][y]['c'][2], a2]
        if v3[2]==0:
          t3 = [data[x+1][y+1]['c'][0], data[x+1][y+1]['c'][1],
                data[x+1][y+1]['c'][2], a3]
        if v4[2]==0:
          t4 = [data[x][y+1]['c'][0], data[x][y+1]['c'][1],
                data[x][y+1]['c'][2], a4]

        if a1 == 0 and a2 == 0 and a3 == 0 and a4 == 0:
          continue

        # add vertices
        vertex.addData3f(v1)
        normal.addData3f(*n)
        color.addData4f(*t1)
        uv.addData2f(0,0)

        vertex.addData3f(v2)
        normal.addData3f(*n)
        color.addData4f(*t2)
        uv.addData2f(1,0)

        vertex.addData3f(v3)
        normal.addData3f(*n)
        color.addData4f(*t3)
        uv.addData2f(1,1)

        vertex.addData3f(v1)
        normal.addData3f(*n)
        color.addData4f(*t1)
        uv.addData2f(0,0)

        vertex.addData3f(v3)
        normal.addData3f(*n)
        color.addData4f(*t3)
        uv.addData2f(1,1)

        vertex.addData3f(v4)
        normal.addData3f(*n)
        color.addData4f(*t4)
        uv.addData2f(0,1)

        number = number + 2

    # add triangles
    prim = GeomTriangles(Geom.UHStatic)
    for n in range(number):
      prim.addVertices((n * 3) + 2, (n * 3) + 0, (n * 3) + 1)
    prim.closePrimitive()

    # make geom
    geom = Geom(vdata)
    geom.addPrimitive(prim)

    # make geom node
    node = GeomNode("layer" + str(i) + "_" + str(a) + "_" + str(b))
    node.addGeom(geom)

    # make mesh nodePath
    mesh = NodePath(node)

    # load and assign texture
    txfile = self.tiles[i]['tex']
    tx = base.loader.loadTexture(txfile)
    tx.setMinfilter(Texture.FTLinearMipmapLinear)
    mesh.setDepthTest(DepthTestAttrib.MLessEqual)
    mesh.setDepthWrite(False)
    mesh.setTransparency(True)
    mesh.setTexture(tx)

    # set render order
    mesh.setBin("", 1)

    # locate mesh
    mesh.setPos(self.divsep * (a * int(len(self.data[a]) / self.div)),
                self.divsep * (b * int(len(self.data[b]) / self.div)), 0.001)

    # reparent mesh
    mesh.reparentTo(self.root)

    # return mesh
    return mesh
Example #58
0
  def make_base(self, a, b):
    # get data
    data = self.subdata[a][b]
    # set vertex data
    vdata = GeomVertexData('plane', GeomVertexFormat.getV3n3c4t2(), Geom.UHStatic)
    vertex = GeomVertexWriter(vdata, 'vertex')
    normal = GeomVertexWriter(vdata, 'normal')
    color = GeomVertexWriter(vdata, 'color')
    uv = GeomVertexWriter(vdata, 'texcoord')

    # set vertices
    number = 0
    for x in range(0, len(data) - 1):
      for y in range(0, len(data[x]) - 1):
        # get vertex data
        v1 = Vec3(x, y, data[x][y]['h'])
        v2 = Vec3(x + 1, y, data[x+1][y]['h'])
        v3 = Vec3(x + 1, y + 1, data[x+1][y+1]['h'])
        v4 = Vec3(x, y + 1, data[x][y+1]['h'])
        n = (0, 0, 1) # normal

        # assign vertex colors + alpha
        option = 1 # black
        if option == 1:
          c = 0
          c1 = [c, c, c, 1]
          c2 = [c, c, c, 1]
          c3 = [c, c, c, 1]
          c4 = [c, c, c, 1]
        # option2: color vertices
        if option == 2:
          alpha = 1.0
          c1 = [data[x][y]['c'][0], data[x][y]['c'][1],
                data[x][y]['c'][2], alpha]
          c2 = [data[x+1][y]['c'][0], data[x+1][y]['c'][1],
                data[x+1][y]['c'][2], alpha]
          c3 = [data[x+1][y+1]['c'][0], data[x+1][y+1]['c'][1],
                data[x+1][y+1]['c'][2], alpha]
          c4 = [data[x][y+1]['c'][0], data[x][y+1]['c'][1],
                data[x][y+1]['c'][2], alpha]

        if option == 3:
          c1 = self.color_vertex(v1)
          c2 = self.color_vertex(v2)
          c3 = self.color_vertex(v3)
          c4 = self.color_vertex(v4)

        vertex.addData3f(v1)
        normal.addData3f(*n)
        color.addData4f(*c1)
        uv.addData2f(0,0)

        vertex.addData3f(v2)
        normal.addData3f(*n)
        color.addData4f(*c2)
        uv.addData2f(1,0)

        vertex.addData3f(v3)
        normal.addData3f(*n)
        color.addData4f(*c3)
        uv.addData2f(1,1)

        vertex.addData3f(v1)
        normal.addData3f(*n)
        color.addData4f(*c1)
        uv.addData2f(0,0)

        vertex.addData3f(v3)
        normal.addData3f(*n)
        color.addData4f(*c3)
        uv.addData2f(1,1)

        vertex.addData3f(v4)
        normal.addData3f(*n)
        color.addData4f(*c4)
        uv.addData2f(0,1)

#         # add vertex h
#         vertex.addData3f(v1)
#         # normal.addData3f(*n)
#         vertex.addData3f(v2)
#         # normal.addData3f(*n)
#         vertex.addData3f(v3)
#         # normal.addData3f(*n)
#         vertex.addData3f(v1)
#         # normal.addData3f(*n)
#         vertex.addData3f(v3)
#         # normal.addData3f(*n)
#         vertex.addData3f(v4)
#         # normal.addData3f(*n)
#         # add vertex color
#         color.addData4f(*c1)
#         color.addData4f(*c2)
#         color.addData4f(*c3)
#         color.addData4f(*c1)
#         color.addData4f(*c3)
#         color.addData4f(*c4)

        # iterate
        number = number + 2

    # add triangles
    prim = GeomTriangles(Geom.UHStatic)
    for n in range(number):
      prim.addVertices((n * 3) + 2, (n * 3) + 0, (n * 3) + 1)
    prim.closePrimitive()

    # make geom
    geom = Geom(vdata)
    geom.addPrimitive(prim)

    # make geom node
    node = GeomNode("base" + "_" + str(a) + "_" + str(b))
    node.addGeom(geom)

    # make mesh nodePath
    mesh = NodePath(node)
    # set render order
    mesh.setBin("", 1)

    # locate mesh
    mesh.setPos(self.divsep * (a * int(len(self.data[a]) / self.div)),
                self.divsep * (b * int(len(self.data[b]) / self.div)), 0)

    # reparent mesh
    mesh.reparentTo(self.root)

    # return mesh
    return mesh