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()