Skip to content

Commit f01590f

Browse files
authored
Merge pull request #218 from travnick/develop
Cryblend 5.2 Release
2 parents 9d69f31 + 17ecffe commit f01590f

File tree

7 files changed

+1133
-512
lines changed

7 files changed

+1133
-512
lines changed

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
11
# Changelog:
22

3+
## 5.2
4+
#### Compatibility:
5+
* Only compatible with CryEngine 3.5 and up.
6+
* Only compatible with Blender 2.7 and up.
7+
* Supports primary assets: CGF, CGA, CHR, SKIN, ANM, I_CAF.
8+
* Compatible with LumberYard.
9+
10+
#### UI Changes:
11+
* Added new Animation Node menuitem to create I_CAF and ANM nodes.
12+
* Added new Export Animation menuitem to separate animation and mesh exporting.
13+
14+
#### New Features:
15+
* Support multiple I_CAF and ANM animation files exporting.
16+
* Animation and character nodes can be located in same project.
17+
18+
#### Improvements/Fixes:
19+
* CGA and ANM exporting have been fixed.
20+
* Mesh exporting logs have been improved.
21+
322
## 5.1
423
#### Compatibility:
524
* Only compatible with CryEngine 3.5 and up.

io_export_cryblend/__init__.py

Lines changed: 228 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
"author": "Angelo J. Miner, Duo Oratar, Mikołaj Milej, Daniel White, "
3636
"David Marcelis, Özkan Afacan, Oscar Martin Garcia",
3737
"blender": (2, 70, 0),
38-
"version": (5, 1, 0),
38+
"version": (5, 2, 0),
3939
"location": "CryBlend Menu",
4040
"description": "Export assets from Blender to CryEngine 3",
4141
"warning": "",
@@ -59,7 +59,7 @@
5959
imp.reload(desc)
6060
else:
6161
import bpy
62-
from io_export_cryblend import add, export, exceptions, utils, desc
62+
from io_export_cryblend import add, export, export_animations, exceptions, utils, desc
6363

6464
from bpy.props import BoolProperty, EnumProperty, FloatVectorProperty, \
6565
FloatProperty, IntProperty, StringProperty, BoolVectorProperty
@@ -198,10 +198,6 @@ class AddCryExportNode(bpy.types.Operator):
198198
"Character"),
199199
("skin", "SKIN",
200200
"Skinned Render Mesh"),
201-
("anm", "ANM",
202-
"Geometry Animation"),
203-
("i_caf", "I_CAF",
204-
"Character Animation"),
205201
),
206202
default="cgf",
207203
)
@@ -235,6 +231,106 @@ def invoke(self, context, event):
235231
return context.window_manager.invoke_props_dialog(self)
236232

237233

