Ejemplo n.º 1
0
    def _gen_faces(self):

        gen_timer = Timer("Gen Timer")

        gen_timer.start()

        self._top =     SphereQuad('T', self, self, radius=self._radius, density=self._density, face=CubeSphereMap.TOP)
        self._bottom =  SphereQuad('U', self, self, radius=self._radius, density=self._density, face=CubeSphereMap.BOTTOM)
        self._front =   SphereQuad('F', self, self, radius=self._radius, density=self._density, face=CubeSphereMap.FRONT)
        self._back =    SphereQuad('B', self, self, radius=self._radius, density=self._density, face=CubeSphereMap.BACK)
        self._left =    SphereQuad('L', self, self, radius=self._radius, density=self._density, face=CubeSphereMap.LEFT)
        self._right =   SphereQuad('R', self, self, radius=self._radius, density=self._density, face=CubeSphereMap.RIGHT)
        
        self.transform.add_child(self._top.transform)
        self.transform.add_child(self._bottom.transform)
        self.transform.add_child(self._front.transform)
        self.transform.add_child(self._back.transform)
        self.transform.add_child(self._left.transform)
        self.transform.add_child(self._right.transform)
        
        self._top._init_quad()
        self._bottom._init_quad()
        self._front._init_quad()
        self._back._init_quad()
        self._left._init_quad()
        self._right._init_quad()

        gen_timer.stop()
        gen_timer.elapsed()
Ejemplo n.º 2
0
class PlanetSphere(Node):
    def __init__(self, pos=Vector3(0,0,0), radius=150.0, density=16): #6.328
        Node.__init__(self)
        
        self._name = "planet_root"

        self.transform.position = pos

        # The mesh density
        self._density = density
        
        # The camera position in sphere-space coordinates
        self._camera_pos = pos
        self._camera_pos_sc = None
        self._radius = radius
        self._horizon = 0.0
        
        self._max_depth = 8
        
        #self._camera_gizmo = WireSphere(radius=0.1)
        #self.transform.add_child(self._camera_gizmo.transform)
        
        self._camera_gizmo = GizmoManager.draw_sphere(Vector3(), radius=0.2)
        
        # The maximum height of the sphere surface (above the radius)
        self._max_height = (radius * 0.05) #0.02
        self._split_factor = 1.1  #16
        self._split_power = 1.1 #1.25
        
        self._horizon = 0
        
        self._ui = PlanetSphereDebugWindow()
        
        # Number splits this frame
        self._num_splits = 0
        # Max number of splits per frame
        self._max_splits = 8
        
#        pos = self.transform.position
#        pos.y += 0.1
#        self.transform.position.y = 1.0
#        self._line = Line(Vector3(0,1,0), Vector3(0, 0, 0), 5.0)
#        self.transform.add_child(self._line.transform)

        self._line = GizmoManager.draw_line(Vector3(-1,0,0), Vector3(0,0,0), 5.0)
        
#        self._cube_pos = Line(self.transform.position, Vector3(0, 0, 0), 5.0)
#        self.transform.add_child(self._cube_pos.transform)
        
        self._camera = None
        self._last_camera_pos = None
        self._last_time = datetime.now()
        
        self._generator = SphereSurface(self._density, self._radius, self._max_height)

        # Create the faces of the planet
        self._gen_faces()

        # Generate a texture for the plane
        #root_trans = SceneManager.get_instance().current_scene.root.transform
        #test_plane = root_trans.get_child_with_name("test_plane", True).node
        #test_plane.renderer.material.texture = self._generator.get_texture("B", 128)

        # test_plane = root_trans.get_child_with_name("test_plane_right", True).node
        # test_plane.renderer.material.texture = self._generator.get_texture("R", 128)

        # test_plane = root_trans.get_child_with_name("test_plane_left", True).node
        # test_plane.renderer.material.texture = self._generator.get_texture("L", 128)

        # test_plane = root_trans.get_child_with_name("test_plane_front", True).node
        # test_plane.renderer.material.texture = self._generator.get_texture("F", 128)

    @property
    def name(self):
        return self._name

    @property
    def radius(self):
        return self._radius
    
    @property
    def max_height(self):
        return self._max_height
        
    @property
    def camera_pos(self):
        return self._camera_pos
    
    @property
    def camera_pos_sc(self):
        return self._camera_pos_sc
    
    @property
    def split_factor(self):
        return self._split_factor
    
    @property
    def split_power(self):
        return self._split_power
    
    @property
    def horizon(self):
        return self._horizon
    
    @property
    def ui(self):
        return self._ui
    
    @property
    def camera(self):
        return self._camera

    @property
    def generator(self):
        return self._generator
    
    def can_split(self):
        split = False
        
