create planete

Hello everybody.
I would like to realize as project to create a (small) planet with panda3D.

I want a sphere with relief and 3D object (grass and tree) and ralph who run.

But i have two problems :

  1. How to apply heightmap to sphere ? for have a sphere with relief
  2. With Panda3D can i have a physic in heightmap for place tree/grass and ralph ?

I need to head out soon, but this is my main resource for making planets: acko.net/blog/making-worlds-1-o … and-cubes/

thak for your help, but the link presents only the theoretical aspect.
I need more help on panda3D, I can not apply a heightmap to a sphere (for relief)

this is my code :

from __future__ import print_function

import os
import sys
from panda3d.core import Vec3, load_prc_file_data, ShaderTerrainMesh
from direct.showbase.ShowBase import ShowBase


from panda3d.core import *

import threading
from threading import Thread
import procedural


class Application(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        model = procedural.IcoSphere(radius=1, subdivisions=3)
        model.reparentTo(self.render)
        
        heightfield = loader.loadTexture("resources/heightfield.png")
        
        terrain_node = ShaderTerrainMesh()
        terrain_node.heightfield = heightfield
        terrain_node.target_triangle_width = 6.0
        terrain_node.generate()

        terrain_n = model.attach_new_node(terrain_node)
        
Application().run()

The shader terrain mesh currently does not support the technique mentioned in the article, because it assumes the terrain is untransformed (or at least, only linear transformed) for culling.

You can either extend the shader terrain mesh if you wish, or you will have to use another terrain generator (Maybe GeoMipTerrain supports it? Not sure.) or even generate the terrain yourself.

i have updated my code with GeoMipTerrain, but i can not apply the node to ODE physic Engine (in line 97)

from __future__ import print_function

import os
import sys
from panda3d.core import Vec3, load_prc_file_data, ShaderTerrainMesh
from direct.showbase.ShowBase import ShowBase
from panda3d.ode import OdeWorld, OdeSimpleSpace, OdeJointGroup
from panda3d.ode import OdeWorld, OdeBody, OdeMass, OdeBoxGeom, OdePlaneGeom
from panda3d.core import Quat


from panda3d.core import *

import threading
from threading import Thread
import procedural
from random import randint, random


class Application(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        
        #Init sphere
        sphere = procedural.IcoSphere(radius=1, subdivisions=3)
        sphere.reparentTo(self.render)
        
        #Init Terrain
        self.terrain_np = render.attach_new_node("terrain")
        terrain = GeoMipTerrain("myDynamicTerrain")
        terrain.setHeightfield("resources/heightfield.png")
        
        # Set terrain properties
        terrain.setBlockSize(32)
        terrain.setNear(40)
        terrain.setFar(100)
        terrain.setFocalPoint(base.camera)
         
        # Store the root NodePath for convenience
        root = terrain.getRoot()
        root.reparentTo(render)
        root.setSz(100)
        
        # Attach Sphere to terrain node
        sphere.reparentTo(root)
        
        #Init Physic
        world = OdeWorld()
        world.setGravity(0, 0, -9.81)
        world.initSurfaceTable(1)
        world.setSurfaceEntry(0, 0, 150, 0.0, 9.1, 0.9, 0.00001, 0.0, 0.002)
        
        # Create a space and add a contactgroup to it to add the contact joints
        space = OdeSimpleSpace()
        space.setAutoCollideWorld(world)
        contactgroup = OdeJointGroup()
        space.setAutoCollideJointGroup(contactgroup)
        
        # Add a random amount of boxes
        box = loader.loadModel("box")
        # Make sure its center is at 0, 0, 0 like OdeBoxGeom
        box.setPos(-.5, -.5, -.5)
        box.flattenLight() # Apply transform
        box.setTextureOff
        
        boxes = []
        for i in range(0, 15):
          # Setup the geometry
          boxNP = box.copyTo(render)
          boxNP.setPos(randint(-10, 10), randint(-10, 10), 10 + random())
          boxNP.setColor(random(), random(), random(), 1)
          boxNP.setHpr(randint(-45, 45), randint(-45, 45), randint(-45, 45))
          # Create the body and set the mass
          boxBody = OdeBody(world)
          M = OdeMass()
          M.setBox(50, 1, 1, 1)
          boxBody.setMass(M)
          boxBody.setPosition(boxNP.getPos(render))
          boxBody.setQuaternion(boxNP.getQuat(render))
          # Create a BoxGeom
          boxGeom = OdeBoxGeom(space, 1, 1, 1)
          boxGeom.setCollideBits(BitMask32(0x00000002))
          boxGeom.setCategoryBits(BitMask32(0x00000001))
          boxGeom.setBody(boxBody)
          boxes.append((boxNP, boxBody))
          
          
        # Generate it.

        cNode = CollisionNode("sphere")
        ground = render.attachNewNode(cNode)

        cm = CardMaker("ground")
        cm.setFrame(-20, 20, -20, 20)
        
        # Why terrain.generate() not work ?
        ground = render.attachNewNode(cm.generate())
        terrain.generate()

        ground.setPos(0, 0, 0); ground.lookAt(0, 0, -1)
        groundGeom = OdePlaneGeom(space, Vec4(0, 0, 1, 0))
        groundGeom.setCollideBits(BitMask32(0x00000001))
        groundGeom.setCategoryBits(BitMask32(0x00000002))

        # Add a task to keep updating the terrain
        def updateTask(task):
          terrain.update()
          return task.cont
        taskMgr.add(updateTask, "update")
        
        # The task for our simulation
        def simulationTask(task):
          space.autoCollide() # Setup the contact joints
          # Step the simulation and set the new positions
          world.quickStep(globalClock.getDt())
          for np, body in boxes:
            np.setPosQuat(render, body.getPosition(), Quat(body.getQuaternion()))
          contactgroup.empty() # Clear the contact joints
          return task.cont
         
        # Wait a split second, then start the simulation  
        taskMgr.doMethodLater(0.5, simulationTask, "Physics Simulation")
        
Application().run()