def export_uv_controller(self, b_material, n_geom): """Export the material UV controller data.""" # get fcurves - a bit more elaborate here so we can zip with the NiUVData later # nb. these are actually specific to the texture slot in blender # here we don't care and just take the first fcurve that matches fcurves = [] for dp, ind in (("offset", 0), ("offset", 1), ("scale", 0), ("scale", 1)): for fcu in b_material.animation_data.action.fcurves: if dp in fcu.data_path and fcu.array_index == ind: fcurves.append(fcu) break else: fcurves.append(None) # continue if at least one fcurve exists if not any(fcurves): return # get the uv curves and translate them into nif data n_uv_data = NifFormat.NiUVData() for fcu, n_uv_group in zip(fcurves, n_uv_data.uv_groups): if fcu: NifLog.debug(f"Exporting {fcu} as NiUVData") n_uv_group.num_keys = len(fcu.keyframe_points) n_uv_group.interpolation = NifFormat.KeyType.LINEAR_KEY n_uv_group.keys.update_size() for b_point, n_key in zip(fcu.keyframe_points, n_uv_group.keys): # add each point of the curve b_frame, b_value = b_point.co if "offset" in fcu.data_path: # offsets are negated in blender b_value = -b_value n_key.arg = n_uv_group.interpolation n_key.time = b_frame / self.fps n_key.value = b_value # if uv data is present then add the controller so it is exported if fcurves[0].keyframe_points: n_uv_ctrl = NifFormat.NiUVController() self.set_flags_and_timing(n_uv_ctrl, fcurves) n_uv_ctrl.data = n_uv_data # attach block to geometry n_geom.add_controller(n_uv_ctrl)
def export_material_uv_controller(self, b_material, n_geom): """Export the material UV controller data.""" # get the material action b_action = b_material.action if not b_action: return # get the uv curves and translate them into nif data n_uvdata = NifFormat.NiUVData() n_times = [] # track all times (used later in start time and end time) b_channels = (Blender.Ipo.MA_OFSX, Blender.Ipo.MA_OFSY, Blender.Ipo.MA_SIZEX, Blender.Ipo.MA_SIZEY) for b_channel, n_uvgroup in zip(b_channels, n_uvdata.uv_groups): b_curve = b_action[b_channel] if b_curve: self.info("Exporting %s as NiUVData" % b_curve) n_uvgroup.num_keys = len(b_curve.bezierPoints) n_uvgroup.interpolation = self.get_n_action_interpolation_from_b_action_interpolation( b_curve.interpolation) n_uvgroup.keys.update_size() for b_point, n_key in zip(b_curve.bezierPoints, n_uvgroup.keys): # add each point of the curve b_time, b_value = b_point.pt if b_channel in (Blender.Ipo.MA_OFSX, Blender.Ipo.MA_OFSY): # offsets are negated in blender b_value = -b_value n_key.arg = n_uvgroup.interpolation n_key.time = (b_time - 1) * self.context.scene.render.fps n_key.value = b_value # track time n_times.append(n_key.time) # save extend mode to export later b_curve_extend = b_curve.extend # if uv data is present (we check this by checking if times were added) # then add the controller so it is exported if n_times: n_uvctrl = NifFormat.NiUVController() n_uvctrl.flags = 8 # active n_uvctrl.flags |= self.get_flags_from_extend(b_curve_extend) n_uvctrl.frequency = 1.0 n_uvctrl.start_time = min(n_times) n_uvctrl.stop_time = max(n_times) n_uvctrl.data = n_uvdata # attach block to geometry n_geom.add_controller(n_uvctrl)