Ejemplo n.º 1
0
 def debug(self):
     np.set_printoptions(suppress=True, edgeitems=10, linewidth=200)
     _, vert_pos_l = p.getMeshData(self.cloth_id,
                                   -1,
                                   flags=p.MESH_DATA_SIMULATION_MESH)
     _, _, c3, c4 = self.c1, self.c2, self.c3, self.c4
     print('\nInside {} reset()'.format(self._name))
     print('\tcloth grid:      {} x {}'.format(self.n_cuts, self.n_cuts))
     print('\tcloth scale:     {:.3f}'.format(self._cloth_scale))
     print('\tedge_length:     {:.3f} meters'.format(self._edge_length))
     print('\tcollisionMargin: {:.3f} meters ({:.1f}) mm'.format(
         self._collisionMargin, self._collisionMargin * 1000))
     print('\tcloth mass:      {:.3f} kg'.format(self._mass))
     print('zone_pose:    {}'.format(U.round_pose(self.zone_pose)))
     print('zone c1 pos:  {}'.format(U.round_pos(self.c1_position)))
     print('zone c2 pos:  {}'.format(U.round_pos(self.c2_position)))
     print('zone c3 pos:  {}'.format(U.round_pos(self.c3_position)))
     print('zone c4 pos:  {}'.format(U.round_pos(self.c4_position)))
     print('cloth c1 pos: {}'.format(
         U.round_pos(vert_pos_l[self.corner_indices[0]])))
     print('cloth c2 pos: {}'.format(
         U.round_pos(vert_pos_l[self.corner_indices[1]])))
     print('cloth c3 pos: {}'.format(
         U.round_pos(vert_pos_l[self.corner_indices[2]])))
     print('cloth c4 pos: {}'.format(
         U.round_pos(vert_pos_l[self.corner_indices[3]])))
     print(f'alpha_l: {self.alpha_l}')
     print(
         f'c4 {c4}, c3 {c3}, edge_length {self._edge_length:0.3f}, vec_offset {self.vec_offset}'
     )
     print('Waiting {} secs for cloth to settle ...\n'.format(
         self._settle_secs))
Ejemplo n.º 2
0
    def info(self):
        """Normally returns dict of:

            object id : (position, rotation, dimensions)

        However, I made a few changes. First, removing IDs in some tasks, so
        we shouldn't query their position. Second, adding object mesh for
        gt_state and soft bodies. The second `if` test is redundant but just
        in case. Here, we instead map to the mesh data instead of (position,
        rotation, dimension). This is: (nb_vertices, (positions)) where the
        latter is a tuple that has all the 3D positions of each vertex in the
        simulation mesh, e.g., it's 100 for cloth.

        Note on soft body IDs:
        cloth-cover: ID 5 is cloth (ID 4 is item to cover)
        cloth-flat(notarget): ID 5 is cloth (ID 4 is the zone, though in the no
            target case we remove it ... historical reasons).
        bag tasks: all have ID 5 as the bag, because they use ID 4 for the zone,
            (with bag-alone removing zone) and other items are added afterwards.

        To see how we use the special case for soft bodies, see:
            ravens/agents/gt_state.py and the extraact_x_y_theta method.
        We depend on assuming that len(info[id]) = 2 instead of 3.
        """
        removed_IDs = []
        if (isinstance(self.task, tasks.names['cloth-flat-notarget']) or
                isinstance(self.task, tasks.names['bag-alone-open'])):
            removed_IDs.append(self.task.zone_ID)

        # Daniel: special case for soft bodies (and gt_state). For now only cloth.
        softbody_id = -1
        if self.is_cloth_env():
            assert len(self.task.def_IDs) == 1, self.task.def_IDs
            softbody_id = self.task.def_IDs[0]

        # object id : (position, rotation, dimensions)
        info = {}
        for object_id in (self.fixed_objects + self.objects):
            if object_id in removed_IDs:
                continue

            # Daniel: special cases for soft bodies (and gt_state), and then bags.
            if (object_id == softbody_id) and self.is_cloth_env():
                info[object_id] = p.getMeshData(object_id, -1, flags=p.MESH_DATA_SIMULATION_MESH)
            elif isinstance(self.task, tasks.names['bag-color-goal']):
                # Note: we don't do this for sorting? :X
                position, rotation = p.getBasePositionAndOrientation(object_id)
                dimensions = p.getVisualShapeData(object_id)[0][3]
                rgba_color = p.getVisualShapeData(object_id)[0][7]  # see pybullet docs
                assert rgba_color[3] == 1, rgba_color
                rgb_color = rgba_color[0:3]  # we can ignore the last component it is always 1
                info[object_id] = (position, rotation, dimensions, rgb_color)
            else:
                # The usual case.
                position, rotation = p.getBasePositionAndOrientation(object_id)
                dimensions = p.getVisualShapeData(object_id)[0][3]
                info[object_id] = (position, rotation, dimensions)

        return info
