-
Notifications
You must be signed in to change notification settings - Fork 7
/
JARoffImport.py
100 lines (83 loc) · 3.87 KB
/
JARoffImport.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import bpy
import math
import struct
### The ROFF Import operator ###
class Operator(bpy.types.Operator):
# everything is scaled down by this factor
SCALE = 10
bl_idname = "import_scene.ja_roff"
bl_label = "Import JA ROFF (.rof)"
# gets set by the file select window - internal Blender Magic or whatever.
filepath: bpy.props.StringProperty(
name="File Path", description="File path used for importing the ROFF file", maxlen=1024, default="") # type: ignore
def execute(self, context):
self.ImportStart()
return {'FINISHED'}
def invoke(self, context, event):
windowMan = context.window_manager
# sets self.properties.filename and runs self.execute()
windowMan.fileselect_add(self)
return {'RUNNING_MODAL'}
def ImportStart(self):
filename = bpy.path.ensure_ext(self.filepath, ".rof")
objlist = bpy.context.selected_objects
if len(objlist) != 1:
self.report({"ERROR"}, "Please select exactly one object!")
return
obj = objlist[0]
try:
file = open(filename, "rb")
# I don't know what the last 4 bytes are, they (nearly) always contain (int) 0 (once it was 7, once 8...)
ident, version, frames, frameDuration = struct.unpack(
"4s3i4x", file.read(20))
if ident != b"ROFF":
self.report({"ERROR"}, "That's no ROFF file!")
return
if version != 2:
self.report(
{"ERROR"}, "Wrong ROFF version, only 2 is supported! (file is "+str(version)+")")
return
if obj.rotation_mode != "XYZ":
self.report(
{"ERROR"}, "Object's rotation mode is not XYZ, I can't handle that, sorry.! (It's "+obj.rotation_mode+")")
return
scn = bpy.context.scene
scn.frame_start = 0
scn.frame_end = frames
scn.frame_current = 0
scn.render.fps = 1000/frameDuration # supposedly read-only?
# add keyframe at frame 0 with current position
obj.keyframe_insert("location")
obj.keyframe_insert("rotation_euler")
for frame in range(frames):
# set the current frame
scn.frame_current = frame + 1
# I don't know what the last 8 bytes are, they always contain 0xFFFFFFFF00000000 (-1 & 0) - I trash them.
dx, dy, dz, droty, drotz, drotx = struct.unpack(
"6f8x", file.read(32))
# translate the object (it's the only selected object so the operators operate on it)
bpy.ops.transform.translate(
value=(dx/self.SCALE, dy/self.SCALE, dz/self.SCALE))
# rotate the object - unsure how to do the rotations using bpy.ops.transform.rotate
# (Blender now uses Radians. Deal with it.)
drot = drotx, droty, drotz
obj.rotation_euler[0] = obj.rotation_euler[0] + \
math.radians(drotx)
obj.rotation_euler[1] = obj.rotation_euler[1] + \
math.radians(droty)
obj.rotation_euler[2] = obj.rotation_euler[2] + \
math.radians(drotz)
# save keyframe
obj.keyframe_insert("location")
obj.keyframe_insert("rotation_euler")
# back to frame 0
scn.frame_current = 0
# set the interpolation to linear
for curve in obj.animation_data.action.fcurves:
for point in curve.keyframe_points:
point.interpolation = "LINEAR"
except IOError:
self.report({"ERROR"}, "Couldn't open file!")
return
def menu_func(self, context):
self.layout.operator(Operator.bl_idname, text="JA ROFF (.rof)")