234+
class AddCryAnimationNode(bpy.types.Operator):
235+
'''Add selected objects to an existing or new CryExportNode'''
236+
bl_label = "Add Animation Node"
237+
bl_idname = "object.add_cry_animation_node"
238+
bl_options = {"REGISTER", "UNDO"}
239+
240+
node_type = EnumProperty(
241+
name="Type",
242+
items=(
243+
("anm", "ANM",
244+
"Geometry Animation"),
245+
("i_caf", "I_CAF",
246+
"Character Animation"),
247+
),
248+
default="i_caf",
249+
)
250+
node_name = StringProperty(name="Animation Name")
251+
node_start = IntProperty(name="Start Frame")
252+
node_end = IntProperty(name="End Frame")
253+
is_use_markers = BoolProperty(name="Use Markers")
254+
start_m_name = StringProperty(name="Marker Start Name")
255+
end_m_name = StringProperty(name="Marker End Name")
256+
257+
def __init__(self):
258+
self.node_start = bpy.context.scene.frame_start
259+
self.node_end = bpy.context.scene.frame_end
260+
261+
if bpy.context.active_object.type == 'ARMATURE':
262+
self.node_type = 'i_caf'
263+
else:
264+
self.node_type = 'anm'
265+
266+
tm = bpy.context.scene.timeline_markers
267+
for marker in tm:
268+
if marker.select:
269+
self.start_m_name = marker.name
270+
self.end_m_name = "{}_E".format(marker.name)
271+
self.is_use_markers = True
272+
273+
self.node_start = marker.frame
274+
if tm.find(self.end_m_name) != -1:
275+
self.node_end = tm[self.end_m_name].frame
276+
277+
self.node_name = marker.name
278+
break
279+
280+
return None
281+
282+
def execute(self, context):
283+
object_ = bpy.context.active_object
284+
if object_:
285+
node_start = None
286+
node_end = None
287+
288+
start_name = "{}_Start".format(self.node_name)
289+
end_name = "{}_End".format(self.node_name)
290+
291+
if self.is_use_markers:
292+
node_start = self.start_m_name
293+
node_end = self.end_m_name
294+
295+
tm = bpy.context.scene.timeline_markers
296+
if tm.find(self.start_m_name) == -1:
297+
tm.new(name=self.start_m_name, frame=self.node_start)
298+
if tm.find(self.end_m_name) == -1:
299+
tm.new(name=self.end_m_name, frame=self.node_end)
300+
else:
301+
node_start = self.node_start
302+
node_end = self.node_end
303+
304+
object_[start_name] = node_start
305+
object_[end_name] = node_end
306+
307+
node_name = "{}.{}".format(self.node_name, self.node_type)
308+
group = bpy.data.groups.get(node_name)
309+
if group is None:
310+
bpy.ops.group.create(name=node_name)
311+
else:
312+
for object in bpy.context.selected_objects:
313+
if object.name not in group.objects:
314+
group.objects.link(object)
315+
316+
message = "Adding Export Node"
317+
else:
318+
message = "There is no a active armature! Please select a armature."
319+
320+
self.report({"INFO"}, message)
321+
return {"FINISHED"}
322+
323+
def invoke(self, context, event):
324+
object_ = bpy.context.active_object
325+
if not object_:
326+
self.report(
327+
{'ERROR'},
328+
"Please select and active a armature or object.")
329+
return {'FINISHED'}
330+
331+
return context.window_manager.invoke_props_dialog(self)
332+
333+
238334
class SelectedToCryExportNodes(bpy.types.Operator):
239335
'''Add selected objects to individual CryExportNodes.'''
240336
bl_label = "Nodes from Object Names"
@@ -1952,6 +2048,115 @@ def draw(self, context):
19522048
box.prop(self, "run_in_profiler")
19532049

19542050

2051+
class ExportAnimations(bpy.types.Operator, ExportHelper):
2052+
'''Export animations to CryEngine'''
2053+
bl_label = "Export Animations"
2054+
bl_idname = "scene.export_animations"
2055+
filename_ext = ".dae"
2056+
filter_glob = StringProperty(default="*.dae", options={'HIDDEN'})
2057+
2058+
do_not_merge = BoolProperty(
2059+
name="Do Not Merge Nodes",
2060+
description="Generally a good idea.",
2061+
default=True,
2062+
)
2063+
export_for_lumberyard = BoolProperty(
2064+
name="Export for LumberYard",
2065+
description="Export for LumberYard engine instead of CryEngine.",
2066+
default=False,
2067+
)
2068+
disable_rc = BoolProperty(
2069+
name="Disable RC",
2070+
description="Do not run the resource compiler.",
2071+
default=False,
2072+
)
2073+
save_dae = BoolProperty(
2074+
name="Save DAE File",
2075+
description="Save the DAE file for developing purposes.",
2076+
default=False,
2077+
)
2078+
run_in_profiler = BoolProperty(
2079+
name="Profile CryBlend",
2080+
description="Select only if you want to profile CryBlend.",
2081+
default=False,
2082+
)
2083+
do_materials = False
2084+
make_layer = False
2085+
2086+
class Config:
2087+
2088+
def __init__(self, config):
2089+
attributes = (
2090+
'filepath',
2091+
'do_not_merge',
2092+
'do_materials',
2093+
'export_for_lumberyard',
2094+
'make_layer',
2095+
'disable_rc',
2096+
'save_dae',
2097+
'run_in_profiler'
2098+
)
2099+
2100+
for attribute in attributes:
2101+
setattr(self, attribute, getattr(config, attribute))
2102+
2103+
setattr(self, 'cryblend_version', VERSION)
2104+
setattr(self, 'rc_path', Configuration.rc_path)
2105+
setattr(self, 'texture_rc_path', Configuration.texture_rc_path)
2106+
setattr(self, 'game_dir', Configuration.game_dir)
2107+
2108+
def execute(self, context):
2109+
cbPrint(Configuration.rc_path, 'debug')
2110+
try:
2111+
config = ExportAnimations.Config(config=self)
2112+
2113+
if self.run_in_profiler:
2114+
import cProfile
2115+
cProfile.runctx(
2116+
'export_animations.save(config)', {}, {
2117+
'export_animations': export_animations, 'config': config})
2118+
else:
2119+
export_animations.save(config)
2120+
2121+
self.filepath = '//'
2122+
2123+
except exceptions.CryBlendException as exception:
2124+
cbPrint(exception.what(), 'error')
2125+
bpy.ops.screen.display_error(
2126+
'INVOKE_DEFAULT', message=exception.what())
2127+
2128+
return {'FINISHED'}
2129+
2130+
def invoke(self, context, event):
2131+
if not Configuration.configured():
2132+
self.report({'ERROR'}, "No RC found.")
2133+
return {'FINISHED'}
2134+
2135+
if not utils.get_export_nodes():
2136+
self.report({'ERROR'}, "No export nodes found.")
2137+
return {'FINISHED'}
2138+
2139+
return ExportHelper.invoke(self, context, event)
2140+
2141+
def draw(self, context):
2142+
layout = self.layout
2143+
col = layout.column()
2144+
2145+
box = col.box()
2146+
box.label("General", icon="WORLD")
2147+
box.prop(self, "do_not_merge")
2148+
2149+
box = col.box()
2150+
box.label("LumberYard", icon="GAME")
2151+
box.prop(self, "export_for_lumberyard")
2152+
2153+
box = col.box()
2154+
box.label("Developer Tools", icon="MODIFIER")
2155+
box.prop(self, "disable_rc")
2156+
box.prop(self, "save_dae")
2157+
box.prop(self, "run_in_profiler")
2158+
2159+
19552160
class ErrorHandler(bpy.types.Operator):
19562161
bl_label = "Error:"
19572162
bl_idname = "screen.display_error"
@@ -2013,6 +2218,9 @@ def draw(self, context):
20132218
col.separator()
20142219
row = col.row(align=True)
20152220
row.operator("object.add_cry_export_node", text="Add Export Node")
2221+
row.operator(
2222+
"object.add_cry_animation_node",
2223+
text="Add Animation Node")
20162224
col.operator(
20172225
"object.selected_to_cry_export_nodes",
20182226
text="Export Nodes from Objects")
@@ -2166,6 +2374,10 @@ def draw(self, context):
21662374
col.label("Export", icon="GAME")
21672375
col.separator()
21682376
col.operator("scene.export_to_game", text="Export to Game")
2377+
col.separator()
2378+
col.label("Export Animations", icon="GAME")
2379+
col.separator()
2380+
col.operator("scene.export_animations", text="Export Animations")
21692381

