示例#1
0
 def update_geom(self):
     geom = self.node.modify_geom(0)
     vdata = geom.modify_vertex_data()
     vwriter = GeomVertexRewriter(vdata, InternalName.get_vertex())
     #TODO: refactor with above code !!!
     delta = self.body.parent.get_local_position()
     if self.orbit.is_periodic():
         epoch = self.context.time.time_full - self.orbit.period
         step = self.orbit.period / (self.nbOfPoints - 1)
     else:
         #TODO: Properly calculate orbit start and end time
         epoch = self.orbit.get_time_of_perihelion() - self.orbit.period * 5.0
         step = self.orbit.period * 10.0 / (self.nbOfPoints - 1)
     for i in range(self.nbOfPoints):
         time = epoch + step * i
         pos = self.orbit.get_position_at(time) - delta
         vwriter.setData3f(*pos)
示例#2
0
 def rain(self, task):
     # animate level
     self.flood()
     # Animate Rain
     speed = 1.0
     vertex = GeomVertexRewriter(self.rain_vdata, 'vertex')
     color = GeomVertexWriter(self.rain_vdata, 'color')
     moving = np.random.choice([0, 1],
                               size=(self.n_points, self.n_points),
                               p=[999 / 1000, 1. / 1000])
     moved = 0
     for j in range(self.n_points):
         for i in range(self.n_points):
             # rain
             v = vertex.getData3f()
             # start falling
             if v[2] == self.n_points:
                 if moving[j][i] == 1 and self.raining == True:
                     self.rz[j][i] -= speed
                     vertex.setData3f(v[0], v[1], self.rz[j][i])
                     color.setData4f(0.3, 0.3, 1, 1)
                     moved += 1
                 else:
                     vertex.setData3f(v[0], v[1], v[2])
                     color.setData4f(0.3, 0.3, 1, 0)
             # keep falling
             elif self.rz[j][i] > self.lz[j][i]:
                 if self.rz[j][i] - speed > self.lz[j][i]:
                     self.rz[j][i] -= speed
                 else:
                     self.rz[j][i] = self.lz[j][i]
                 vertex.setData3f(v[0], v[1], self.rz[j][i])
                 if self.rz[j][i] > self.wz[j][i]:
                     color.setData4f(0.3, 0.3, 1, 1)
                 else:
                     color.setData4f(0.3, 0.3, 1, 0)
                 moved += 1
             # stop falling
             else:
                 # handle rolling drops
                 v = list(map(int, v))
                 moved += self.rolling_drops(v, vertex, color, moved, i, j)
     if moved == 0:
         self.flooding = False
         return task.done
     return task.cont