Ejemplo n.º 3
0
    def activate_def(self, def_id):
        """Simulates suction by anchoring vertices of the deformable object.

    Get distance values in `distances`, get indices for argsort, then
    resulting indices in `distances_sort` correspond _exactly_ to vertex
    indices arranged from nearest to furthest to the gripper.

    Args:
      def_id: bullet id for object to anchor.

    Returns:
      info dict containing activation information.
    """
        _, vert_pos_l = p.getMeshData(bodyUniqueId=def_id)
        gripper_position = np.float32(p.getLinkState(self.body, 0)[0])
        distances = []
        for v_position in vert_pos_l:
            d = gripper_position - np.float32(v_position)
            distances.append(np.linalg.norm(d))
        distances_sort = np.argsort(distances)

        anchors = []
        for i in range(self.def_nb_anchors):
            # For each vertex close enough (under threshold), create anchor(s).
            v_index = distances_sort[i]
            if distances[v_index] > self.def_threshold:
                pass
            # This should prevent us from gripping if the suction didn't grip
            # anything.
            if distances[v_index] > self.def_ignore:
                print(
                    f'WARNING, dist={distances[v_index]:0.4f} > thresh '
                    f'{self.def_ignore:0.4f}. No points are close to the suction'
                )
                break
            anchor_id = p.createSoftBodyAnchor(
                softBodyBodyUniqueId=def_id,
                nodeIndex=v_index,
                bodyUniqueId=self.body,
                linkIndex=-1,
            )
            anchors.append(anchor_id)

        info = {
            'anchors': anchors,
            'closest_vertex': distances_sort[0],
            'min_distance': np.min(distances),
        }
        return info
Ejemplo n.º 4
0
    def activate_def(self, defId):
        """Simulates suction by anchoring vertices of the deformable object.

        Get distance values in `distances`, get indices for argsort, then
        resulting indices in `distances_sort` correspond _exactly_ to vertex
        indices arranged from nearest to furthest to the gripper.
        """
        _, vert_pos_l = p.getMeshData(defId,
                                      -1,
                                      flags=p.MESH_DATA_SIMULATION_MESH)
        gripper_position = np.float32(p.getLinkState(self.body, 0)[0])
        distances = []
        for v_position in vert_pos_l:
            d = gripper_position - np.float32(v_position)
            distances.append(np.linalg.norm(d))
        distances_sort = np.argsort(distances)

        anchors = []
        for i in range(self.def_nb_anchors):
            # For each vertex close enough (under threshold), create anchor(s).
            vIndex = distances_sort[i]
            if distances[vIndex] > self.def_threshold:
                #print(f'WARNING, dist={distances[vIndex]:0.4f} > {self.def_threshold} '
                #    f'This means our gripper touched the surface (z=0)')
                pass
            # This should prevent us from gripping if the suction didn't grip anything.
            if distances[vIndex] > self.def_ignore:
                print(
                    f'WARNING, dist={distances[vIndex]:0.4f} > thresh '
                    f'{self.def_ignore:0.4f}. No points are close to the suction'
                )
                break
            anchorId = p.createSoftBodyAnchor(
                softBodyBodyUniqueId=defId,
                nodeIndex=vIndex,
                bodyUniqueId=self.body,
                linkIndex=-1,
            )
            anchors.append(anchorId)

        info = {
            'anchors': anchors,
            'closest_vertex': distances_sort[0],
            'min_distance': np.min(distances),
        }
        #print(info)
        return info
Ejemplo n.º 5
0
    def detect_contact_def(self, gripper_position, def_id):
        """Detect contact, when dealing with deformables.

    Args:
      gripper_position: gripper position.
      def_id: Bullet id of deformable.

    Returns:
      bool indicating if there exists _any_ vertex within the distance
        threshold.
    """
        _, vert_pos_l = p.getMeshData(bodyUniqueId=def_id)
        distances = []
        for v_position in vert_pos_l:
            d = gripper_position - np.float32(v_position)
            distances.append(np.linalg.norm(d))
        return np.min(distances) < self.def_threshold
