angus Posted April 30, 2020 Share Posted April 30, 2020 To solve a need we had, the below code will copy Blender keyframe animation to a CSV file. It writes out location and rotation only. Data is stored as XYZ position, Quaternion rotation. Axis conversion is done in the script so the values from the CSV file can be used directly. import bpy import os from math import degrees from bpy_extras.io_utils import axis_conversion def loc_rot_to_file(context, filepath): blender_to_unigine = axis_conversion(from_forward='-Y', from_up='Z', to_forward='Y', to_up='Z').to_4x4() movement_object = bpy.context.selected_objects[0] mw = movement_object.matrix_world scene = context.scene frame = scene.frame_start f = open(filepath, 'w', encoding='utf-8') while frame <= scene.frame_end: scene.frame_set(frame) mw = movement_object.matrix_world mw = blender_to_unigine @ mw x, y, z = mw.to_translation() rw, rx, ry, rz = mw.to_quaternion() f.write("%d" % frame) f.write(", ") f.write("%0.9f, %0.9f, %0.9f" % (x, y, z)) f.write(", ") f.write("%0.9f, %0.9f, %0.9f, %0.9f" % (rw, rx, ry, rz)) f.write("\n") frame += 1 f.close() loc_rot_to_file(bpy.context, "d:/tmp/blenderdata.csv") To use, copy the code in to the "Scripting" panel in Blender, select the object you wish to save out, edit the destination file name and then "Run Script" in Blender to save it out. Warning: only lightly tested. Link to comment
leon.dong Posted May 5, 2020 Share Posted May 5, 2020 Thanks . angus , BTW , how to play keyframe animation in Unigine after export ? Link to comment
angus Posted May 6, 2020 Author Share Posted May 6, 2020 On 5/5/2020 at 10:49 AM, leon.dong said: Thanks . angus , BTW , how to play keyframe animation in Unigine after export ? I load the CSV file in to two Unigine Vectors. std::ifstream infile(movement_filename_full.get()); if (!infile) { Log::error("Error opening [%s]\n", movement_filename_full.get()); assert(false); } int frame = 0; vec3 position; quat rotation; char comma; // File is CSV with frame number, location XYZ, rotation Quat. while (infile >> frame >> comma >> position.x >> comma >> position.y >> comma >> position.z >> comma >> rotation.w >> comma >> rotation.x >> comma >> rotation.y >> comma >> rotation.z) { position *= scaling_factor; thing_positions.push_back((position)); thing_rotations.push_back(rotation); } And then at go-time it's just a case of setting location and rotation on the node thing->setWorldRotation(thing_rotations.at(frame_number)); thing->setWorldPosition(thing_positions.at(frame_number)); Where "frame_number" increments in-line with the frame rate of the original Blender file by adding Game::getIFps() Link to comment
Recommended Posts