示例#3
0
 def wave(self, task):
     # Compute physic
     step_np1 = self.water_physic()
     self.H += 0.1 * (np.mean(step_np1) - self.H)
     # render wave
     vertex = GeomVertexRewriter(self.water_vdata, 'vertex')
     normal = GeomVertexRewriter(self.water_vdata, 'normal')
     for j in range(0, self.n_points, self.details):
         for i in range(0, self.n_points, self.details):
             self.wz[j][i] = step_np1[j // self.details][i // self.details]
             v = vertex.getData3f()
             if j != 0 and i != 0 and j != self.n_points - self.details and \
                                         i != self.n_points - self.details:
                 vertex.setData3f(v[0], v[1], self.wz[j][i])
                 n = np.array([v[0], v[1], self.wz[j][i]])
             else:
                 vertex.setData3f(v[0], v[1], self.H)
                 n = np.array([v[0], v[1], self.H])
             norm = n / np.linalg.norm(n)
             normal.setData3f(norm[0], norm[1], norm[2])
     # Extend Water Borders
     vertex = GeomVertexRewriter(self.water_border_vdata, 'vertex')
     normal = GeomVertexRewriter(self.water_border_vdata, 'normal')
     for i in range(0, 8, 2):
         v = vertex.getData3f()
         vertex.setData3f(v[0], v[1], self.H)
         n = np.array([v[0], v[1], self.H])
         norm = n / np.linalg.norm(n)
         normal.setData3f(norm[0], norm[1], norm[2])
         v = vertex.getData3f()
         vertex.setData3f(v[0], v[1], 0)
         n = np.array([v[0], v[1], 1e-12])
         norm = n / np.linalg.norm(n)
         normal.setData3f(norm[0], norm[1], norm[2])
     # handle last puddles
     self.handle_last_puddles()
     return task.cont
示例#4
0
 def flood(self, task=None):
     # Animate Water Surface
     step_np1 = self.water_physic()
     vertex = GeomVertexRewriter(self.water_vdata, 'vertex')
     normal = GeomVertexRewriter(self.water_vdata, 'normal')
     for j in range(0, self.n_points, self.details):
         for i in range(0, self.n_points, self.details):
             # Flood
             if j != 0 and i != 0 and j != self.n_points - self.details and \
                                     i != self.n_points - self.details:
                 self.wz[j][i] = step_np1[j // self.details][i //
                                                             self.details]
             else:
                 self.wz[j][i] = self.H  # borders condition
             v = vertex.getData3f()
             vertex.setData3f(v[0], v[1], self.wz[j][i])
             n = np.array([v[0], v[1], self.wz[j][i]])
             norm = n / np.linalg.norm(n)
             normal.setData3f(norm[0], norm[1], norm[2])
     # Extend Water Borders
     vertex = GeomVertexRewriter(self.water_border_vdata, 'vertex')
     normal = GeomVertexRewriter(self.water_border_vdata, 'normal')
     for i in range(0, 8, 2):
         v = vertex.getData3f()
         vertex.setData3f(v[0], v[1], self.H)
         n = np.array([v[0], v[1], self.H])
         norm = n / np.linalg.norm(n)
         normal.setData3f(norm[0], norm[1], norm[2])
         v = vertex.getData3f()
         vertex.setData3f(v[0], v[1], 0)
         n = np.array([v[0], v[1], 1e-12])
         norm = n / np.linalg.norm(n)
         normal.setData3f(norm[0], norm[1], norm[2])
     # animate level
     if self.flooding == True and self.flush == False and self.H < self.n_points:
         self.H += self.dt
     elif self.flush == True and self.H > 1:
         self.H -= self.dt
         # handle last puddles
         #self.handle_last_puddles()
     if task:
         return task.cont
示例#5
0
 def __init__(self, objinit, cdtype="triangle", mass=.3, restitution=0, allowdeactivation=False, allowccd=True,
              friction=.2, dynamic=True, name="rbd"):
     """
     :param objinit: could be itself (copy), or an instance of collision model
     :param type: triangle or convex
     :param mass:
     :param restitution: bounce parameter
     :param friction:
     :param dynamic: only applicable to triangle type, if an object does not move with force, it is not dynamic
     :param name:
     author: weiwei
     date: 20190626, 20201119
     """
     super().__init__(name)
     if isinstance(objinit, gm.GeometricModel):
         if objinit._objtrm is None:
             raise ValueError("Only applicable to models with a trimesh!")
         self.com = objinit.objtrm.center_mass
         self.setMass(mass)
         self.setRestitution(restitution)
         self.setFriction(friction)
         self.setLinearDamping(.3)
         self.setAngularDamping(.3)
         if allowdeactivation:
             self.setDeactivationEnabled(True)
             self.setLinearSleepThreshold(0.001)
             self.setAngularSleepThreshold(0.001)
         else:
             self.setDeactivationEnabled(False)
         if allowccd:  # continuous collision detection
             self.setCcdMotionThreshold(1e-6)
             self.setCcdSweptSphereRadius(0.0005)
         gnd = objinit.objpdnp.getChild(0).find("+GeomNode")
         geom = copy.deepcopy(gnd.node().getGeom(0))
         vdata = geom.modifyVertexData()
         vertrewritter = GeomVertexRewriter(vdata, 'vertex')
         while not vertrewritter.isAtEnd():  # shift local coordinate to geom to correctly update dynamic changes
             v = vertrewritter.getData3f()
             vertrewritter.setData3f(v[0] - self.com[0], v[1] - self.com[1], v[2] - self.com[2])
         geomtf = gnd.getTransform()
         if cdtype is "triangle":
             geombmesh = BulletTriangleMesh()
             geombmesh.addGeom(geom)
             bulletshape = BulletTriangleMeshShape(geombmesh, dynamic=dynamic)
             bulletshape.setMargin(1e-6)
             self.addShape(bulletshape, geomtf)
         elif cdtype is "convex":
             bulletshape = BulletConvexHullShape()  # TODO: compute a convex hull?
             bulletshape.addGeom(geom, geomtf)
             bulletshape.setMargin(1e-6)
             self.addShape(bulletshape, geomtf)
         else:
             raise NotImplementedError
         pdmat4 = geomtf.getMat()
         pdv3 = pdmat4.xformPoint(Vec3(self.com[0], self.com[1], self.com[2]))
         homomat = dh.pdmat4_to_npmat4(pdmat4)
         pos = dh.pdv3_to_npv3(pdv3)
         homomat[:3, 3] = pos  # update center to com
         self.setTransform(TransformState.makeMat(dh.npmat4_to_pdmat4(homomat)))
     elif isinstance(objinit, BDBody):
         self.com = objinit.com.copy()
         self.setMass(objinit.getMass())
         self.setRestitution(objinit.restitution)
         self.setFriction(objinit.friction)
         self.setLinearDamping(.3)
         self.setAngularDamping(.3)
         if allowdeactivation:
             self.setDeactivationEnabled(True)
             self.setLinearSleepThreshold(0.001)
             self.setAngularSleepThreshold(0.001)
         else:
             self.setDeactivationEnabled(False)
         if allowccd:
             self.setCcdMotionThreshold(1e-6)
             self.setCcdSweptSphereRadius(0.0005)
         self.setTransform(TransformState.makeMat(dh.npmat4_to_pdmat4(objinit.gethomomat())))
         self.addShape(objinit.getShape(0), objinit.getShapeTransform(0))