Ejemplo n.º 6
0
    def detect_contact_def(self, gripper_position, defId):
        """Detect contact, when dealing with deformables.

        We may want to speed this up if it is a bottleneck. Returns a binary
        signal of whether there exists _any_ vertex within the threshold.
        Note with collisionMargin=0.004, I am getting most cloth vertices
        (for ClothFlat) to settle at ~0.004m high.
        """
        _, vert_pos_l = p.getMeshData(defId,
                                      -1,
                                      flags=p.MESH_DATA_SIMULATION_MESH)

        # Vectorized.
        distances_np = gripper_position - np.array(vert_pos_l)
        assert len(distances_np.shape) == 2, distances_np.shape
        distances_L2 = np.linalg.norm(distances_np, axis=1)
        return np.min(distances_L2) < self.def_threshold
Ejemplo n.º 7
0
    def add_cloth(self, env, base_pos, base_orn):
        """Adding a cloth from an .obj file."""
        cloth_id = p.loadSoftBody(
            fileName=self._f_cloth,
            basePosition=base_pos,
            baseOrientation=base_orn,
            collisionMargin=self._collisionMargin,
            scale=self._cloth_scale,
            mass=self._mass,
            useNeoHookean=0,
            useBendingSprings=1,
            useMassSpring=1,
            springElasticStiffness=40,
            springDampingStiffness=0.1,
            springDampingAllDirections=0,
            useSelfCollision=1,
            frictionCoeff=1.0,
            useFaceContact=1,
        )

        # Only if using more recent PyBullet versions.
        p_version = pkg_resources.get_distribution('pybullet').version
        if p_version == '3.0.4':
            color = U.COLORS['yellow'] + [1]
            p.changeVisualShape(cloth_id,
                                -1,
                                flags=p.VISUAL_SHAPE_DOUBLE_SIDED,
                                rgbaColor=color)

        # For tracking IDs and consistency with existing ravens code.
        self._IDs[cloth_id] = 'cloth'
        self.object_points[cloth_id] = np.float32((0, 0, 0)).reshape(3, 1)
        env.objects.append(cloth_id)

        # To help environment pick-place method track all deformables.
        self.def_IDs.append(cloth_id)

        # Sanity checks.
        nb_vertices, _ = p.getMeshData(cloth_id,
                                       -1,
                                       flags=p.MESH_DATA_SIMULATION_MESH)
        assert nb_vertices == self.n_cuts * self.n_cuts
        return cloth_id
Ejemplo n.º 8
0
    def add_cloth(self, env, base_pos, base_orn):
        """Adding a cloth from an .obj file.

    Since this is a soft body, need to add this ID to `self.def_ids.

    Args:
      env: a ravens environment.
      base_pos: Position of the cloth.
      base_orn: Orientation of the cloth.

    Returns:
      bullet id of the cloth.
    """
        cloth_id = p.loadSoftBody(fileName=self._f_cloth,
                                  basePosition=base_pos,
                                  baseOrientation=base_orn,
                                  collisionMargin=self._collision_margin,
                                  scale=self._cloth_scale,
                                  mass=self._mass,
                                  useNeoHookean=0,
                                  useBendingSprings=1,
                                  useMassSpring=1,
                                  springElasticStiffness=40,
                                  springDampingStiffness=0.1,
                                  springDampingAllDirections=0,
                                  useSelfCollision=1,
                                  frictionCoeff=1.0,
                                  useFaceContact=1)

        # Add objects in a consistent manner.
        self.object_points[cloth_id] = np.float32((0, 0, 0)).reshape(3, 1)
        env.objects.append(cloth_id)
        self.def_ids.append(cloth_id)

        # Sanity checks.
        nb_vertices, _ = p.getMeshData(bodyUniqueId=cloth_id)
        assert nb_vertices == self.n_cuts * self.n_cuts
        return cloth_id
Ejemplo n.º 9
0
p.createSoftBodyAnchor(armId2, 0, mod2, -1)
p.createSoftBodyAnchor(armId2, 1, mod2, -1)
p.createSoftBodyAnchor(armId2, 2, mod2, -1)
p.createSoftBodyAnchor(armId2, 3, mod2, -1)