#        print "Requesting split: # %d Max # %d" % (self._num_splits, self._max_splits )
        if self._num_splits < self._max_splits:
            split = True
            self._num_splits += 1
#            print "Granted"
#        else:
#            print "Rejected"
        
        return split
        
        
    def _gen_faces(self):

        gen_timer = Timer("Gen Timer")

        gen_timer.start()

        self._top =     SphereQuad('T', self, self, radius=self._radius, density=self._density, face=CubeSphereMap.TOP)
        self._bottom =  SphereQuad('U', self, self, radius=self._radius, density=self._density, face=CubeSphereMap.BOTTOM)
        self._front =   SphereQuad('F', self, self, radius=self._radius, density=self._density, face=CubeSphereMap.FRONT)
        self._back =    SphereQuad('B', self, self, radius=self._radius, density=self._density, face=CubeSphereMap.BACK)
        self._left =    SphereQuad('L', self, self, radius=self._radius, density=self._density, face=CubeSphereMap.LEFT)
        self._right =   SphereQuad('R', self, self, radius=self._radius, density=self._density, face=CubeSphereMap.RIGHT)
        
        self.transform.add_child(self._top.transform)
        self.transform.add_child(self._bottom.transform)
        self.transform.add_child(self._front.transform)
        self.transform.add_child(self._back.transform)
        self.transform.add_child(self._left.transform)
        self.transform.add_child(self._right.transform)
        
        self._top._init_quad()
        self._bottom._init_quad()
        self._front._init_quad()
        self._back._init_quad()
        self._left._init_quad()
        self._right._init_quad()

        gen_timer.stop()
        gen_timer.elapsed()

    def update_sphere(self):
        
#        start = datetime.now()
        
        if (datetime.now() - self._last_time).total_seconds() > 0.1:
        
            if self._ui.track_camera:
            
                if self._camera is None:
                    self._camera = SceneManager.get_instance().current_scene.active_camera

                # Store the camera pos for access by the quad children
                self._camera_pos = self._camera.node_parent.transform.position - self.transform.position

                self._camera_pos_sc = CubeSphereMap.get_cube_coord(self._camera_pos.x, self._camera_pos.y, self._camera_pos.z) 
                
                self._line.line_to(self._camera_pos)


                if self._ui.planet_camera:
                    # Check if the camera has intersected the planet.
                    if self._camera_pos.magnitude() < (self._radius + self._max_height):
                        u = self._camera_pos_sc.x
                        v = self._camera_pos_sc.y
                        face = self._camera_pos_sc.face
                        self._camera.node_parent.transform.position = CubeSphereMap.get_sphere_position(u, v, face, (self._radius + self._max_height))

                
                # Reset the number of splits
                self._num_splits = 0
                #print "Resetting splits"
                
                # If the camera has moved a sufficient distance to warrant an update
    #            if self._last_camera_pos is None:
    #                self._last_camera_pos = self._camera_pos
    #            dist = self._last_camera_pos - self._camera_pos 
    #            if dist.magnitude() > 1.0:
                    
                # Calc the horizon
                altitude = self._camera_pos.magnitude()
                horizon_altitude = max([altitude-self.radius, self.max_height])
                self._horizon = math.sqrt(horizon_altitude * horizon_altitude + 2.0 * horizon_altitude * self._radius)
                
                if True:
                    # Update all of the sides of the cube/sphere
                    for child in self.transform.children:
                        if isinstance(child.node, SphereQuad):
                            child.node.update_surface()
                        
                self._last_camera_pos = self._camera_pos
                        
                self._last_time = datetime.now()
                
                # Update the UI with the camera pos
    #            self._ui.rel_camera_pos = self._camera_pos
    #            self._ui.camera_pos = self._camera_pos_sc

                if not self._camera_pos_sc is None:
                    pos = CubeSphereMap.get_sphere_vector(self._camera_pos_sc.x, self._camera_pos_sc.y, self._camera_pos_sc.face)
                    pos.normalize()
                    pos *= (self._radius / 1.9)
                    self._camera_gizmo.transform.position = pos
            
#        el = datetime.now() - start
#        print "Update Elapsed: %4.2f ms " % (el.microseconds / 1000)
            
    def cull(self, camera):
        # Override culling so that it doesn't interfere with the planet
        return [self,]
            
    def draw(self):
        
#        start = datetime.now()
        
        self.renderer._setup_draw()
        
        for child in self.transform.children:
            if child.node:
                child.node.draw()
            
        self.renderer._teardown_draw()