21702382
#------------------------------------------------------------------------------
21712383
# CryBlend Menu:
@@ -2190,9 +2402,14 @@ def draw(self, context):
21902402
"object.add_cry_export_node",
21912403
text="Add Export Node",
21922404
icon="GROUP")
2405+
layout.operator(
2406+
"object.add_cry_animation_node",
2407+
text="Add Animation Node",
2408+
icon="PREVIEW_RANGE")
21932409
layout.operator(
21942410
"object.selected_to_cry_export_nodes",
2195-
text="Export Nodes from Objects")
2411+
text="Export Nodes from Objects",
2412+
icon="SCENE_DATA")
21962413
layout.separator()
21972414
layout.operator(
21982415
"object.apply_transforms",
@@ -2217,6 +2434,8 @@ def draw(self, context):
22172434
layout.separator()
22182435
layout.separator()
22192436
layout.operator("scene.export_to_game", icon="GAME")
2437+
layout.separator()
2438+
layout.operator("scene.export_animations", icon="RENDER_ANIMATION")
22202439

22212440

22222441
class AddPhysicsProxyMenu(bpy.types.Menu):
@@ -2518,6 +2737,7 @@ def get_classes_to_register():
25182737
SaveCryBlendConfiguration,
25192738

25202739
AddCryExportNode,
2740+
AddCryAnimationNode,
25212741
SelectedToCryExportNodes,
25222742
AddMaterial,
25232743
SetMaterialNames,
@@ -2558,6 +2778,7 @@ def get_classes_to_register():
25582778
ApplyAnimationScale,
25592779

25602780
Export,
2781+
ExportAnimations,
25612782
ErrorHandler,
25622783

25632784
ExportUtilitiesPanel,

io_export_cryblend/exceptions.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,11 @@ def __init__(self):
6363
message = "Please select a Game Directory!"
6464

6565
CryBlendException.__init__(self, message)
66+
67+
68+
class MarkersNotFound(CryBlendException):
69+
70+
def __init__(self):
71+
message = "Start or end marker is less!"
72+
73+
CryBlendException.__init__(self, message)

0 commit comments

Comments
 (0)