예제 #1
0
def make_plane(size=(1.0, 1.0)):
    """Make a plane geometry.

    Arguments:
        size {tuple} -- plane size x,y

    Returns:
        Geom -- p3d geometry
    """
    vformat = GeomVertexFormat.get_v3n3t2()
    vdata = GeomVertexData('vdata', vformat, Geom.UHStatic)
    vdata.uncleanSetNumRows(4)

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

    quad = ((0, 0), (1, 0), (0, 1), (1, 1))

    for u, v in quad:
        vertex.addData3((u - 0.5) * size[0], (v - 0.5) * size[1], 0)
        normal.addData3(0, 0, 1)
        tcoord.addData2(u, v)

    prim = GeomTriangles(Geom.UHStatic)
    prim.addVertices(0, 1, 2)
    prim.addVertices(2, 1, 3)

    geom = Geom(vdata)
    geom.addPrimitive(prim)
    return geom
예제 #2
0
def make_box():
    """Make a uniform box geometry.

    Returns:
        Geom -- p3d geometry
    """
    vformat = GeomVertexFormat.get_v3n3t2()
    vdata = GeomVertexData('vdata', vformat, Geom.UHStatic)
    vdata.uncleanSetNumRows(24)

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

    axes = itertools.permutations(np.eye(3), r=2)
    quad = ((0, 0), (1, 0), (0, 1), (1, 1))

    for x, y in axes:
        z = np.cross(x, y)
        for u, v in quad:
            vertex.addData3(*(x * (u - 0.5) + y * (v - 0.5) + z * 0.5))
            normal.addData3(*z)
            tcoord.addData2(u, v)

    prim = GeomTriangles(Geom.UHStatic)
    for i in range(0, 24, 4):
        prim.addVertices(i + 0, i + 1, i + 2)
        prim.addVertices(i + 2, i + 1, i + 3)

    geom = Geom(vdata)
    geom.addPrimitive(prim)
    return geom
예제 #3
0
    def _get_geom_data_plate(build_plate_size: LVector2d,
                             name: str = "") -> GeomVertexData:
        """Generate build plate GeomVertexData.

        Parameters
        ----------
        build_plate_size : LVector2d
            Build plate size.
        name : str
            Name for the generated GeomVertexData.
        """
        # noinspection PyArgumentList
        geom_data = GeomVertexData(name, GeomVertexFormat.get_v3t2(),
                                   Geom.UHStatic)
        geom_data.setNumRows(4)

        writer_vertex = GeomVertexWriter(geom_data, "vertex")
        writer_texture = GeomVertexWriter(geom_data, "texcoord")

        # Add build plate vertices
        writer_vertex.addData3d(0, 0, 0)
        writer_vertex.addData3d(build_plate_size.x, 0, 0)
        writer_vertex.addData3d(build_plate_size.x, build_plate_size.y, 0)
        writer_vertex.addData3d(0, build_plate_size.y, 0)

        for uv in [(0, 0), (1, 0), (1, 1), (0, 1)]:
            writer_texture.addData2(*uv)

        return geom_data
예제 #4
0
def make_capsule(radius, length, num_segments=16, num_rings=16):
    """Make capsule geometry.

    Arguments:
        radius {float} -- capsule radius
        length {float} -- capsule length

    Keyword Arguments:
        num_segments {int} -- segments number (default: {16})
        num_rings {int} -- rings number (default: {16})

    Returns:
        Geom -- p3d geometry
    """
    vformat = GeomVertexFormat.get_v3n3t2()
    vdata = GeomVertexData('vdata', vformat, Geom.UHStatic)
    vdata.uncleanSetNumRows(num_segments * num_rings)

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

    for u in np.linspace(0, np.pi, num_rings):
        for v in np.linspace(0, 2 * np.pi, num_segments):
            x, y, z = np.cos(v) * np.sin(u), np.sin(v) * np.sin(u), np.cos(u)
            offset = np.sign(z) * 0.5 * length
            vertex.addData3(x * radius, y * radius, z * radius + offset)
            normal.addData3(x, y, z)
            tcoord.addData2(u / np.pi, v / (2 * np.pi))

    prim = GeomTriangles(Geom.UHStatic)
    for i in range(num_rings - 1):
        for j in range(num_segments - 1):
            r0 = i * num_segments + j
            r1 = r0 + num_segments
            if i < num_rings - 2:
                prim.addVertices(r0, r1, r1 + 1)
            if i > 0:
                prim.addVertices(r0, r1 + 1, r0 + 1)

    geom = Geom(vdata)
    geom.addPrimitive(prim)
    return geom