p.createSoftBodyAnchor(armId3, 7, mod3, -1)
p.createSoftBodyAnchor(armId3, 8, mod3, -1)
p.createSoftBodyAnchor(armId3, 16, mod3, -1)
p.createSoftBodyAnchor(armId3, 17, mod3, -1)

p.createSoftBodyAnchor(armId4, 7, mod4, -1)
p.createSoftBodyAnchor(armId4, 8, mod4, -1)
p.createSoftBodyAnchor(armId4, 16, mod4, -1)
p.createSoftBodyAnchor(armId4, 17, mod4, -1)

numLinks = p.getMeshData(armId1)
pos, ort = p.getBasePositionAndOrientation(armId1)

# run simulation
useRealTimeSimulation = 0
if (useRealTimeSimulation):
    p.setRealTimeSimulation(0)

posArr1 = []
posArr2 = []
posArr3 = []
posArr4 = []
posArr5 = []

velArr1 = []
velArr2 = []
Ejemplo n.º 10
0
    def render(self, shadow_pass=0):
        """
        Render this instance
        shadow_pass = 0: normal rendering mode, disable shadow
        shadow_pass = 1: enable_shadow, rendering depth map from light space
        shadow_pass = 2: use rendered depth map to calculate shadow

        :param shadow_pass: shadow pass mode
        """
        if self.renderer is None:
            return

        # softbody: reload vertex position
        if self.softbody:
            # construct new vertex position into shape format
            object_idx = self.object.VAO_ids[0]
            vertices = p.getMeshData(self.pybullet_uuid)[1]
            vertices_flattened = [
                item for sublist in vertices for item in sublist]
            vertex_position = np.array(vertices_flattened).reshape(
                (len(vertices_flattened) // 3, 3))
            shape = self.renderer.shapes[object_idx]
            n_indices = len(shape.mesh.indices)
            np_indices = shape.mesh.numpy_indices().reshape((n_indices, 3))
            shape_vertex_index = np_indices[:, 0]
            shape_vertex = vertex_position[shape_vertex_index]

            # update new vertex position in buffer data
            new_data = self.renderer.vertex_data[object_idx]
            new_data[:, 0:shape_vertex.shape[1]] = shape_vertex
            new_data = new_data.astype(np.float32)

            # transform and rotation already included in mesh data
            self.pose_trans = np.eye(4)
            self.pose_rot = np.eye(4)
            self.last_trans = np.eye(4)
            self.last_rot = np.eye(4)

            # update buffer data into VBO
            self.renderer.r.render_softbody_instance(
                self.renderer.VAOs[object_idx], self.renderer.VBOs[object_idx], new_data)

        self.renderer.r.initvar(self.renderer.shaderProgram,
                                self.renderer.V,
                                self.renderer.last_V,
                                self.renderer.lightV,
                                shadow_pass,
                                self.renderer.P,
                                self.renderer.lightP,
                                self.renderer.camera,
                                self.renderer.lightpos,
                                self.renderer.lightcolor)

        self.renderer.r.init_pos_instance(self.renderer.shaderProgram,
                                          self.pose_trans,
                                          self.pose_rot,
                                          self.last_trans,
                                          self.last_rot)

        for object_idx in self.object.VAO_ids:
            current_material = self.renderer.materials_mapping[
                self.renderer.mesh_materials[object_idx]]
            self.renderer.r.init_material_instance(self.renderer.shaderProgram,
                                                   float(
                                                       self.class_id) / 255.0,
                                                   current_material.kd,
                                                   float(
                                                       current_material.is_texture()),
                                                   float(self.use_pbr),
                                                   float(self.use_pbr_mapping),
                                                   float(self.metalness),
                                                   float(self.roughness),
                                                   current_material.transform_param)
            try:

                texture_id = current_material.texture_id
                metallic_texture_id = current_material.metallic_texture_id
                roughness_texture_id = current_material.roughness_texture_id
                normal_texture_id = current_material.normal_texture_id

                if texture_id is None:
                    texture_id = -1
                if metallic_texture_id is None:
                    metallic_texture_id = -1
                if roughness_texture_id is None:
                    roughness_texture_id = -1
                if normal_texture_id is None:
                    normal_texture_id = -1

                if self.renderer.msaa:
                    buffer = self.renderer.fbo_ms
                else:
                    buffer = self.renderer.fbo

                self.renderer.r.draw_elements_instance(
                    self.renderer.materials_mapping[self.renderer.mesh_materials[object_idx]].is_texture(
                    ),
                    texture_id,
                    metallic_texture_id,
                    roughness_texture_id,
                    normal_texture_id,
                    self.renderer.depth_tex_shadow,
                    self.renderer.VAOs[object_idx],
                    self.renderer.faces[object_idx].size,
                    self.renderer.faces[object_idx],
                    buffer)
            finally:
                self.renderer.r.cglBindVertexArray(0)

        self.renderer.r.cglUseProgram(0)
Ejemplo n.º 11
0
  def add_cable_ring(self, env):
    """Make the cable beads coincide with the vertices of the top ring.

    Should lead to better physics and will make it easy for an algorithm
    to see the bag's top ring. Notable differences between this and the
    cables: (1) we don't need to discretize rotations and manually
    compute bead positions, because the previously created bag does it
    for us, (2) Beads have anchors with vertices, in ADDITION to
    constraints with adjacent beads.

    Args:
      env: A ravens environment.
    """
    num_parts = len(self._top_ring_idxs)
    radius = 0.005
    color = U.COLORS['blue'] + [1]
    beads = []
    bead_positions_l = []
    part_shape = p.createCollisionShape(p.GEOM_BOX, halfExtents=[radius] * 3)
    part_visual = p.createVisualShape(p.GEOM_SPHERE, radius=radius * 1.5)

    # Fortunately `verts_l` coincides with `self._top_ring_idxs`.
    _, verts_l = p.getMeshData(self.bag_id)

    # Iterate through parts and create constraints as needed.
    for i in range(num_parts):
      bag_vidx = self._top_ring_idxs[i]
      bead_position = np.float32(verts_l[bag_vidx])
      part_id = p.createMultiBody(
          0.01, part_shape, part_visual, basePosition=bead_position)
      p.changeVisualShape(part_id, -1, rgbaColor=color)

      if i > 0:
        parent_frame = bead_position - bead_positions_l[-1]
        constraint_id = p.createConstraint(
            parentBodyUniqueId=beads[-1],
            parentLinkIndex=-1,
            childBodyUniqueId=part_id,
            childLinkIndex=-1,
            jointType=p.JOINT_POINT2POINT,
            jointAxis=(0, 0, 0),
            parentFramePosition=parent_frame,
            childFramePosition=(0, 0, 0))
        p.changeConstraint(constraint_id, maxForce=100)

      # Make a constraint with i=0. Careful with `parent_frame`!
      if i == num_parts - 1:
        parent_frame = bead_positions_l[0] - bead_position
        constraint_id = p.createConstraint(
            parentBodyUniqueId=part_id,
            parentLinkIndex=-1,
            childBodyUniqueId=beads[0],
            childLinkIndex=-1,
            jointType=p.JOINT_POINT2POINT,
            jointAxis=(0, 0, 0),
            parentFramePosition=parent_frame,
            childFramePosition=(0, 0, 0))
        p.changeConstraint(constraint_id, maxForce=100)

      # Create constraint between a bead and certain bag vertices.
      _ = p.createSoftBodyAnchor(
          softBodyBodyUniqueId=self.bag_id,
          nodeIndex=bag_vidx,
          bodyUniqueId=part_id,
          linkIndex=-1)

      # Track beads.
      beads.append(part_id)
      bead_positions_l.append(bead_position)

      # Add objects in a consistent manner.
      self.cable_bead_ids.append(part_id)
      env.objects.append(part_id)
      self.object_points[part_id] = np.float32((0, 0, 0)).reshape(3, 1)
Ejemplo n.º 12
0
    def render(self):
        """
        Render this instance
        """
        if self.renderer is None:
            return

        # softbody: reload vertex position
        if self.softbody:
            # construct new vertex position into shape format
            object_idx = self.object.VAO_ids[0]
            vertices = p.getMeshData(self.pybullet_uuid)[1]
            vertices_flattened = [
                item for sublist in vertices for item in sublist
            ]
            vertex_position = np.array(vertices_flattened).reshape(
                (len(vertices_flattened) // 3, 3))
            shape = self.renderer.shapes[object_idx]
            n_indices = len(shape.mesh.indices)
            np_indices = shape.mesh.numpy_indices().reshape((n_indices, 3))
            shape_vertex_index = np_indices[:, 0]
            shape_vertex = vertex_position[shape_vertex_index]

            # update new vertex position in buffer data
            new_data = self.renderer.vertex_data[object_idx]
            new_data[:, 0:shape_vertex.shape[1]] = shape_vertex
            new_data = new_data.astype(np.float32)

            # transform and rotation already included in mesh data
            self.pose_trans = np.eye(4)
            self.pose_rot = np.eye(4)

            # update buffer data into VBO
            self.renderer.r.render_softbody_instance(
                self.renderer.VAOs[object_idx], self.renderer.VBOs[object_idx],
                new_data)

        self.renderer.r.initvar_instance(self.renderer.shaderProgram,
                                         self.renderer.V, self.renderer.P,
                                         self.pose_trans, self.pose_rot,
                                         self.renderer.lightpos,
                                         self.renderer.lightcolor)

        for object_idx in self.object.VAO_ids:
            self.renderer.r.init_material_instance(
                self.renderer.shaderProgram,
                float(self.class_id) / 255.0, self.renderer.materials_mapping[
                    self.renderer.mesh_materials[object_idx]].kd,
                float(self.renderer.materials_mapping[
                    self.renderer.mesh_materials[object_idx]].is_texture()))
            try:
                texture_id = self.renderer.materials_mapping[
                    self.renderer.mesh_materials[object_idx]].texture_id
                if texture_id is None:
                    texture_id = -1

                if self.renderer.msaa:
                    buffer = self.renderer.fbo_ms
                else:
                    buffer = self.renderer.fbo

                self.renderer.r.draw_elements_instance(
                    self.renderer.materials_mapping[
                        self.renderer.mesh_materials[object_idx]].is_texture(),
                    texture_id, self.renderer.texUnitUniform,
                    self.renderer.VAOs[object_idx],
                    self.renderer.faces[object_idx].size,
                    self.renderer.faces[object_idx], buffer)
            finally:
                self.renderer.r.cglBindVertexArray(0)

        self.renderer.r.cglUseProgram(0)
Ejemplo n.º 13
0
clothId = p.loadSoftBody("cloth_z_up.obj", basePosition=[0, 0, 2], scale=0.5, mass=1., useNeoHookean=0,
                         useBendingSprings=1, useMassSpring=1, springElasticStiffness=40, springDampingStiffness=.1,
                         springDampingAllDirections=1, useSelfCollision=0, frictionCoeff=.5, useFaceContact=1)

p.changeVisualShape(clothId, -1, flags=p.VISUAL_SHAPE_DOUBLE_SIDED)

p.createSoftBodyAnchor(clothId, 24, -1, -1)
p.createSoftBodyAnchor(clothId, 20, -1, -1)
p.createSoftBodyAnchor(clothId, 15, boxId, -1, [0.5, -0.5, 0])
p.createSoftBodyAnchor(clothId, 19, boxId, -1, [-0.5, -0.5, 0])
p.setPhysicsEngineParameter(sparseSdfVoxelSize=0.25)

debug = True
if debug:
    data = p.getMeshData(clothId, -1, flags=p.MESH_DATA_SIMULATION_MESH)
    print("--------------")
    print("data=", data)
    print(data[0])
    print(data[1])
    text_uid = []
    for i in range(data[0]):
        pos = data[1][i]
        uid = p.addUserDebugText(str(i), pos, textColorRGB=[1, 1, 1])
        text_uid.append(uid)

while p.isConnected():
    p.getCameraImage(320, 200)

    if debug:
        data = p.getMeshData(clothId, -1, flags=p.MESH_DATA_SIMULATION_MESH)
Ejemplo n.º 14
0
    def render(self):
        """
        Render this instance
        """
        if self.renderer is None:
            return

        # softbody: reload vertex position
        if self.softbody:
            # construct new vertex position into shape format
            object_idx = self.object.VAO_ids[0]
            vertices = p.getMeshData(self.pybullet_uuid)[1]
            vertices_flattened = [
                item for sublist in vertices for item in sublist
            ]
            vertex_position = np.array(vertices_flattened).reshape(
                (len(vertices_flattened) // 3, 3))
            shape = self.renderer.shapes[object_idx]
            n_indices = len(shape.mesh.indices)
            np_indices = shape.mesh.numpy_indices().reshape((n_indices, 3))
            shape_vertex_index = np_indices[:, 0]
            shape_vertex = vertex_position[shape_vertex_index]

            # update new vertex position in buffer data
            new_data = self.renderer.vertex_data[object_idx]
            new_data[:, 0:shape_vertex.shape[1]] = shape_vertex
            new_data = new_data.astype(np.float32)

            # transform and rotation already included in mesh data
            self.pose_trans = np.eye(4)
            self.pose_rot = np.eye(4)

            # update buffer data into VBO
            self.renderer.r.render_softbody_instance(
                self.renderer.VAOs[object_idx], self.renderer.VBOs[object_idx],
                new_data)

        # print(self.renderer.camera, self.renderer.target, self.renderer.up)
        v_array = []  # posZ, negZ
        forward_dir = [
            self.renderer.target[0] - self.renderer.camera[0],
            self.renderer.target[1] - self.renderer.camera[1],
            self.renderer.target[2] - self.renderer.camera[2]
        ]
        target_array = [
            [
                self.renderer.camera[0] + forward_dir[1],
                self.renderer.camera[1] - forward_dir[0],
                self.renderer.camera[2]
            ],
            [
                self.renderer.camera[0] - forward_dir[1],
                self.renderer.camera[1] + forward_dir[0],
                self.renderer.camera[2]
            ],
            # [self.renderer.camera[0], self.renderer.camera[1], self.renderer.camera[2] - 1], # dir = (0, 1, 0)
            # [self.renderer.camera[0], self.renderer.camera[1], self.renderer.camera[2] + 1], # dir = (0, 1, 0)
            [
                self.renderer.camera[0], self.renderer.camera[1],
                self.renderer.camera[2] - 1
            ],  # dir = (1, 0, 0)
            [
                self.renderer.camera[0], self.renderer.camera[1],
                self.renderer.camera[2] + 1
            ],  # dir = (1, 0, 0)
            [
                self.renderer.camera[0] + forward_dir[0],
                self.renderer.camera[1] + forward_dir[1],
                self.renderer.camera[2]
            ],
            [
                self.renderer.camera[0] - forward_dir[0],
                self.renderer.camera[1] - forward_dir[1],
                self.renderer.camera[2]
            ]
        ]

        up_array = [
            [0, 0, 1],
            [0, 0, 1],
            # [-1, 0, 0], # dir = (0, 1, 0)
            # [ 1, 0, 0], # dir = (0, 1, 0)
            [forward_dir[0], forward_dir[1], 0],  # dir = (1, 0, 0)
            [-forward_dir[0], -forward_dir[1], 0],  # dir = (1, 0, 0)
            [0, 0, 1],
            [0, 0, 1]
        ]

        for i in range(6):
            _camera = self.renderer.camera
            _target = target_array[i]
            _up = up_array[i]
            v_array.append(
                np.ascontiguousarray(lookat(_camera, _target, up=_up),
                                     dtype=np.float32))

        V_array = np.ascontiguousarray(np.array(v_array), dtype=np.float32)

        if self.renderer.pano:
            self.renderer.r.initvar_instance_cubemap(
                self.renderer.shaderProgram, V_array, self.renderer.P,
                self.pose_trans, self.pose_rot, self.renderer.lightpos,
                self.renderer.lightcolor)
        else:
            self.renderer.r.initvar_instance(self.renderer.shaderProgram,
                                             self.renderer.V, self.renderer.P,
                                             self.pose_trans, self.pose_rot,
                                             self.renderer.lightpos,
                                             self.renderer.lightcolor)

        for object_idx in self.object.VAO_ids:
            self.renderer.r.init_material_instance(
                self.renderer.shaderProgram,
                float(self.class_id) / 255.0, self.renderer.materials_mapping[
                    self.renderer.mesh_materials[object_idx]].kd,
                float(self.renderer.materials_mapping[
                    self.renderer.mesh_materials[object_idx]].is_texture()))
            try:
                texture_id = self.renderer.materials_mapping[
                    self.renderer.mesh_materials[object_idx]].texture_id
                if texture_id is None:
                    texture_id = -1

                if self.renderer.msaa:
                    buffer = self.renderer.fbo_ms
                else:
                    buffer = self.renderer.fbo

                self.renderer.r.draw_elements_instance(
                    self.renderer.materials_mapping[
                        self.renderer.mesh_materials[object_idx]].is_texture(),
                    texture_id, self.renderer.texUnitUniform,
                    self.renderer.VAOs[object_idx],
                    self.renderer.faces[object_idx].size,
                    self.renderer.faces[object_idx], buffer)
            finally:
                self.renderer.r.cglBindVertexArray(0)

        self.renderer.r.cglUseProgram(0)