예제 #5
0
def make_cylinder(num_segments=16, closed=True):
    """Make a uniform cylinder geometry.

    Keyword Arguments:
        num_segments {int} -- segments number (default: {16})
        closed {bool} -- add caps (default: {True})

    Returns:
        Geom -- p3d geometry
    """
    vformat = GeomVertexFormat.get_v3n3t2()
    vdata = GeomVertexData('vdata', vformat, Geom.UHStatic)

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

    cyl_rows = num_segments * 2
    cap_rows = num_segments + 1
    if closed:
        vdata.uncleanSetNumRows(cyl_rows + 2 * cap_rows)
    else:
        vdata.uncleanSetNumRows(cyl_rows)

    for phi in np.linspace(0, 2 * np.pi, num_segments):
        x, y = np.cos(phi), np.sin(phi)
        for z in (-1, 1):
            vertex.addData3(x, y, z * 0.5)
            normal.addData3(x, y, 0)
            tcoord.addData2(phi / (2 * np.pi), (z + 1) / 2)

    prim = GeomTriangles(Geom.UHStatic)
    for i in range(num_segments - 1):
        prim.addVertices(i * 2, i * 2 + 3, i * 2 + 1)
        prim.addVertices(i * 2, i * 2 + 2, i * 2 + 3)

    if closed:
        for z in (-1, 1):
            vertex.addData3(0, 0, z * 0.5)
            normal.addData3(0, 0, z)
            tcoord.addData2(0, 0)

            for phi in np.linspace(0, 2 * np.pi, num_segments):
                x, y = np.cos(phi), np.sin(phi)
                vertex.addData3(x, y, z * 0.5)
                normal.addData3(0, 0, z)
                tcoord.addData2(x, y)

        for i in range(num_segments):
            r0 = cyl_rows
            r1 = r0 + cap_rows
            prim.addVertices(r0, r0 + i + 1, r0 + i)
            prim.addVertices(r1, r1 + i, r1 + i + 1)

    geom = Geom(vdata)
    geom.addPrimitive(prim)
    return geom
예제 #6
0
    def gen_geom(self, mesh_json):
        # Create vertex format
        geom_array = GeomVertexArrayFormat()
        geom_array.add_column("vertex", 3, Geom.NTFloat32, Geom.CPoint)
        has_normals = False
        has_texcoords = False
        has_weights = False
        if "normals" in mesh_json:
            geom_array.add_column("normal", 3, Geom.NTFloat32, Geom.CNormal)
            has_normals = True
        if "texcoords" in mesh_json:
            geom_array.add_column("texcoord", 3, Geom.NTFloat32,
                                  Geom.CTexcoord)
            has_texcoords = True
        if "weights" in mesh_json:
            geom_array.add_column("joint", 4, Geom.NTUint8, Geom.CIndex)
            geom_array.add_column("weight", 4, Geom.NTFloat32, Geom.COther)
            has_weights = True
        geom_format = GeomVertexFormat()
        geom_format.add_array(geom_array)
        geom_format = GeomVertexFormat.register_format(geom_format)

        # Set up vertex data
        vdata = GeomVertexData(
            str(random.randint(0, 255)) + "_vdata", geom_format, Geom.UHStatic)
        vcount = len(mesh_json["vertices"]) // 3
        vdata.setNumRows(vcount)
        vertex = GeomVertexWriter(vdata, "vertex")

        for i in range(vcount):
            vertex.addData3(mesh_json["vertices"][3 * i],
                            mesh_json["vertices"][3 * i + 1],
                            mesh_json["vertices"][3 * i + 2])
        if has_normals:
            normal = GeomVertexWriter(vdata, "normal")
            for i in range(vcount):
                normal.addData3(mesh_json["normals"][3 * i],
                                mesh_json["normals"][3 * i + 1],
                                mesh_json["normals"][3 * i + 2])
        if has_texcoords:
            texcoord = GeomVertexWriter(vdata, "texcoord")
            for i in range(vcount):
                texcoord.addData2(mesh_json["texcoords"][2 * i],
                                  mesh_json["texcoords"][2 * i + 1])
        if has_weights:
            joint = GeomVertexWriter(vdata, "joint")
            weight = GeomVertexWriter(vdata, "weight")
            for i in range(vcount):
                joint_count = len(mesh_json["joints"][i])
                joint.addData4(
                    0 if joint_count < 1 else mesh_json["joints"][i][0],
                    0 if joint_count < 2 else mesh_json["joints"][i][1],
                    0 if joint_count < 3 else mesh_json["joints"][i][2],
                    0 if joint_count < 4 else mesh_json["joints"][i][3])
                weight.addData4(
                    0 if joint_count < 1 else mesh_json["weights"][i][0],
                    0 if joint_count < 2 else mesh_json["weights"][i][1],
                    0 if joint_count < 3 else mesh_json["weights"][i][2],
                    0 if joint_count < 4 else mesh_json["weights"][i][3])

        # Create primitive
        prim = GeomTriangles(Geom.UHStatic)
        for i in range(vcount // 3):
            prim.addVertices(3 * i, 3 * i + 1, 3 * i + 2)
        geom = Geom(vdata)
        geom.add_primitive(prim)

        # Load texture
        tex = None
        if "texture" in mesh_json:
            tex = Loader(EComponent.base).loadTexture(
                (Path("resources") / mesh_json["texture"]).absolute())
            tex.setMagfilter(SamplerState.FT_nearest)
            tex.setMinfilter(SamplerState.FT_nearest)

        # Create new geometry node
        geom_node = GeomNode(str(random.randint(0, 255)) + "_node")
        if tex is None:
            geom_node.addGeom(geom)
        else:
            attrib = TextureAttrib.make(tex)
            state = RenderState.make(attrib)
            geom_node.addGeom(geom, state)
        if EComponent.panda_root_node is not None:
            self.geom_path = EComponent.panda_root_node.attach_new_node(
                geom_node)
            self.geom_path.set_shader_input("object_id", self.object_id)

        # Set shader
        if has_weights and self.geom_path is not None:
            self.geom_path.setTag("shader type", "skinned")
            bone_mats = PTA_LMatrix4f()
            for _ in range(100):
                bone_mats.push_back(helper.np_mat4_to_panda(np.identity(4)))
            self.geom_path.set_shader_input(f"boneMats", bone_mats)

            # Disable culling
            self.geom_path.node().setBounds(OmniBoundingVolume())
            self.geom_path.node().setFinal(True)
예제 #7
0
class RoadBuilder():
    def __init__(self):
        self.debugSphere = render.find("scene.dae").find("Scene").find(
            "debug_sphere")
        self.debugVector = render.find("scene.dae").find("Scene").find(
            "debug_vector")

        self.vdata = GeomVertexData('road', GeomVertexFormat.getV3t2(),
                                    Geom.UHStatic)
        # TODO: call this with right number of rows when it is known
        # self.vdata.setNumRows()
        self.vertex = GeomVertexWriter(self.vdata, 'vertex')
        self.texcoord = GeomVertexWriter(self.vdata, 'texcoord')
        self.prim = None
        self.prims = []
        self.lastv = 0
        self.vertices = []

        self.lru_vertices = []

    def addPrim(self):
        if self.prim is not None:
            for vertex in self.vertices:
                self.prim.addVertex(vertex)

            self.prims.append(self.prim)

        self.prim = GeomTriangles(Geom.UHStatic)

    def snapToExisting(self, point, tolerance=0.1):
        CACHE_SIZE = 1024

        for i in self.lru_vertices:
            if (point - i).length() < tolerance:
                return i

        self.lru_vertices.append(point)

        if len(self.lru_vertices) > CACHE_SIZE:
            self.lru_vertices = self.lru_vertices[0:CACHE_SIZE]

        return point

    def updateTask(self, dt):
        self.nodepath.setShaderInput("time", (globalClock.getFrameTime()))
        return Task.cont

    def addSegment(self, p0, p1):

        width = HALF_ROAD_WIDTH

        side = -(p1 - p0).cross(Vec3().up()).normalized() * width
        length = (p1 - p0)

        h = (p1 - p0).length()

        v1 = side
        v2 = side + length
        v3 = -side + length
        v4 = -side

        v1 += p0
        v2 += p0
        v3 += p0
        v4 += p0

        v1 = self.snapToExisting(v1)
        v2 = self.snapToExisting(v2)
        v3 = self.snapToExisting(v3)
        v4 = self.snapToExisting(v4)

        self.vertex.addData3(v1)
        self.texcoord.addData2(1, 0)

        self.vertex.addData3(v2)
        self.texcoord.addData2(1, 1)

        self.vertex.addData3(v3)
        self.texcoord.addData2(0, 1)

        self.vertex.addData3(v4)
        self.texcoord.addData2(0, 0)

        lastv = self.lastv
        self.vertices.append(0 + lastv)
        self.vertices.append(1 + lastv)
        self.vertices.append(2 + lastv)
        self.vertices.append(3 + lastv)
        self.vertices.append(2 + lastv)
        self.vertices.append(0 + lastv)

        self.lastv += 4

    def finish(self):
        self.geom = Geom(self.vdata)

        for prim in self.prims:
            self.geom.addPrimitive(prim)

        self.road_visual_node = GeomNode('road_node')
        visnode = self.road_visual_node
        visnode.addGeom(self.geom)

        self.road_visual_nodePath = render.attachNewNode(visnode)
        nodepath = self.road_visual_nodePath
        nodepath.setTwoSided(True)
        nodepath.setShader(
            Shader.load(Shader.SL_GLSL,
                        vertex="shaders/road.vert",
                        fragment="shaders/road.frag"))
        pleaseMakeTransparent(nodepath)
        self.nodepath = nodepath
        taskMgr.add(self.updateTask, "updateTask")

        self.lru_vertices = []
예제 #8
0
    def __init__(self):
        ShowBase.__init__(self)
        props = WindowProperties()
        props.setTitle("The Rat Cave")
        self.win.requestProperties(props)
        self.win.setClearColor((0.5, 0.5, 0.9, 1.0))
        self.disableMouse()
        self.locked = False
        lens = PerspectiveLens()
        lens.set_fov(70)
        self.cam.node().setLens(lens)
        self.position = [30, 30, 30]
        self.velocity = [0, 0, 0]
        self.setFrameRateMeter(True)
        self.myFog = Fog("Fog Name")
        self.myFog.setColor(0.5, 0.5, 0.9)
        self.myFog.setExpDensity(0.005)
        render.setFog(self.myFog)
        #cool bg
        #b=OnscreenImage(parent=render2d, image="space.png")
        #base.cam.node().getDisplayRegion(0).setSort(20)

        render.setAntialias(AntialiasAttrib.MMultisample)

        debugNode = BulletDebugNode('Debug')
        debugNode.showWireframe(True)
        debugNode.showConstraints(True)
        debugNode.showBoundingBoxes(False)
        debugNode.showNormals(False)
        debugNP = render.attachNewNode(debugNode)
        debugNP.show()

        self.world = BulletWorld()
        self.world.setGravity(Vec3(0, 0, -80))
        #self.world.setDebugNode(debugNP.node())

        loader = Loader(self)
        myShader = Shader.load(Shader.SL_GLSL,
                               vertex="vertshader.vert",
                               fragment="fragshader.frag")
        floorMesh = BulletTriangleMesh()

        texs = [
            loader.loadTexture("flatstone.png"),
            loader.loadTexture("flatstone2.png"),
            loader.loadTexture("flatgrass.png"),
            loader.loadTexture("flatgrass2.png"),
            loader.loadTexture("flatrock.png"),
            loader.loadTexture("flatrock2.png"),
            loader.loadTexture("flatsnow.png"),
            loader.loadTexture("flatsand.png"),
            loader.loadTexture("flatsand2.png")
        ]
        hmap = generator.generate(200, 200, 50, 0.01, 5)
        groundTypes = [[] for x in range(9)]
        for thing in hmap:
            groundTypes[thing[3]].append(thing[0:3])
        for i in range(len(groundTypes)):
            if len(groundTypes[i]) == 0:
                continue
            format = GeomVertexFormat.get_v3n3t2()
            format = GeomVertexFormat.registerFormat(format)
            vdata = GeomVertexData('name', format, Geom.UHStatic)
            vdata.setNumRows(3)
            vertex = GeomVertexWriter(vdata, 'vertex')
            normal = GeomVertexWriter(vdata, 'normal')
            texcoord = GeomVertexWriter(vdata, 'texcoord')
            prim = GeomTriangles(Geom.UHStatic)
            for grid in groundTypes[i]:
                v0 = (grid[0][0], grid[0][2], grid[0][1])
                vertex.addData3(v0)
                if grid[1][2] < 0:
                    normal.addData3(grid[1][0], grid[1][2], grid[1][1])
                else:
                    normal.addData3(-grid[1][0], -grid[1][2], -grid[1][1])
                texcoord.addData2(grid[2][0], grid[2][1])
                v1 = (grid[0][3], grid[0][5], grid[0][4])
                vertex.addData3(v1)
                if grid[1][5] < 0:
                    normal.addData3(grid[1][3], grid[1][5], grid[1][4])
                else:
                    normal.addData3(-grid[1][3], -grid[1][5], -grid[1][4])
                texcoord.addData2(grid[2][2], grid[2][3])
                v2 = (grid[0][6], grid[0][8], grid[0][7])
                vertex.addData3(v2)
                if grid[1][8] < 0:
                    normal.addData3(grid[1][6], grid[1][8], grid[1][7])
                else:
                    normal.addData3(-grid[1][6], -grid[1][8], -grid[1][7])
                texcoord.addData2(grid[2][4], grid[2][5])
                floorMesh.addTriangle(v0, v1, v2)
                prim.add_next_vertices(3)
            geom = Geom(vdata)
            geom.addPrimitive(prim)
            node = GeomNode('gnode')
            node.addGeom(geom)
            nodePath = render.attachNewNode(node)
            nodePath.setTexture(texs[i])
            nodePath.setShader(myShader)
        vdata2 = GeomVertexData('wata', format, Geom.UHStatic)
        vdata2.setNumRows(3)
        prim2 = GeomTriangles(Geom.UHStatic)
        vertex2 = GeomVertexWriter(vdata2, 'vertex')
        normal2 = GeomVertexWriter(vdata2, 'normal')
        texcoord2 = GeomVertexWriter(vdata2, 'texcoord')
        vertex2.addData3((0, 0, 0))
        vertex2.addData3((200, 0, 0))
        vertex2.addData3((0, 200, 0))
        normal2.addData3((0, 0, 1))
        normal2.addData3((0, 0, 1))
        normal2.addData3((0, 0, 1))
        texcoord2.addData2((0, 0))
        texcoord2.addData2((1, 0))
        texcoord2.addData2((0, 1))
        prim2.addNextVertices(3)
        vertex2.addData3((200, 200, 0))
        vertex2.addData3((0, 200, 0))
        vertex2.addData3((200, 0, 0))
        normal2.addData3((0, 0, 1))
        normal2.addData3((0, 0, 1))
        normal2.addData3((0, 0, 1))
        texcoord2.addData2((1, 1))
        texcoord2.addData2((0, 1))
        texcoord2.addData2((1, 0))
        prim2.addNextVertices(3)
        water = Geom(vdata2)
        water.addPrimitive(prim2)
        waterNode = GeomNode('water')
        waterNode.addGeom(water)
        waterNodePath = render.attachNewNode(waterNode)
        waterNodePath.setTransparency(True)
        waterNodePath.setTexture(loader.loadTexture("water.png"))
        floorMeshShape = BulletTriangleMeshShape(floorMesh, dynamic=False)
        fNode = BulletRigidBodyNode('floor')
        fNode.addShape(floorMeshShape)
        self.floorPhysNode = render.attachNewNode(fNode)
        self.world.attachRigidBody(fNode)
        for i in range(25):
            rat = loader.loadModel("deer.obj")
            rat.setScale((0.003, 0.003, 0.003))
            rat.setHpr((0, 90, 0))
            rat.setPos((0, 0, -0.8))
            rat.setTexture(texs[5])

            shape = BulletSphereShape(1)
            node = BulletRigidBodyNode('ratBox')
            #node.setAngularFactor((0,0,1))
            node.setMass(10.0)
            node.addShape(shape)
            node.setActive(False)
            #node.friction = 1
            np = render.attachNewNode(node)
            np.setPos((i % 5) * 2 + 40, int(i / 5) * 2 + 40, 50)
            self.world.attachRigidBody(node)
            rat.flattenLight()
            rat.reparentTo(np)
            #posInterval1 = rat.hprInterval(0.1,
            #							 Point3(10, 90, 0),
            #							 startHpr=Point3(-10, 90, 0))
            #posInterval2 = rat.hprInterval(0.1,
            #							 Point3(-10, 90, 0),
            #							 startHpr=Point3(10,90,0))
            #pandaPace = Sequence(posInterval1, posInterval2,
            #						  name="pandaPace" + str(i))
            #pandaPace.loop()
            self.ratto = np
        self.deer = loader.loadModel("rat.obj")
        self.deer.setScale((0.15, 0.15, 0.15))
        self.deer.setHpr((0, 90, 0))
        self.deer.setPos((0, 0, -2))
        self.deerShape = BulletBoxShape((3, 1, 3))
        self.deerNode = BulletRigidBodyNode('deerBox')
        self.deerNode.setAngularFactor((0, 0, 1))
        self.deerNode.setMass(10.0)
        self.deerNode.setFriction(1)
        self.deerNode.addShape(self.deerShape)
        self.deerNodePath = render.attachNewNode(self.deerNode)
        self.deerNodePath.setPos((30, 30, 130))
        self.world.attachRigidBody(self.deerNode)
        self.deer.reparentTo(self.deerNodePath)

        self.keyMap = {
            "w": False,
            "s": False,
            "a": False,
            "d": False,
            "space": False,
            "lshift": False,
            "p": False,
            "o": False
        }
        self.accept("w", self.setKey, ["w", True])
        self.accept("s", self.setKey, ["s", True])
        self.accept("a", self.setKey, ["a", True])
        self.accept("d", self.setKey, ["d", True])
        self.accept("space", self.setKey, ["space", True])
        self.accept("lshift", self.setKey, ["lshift", True])
        self.accept("e", self.lockMouse)
        self.accept("p", self.setKey, ["p", True])
        self.accept("o", self.setKey, ["o", True])

        self.accept("w-up", self.setKey, ["w", False])
        self.accept("s-up", self.setKey, ["s", False])
        self.accept("a-up", self.setKey, ["a", False])
        self.accept("d-up", self.setKey, ["d", False])
        self.accept("space-up", self.setKey, ["space", False])
        self.accept("lshift-up", self.setKey, ["lshift", False])
        self.accept("e-up", self.setKey, ["e", False])
        self.accept('escape', sys.exit)
        self.accept("p-up", self.setKey, ["p", False])
        self.accept("o-up", self.setKey, ["o", False])

        # Add the spinCameraTask procedure to the task manager.
        self.taskMgr.add(self.cameraControl, "CameraControl")

        self.camera.setPos(tuple(self.position))