mirror of
https://github.com/MapMakersAndProgrammers/io_scene_a3d.git
synced 2025-10-26 01:49:13 -07:00
Import spawnpoints and some collision geometry
This commit is contained in:
@@ -235,6 +235,25 @@ class Material:
|
|||||||
if optionalMask.getOptional():
|
if optionalMask.getOptional():
|
||||||
self.vector4Parameters = AlternativaProtocol.readObjectArray(stream, Vector4Parameter, optionalMask)
|
self.vector4Parameters = AlternativaProtocol.readObjectArray(stream, Vector4Parameter, optionalMask)
|
||||||
|
|
||||||
|
#TODO: tanki has more than this number of spawn types now, investigate it
|
||||||
|
BATTLEMAP_SPAWNPOINTTYPE_DM = 0
|
||||||
|
BATTLEMAP_SPAWNPOINTTYPE_DOM_TEAMA = 1
|
||||||
|
BATTLEMAP_SPAWNPOINTTYPE_DOM_TEAMB = 2
|
||||||
|
BATTLEMAP_SPAWNPOINTTYPE_RUGBY_TEAMA = 3
|
||||||
|
BATTLEMAP_SPAWNPOINTTYPE_RUGBY_TEAMB = 4
|
||||||
|
BATTLEMAP_SPAWNPOINTTYPE_TEAMA = 5
|
||||||
|
BATTLEMAP_SPAWNPOINTTYPE_TEAMB = 6
|
||||||
|
BATTLEMAP_SPAWNPOINTTYPE_UNKNOWN = 7
|
||||||
|
BattleMapSpawnPointTypeName = {
|
||||||
|
BATTLEMAP_SPAWNPOINTTYPE_DM: "Deathmatch",
|
||||||
|
BATTLEMAP_SPAWNPOINTTYPE_DOM_TEAMA: "DominationTeamA",
|
||||||
|
BATTLEMAP_SPAWNPOINTTYPE_DOM_TEAMB: "DominationTeamB",
|
||||||
|
BATTLEMAP_SPAWNPOINTTYPE_RUGBY_TEAMA: "RugbyTeamA",
|
||||||
|
BATTLEMAP_SPAWNPOINTTYPE_RUGBY_TEAMB: "RugbyTeamB",
|
||||||
|
BATTLEMAP_SPAWNPOINTTYPE_TEAMA: "TeamA",
|
||||||
|
BATTLEMAP_SPAWNPOINTTYPE_TEAMB: "TeamB",
|
||||||
|
BATTLEMAP_SPAWNPOINTTYPE_UNKNOWN: "Unknown"
|
||||||
|
}
|
||||||
class SpawnPoint:
|
class SpawnPoint:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.position = (0.0, 0.0, 0.0)
|
self.position = (0.0, 0.0, 0.0)
|
||||||
@@ -279,8 +298,8 @@ class BattleMap:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.atlases = []
|
self.atlases = []
|
||||||
self.batches = []
|
self.batches = []
|
||||||
self.collisionGeometry = []
|
self.collisionGeometry = None
|
||||||
self.collisionGeometryOutsideGamingZone = []
|
self.collisionGeometryOutsideGamingZone = None
|
||||||
self.materials = []
|
self.materials = []
|
||||||
self.spawnPoints = []
|
self.spawnPoints = []
|
||||||
self.staticGeometry = []
|
self.staticGeometry = []
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ SOFTWARE.
|
|||||||
|
|
||||||
from json import load
|
from json import load
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
|
||||||
from .A3D import A3D
|
from .A3D import A3D
|
||||||
from .A3DBlenderImporter import A3DBlenderImporter
|
from .A3DBlenderImporter import A3DBlenderImporter
|
||||||
|
|
||||||
@@ -67,20 +69,61 @@ class BattleMapBlenderImporter:
|
|||||||
# Allows subsequent map loads to be faster
|
# Allows subsequent map loads to be faster
|
||||||
libraryCache = {}
|
libraryCache = {}
|
||||||
|
|
||||||
def __init__(self, mapData, propLibrarySourcePath):
|
def __init__(self, mapData, propLibrarySourcePath, import_static_geom=True, import_collision_geom=False, import_spawn_points=False):
|
||||||
self.mapData = mapData
|
self.mapData = mapData
|
||||||
self.propLibrarySourcePath = propLibrarySourcePath
|
self.propLibrarySourcePath = propLibrarySourcePath
|
||||||
|
self.import_static_geom = import_static_geom
|
||||||
|
self.import_collision_geom = import_collision_geom
|
||||||
|
self.import_spawn_points = import_spawn_points
|
||||||
|
|
||||||
def importData(self):
|
def importData(self):
|
||||||
print("Importing BattleMap data into blender")
|
print("Importing BattleMap data into blender")
|
||||||
|
|
||||||
# Load props
|
|
||||||
propObjects = []
|
propObjects = []
|
||||||
for propData in self.mapData.staticGeometry:
|
if self.import_static_geom:
|
||||||
ob = self.getBlenderProp(propData)
|
# Load props
|
||||||
propObjects.append(ob)
|
for propData in self.mapData.staticGeometry:
|
||||||
|
ob = self.getBlenderProp(propData)
|
||||||
return propObjects
|
propObjects.append(ob)
|
||||||
|
collisionObjects = []
|
||||||
|
if self.import_collision_geom:
|
||||||
|
# Load collision meshes
|
||||||
|
collisionTriangles = self.mapData.collisionGeometry.triangles + self.mapData.collisionGeometryOutsideGamingZone.triangles
|
||||||
|
collisionTriangleObjects = self.createBlenderCollisionTriangles(collisionTriangles)
|
||||||
|
collisionPlanes = self.mapData.collisionGeometry.planes + self.mapData.collisionGeometryOutsideGamingZone.planes
|
||||||
|
collisionPlaneObjects = self.createBlenderCollisionPlanes(collisionPlanes)
|
||||||
|
collisionBoxes = self.mapData.collisionGeometry.boxes + self.mapData.collisionGeometryOutsideGamingZone.boxes
|
||||||
|
collisionBoxObjects = self.createBlenderCollisionBoxes(collisionBoxes)
|
||||||
|
|
||||||
|
collisionObjects += collisionTriangleObjects
|
||||||
|
collisionObjects += collisionPlaneObjects
|
||||||
|
collisionObjects += collisionBoxObjects
|
||||||
|
spawnPointObjects = []
|
||||||
|
if self.import_spawn_points:
|
||||||
|
# Create spawn points
|
||||||
|
for spawnPointData in self.mapData.spawnPoints:
|
||||||
|
ob = self.createBlenderSpawnPoint(spawnPointData)
|
||||||
|
spawnPointObjects.append(ob)
|
||||||
|
|
||||||
|
# Create empty objects to house each type of object
|
||||||
|
objects = propObjects + collisionObjects + spawnPointObjects
|
||||||
|
if self.import_static_geom:
|
||||||
|
groupOB = bpy.data.objects.new("StaticGeometry", None)
|
||||||
|
objects.append(groupOB)
|
||||||
|
for ob in propObjects:
|
||||||
|
ob.parent = groupOB
|
||||||
|
if self.import_collision_geom:
|
||||||
|
groupOB = bpy.data.objects.new("CollisionGeometry", None)
|
||||||
|
objects.append(groupOB)
|
||||||
|
for ob in collisionObjects:
|
||||||
|
ob.parent = groupOB
|
||||||
|
if self.import_spawn_points:
|
||||||
|
groupOB = bpy.data.objects.new("SpawnPoints", None)
|
||||||
|
objects.append(groupOB)
|
||||||
|
for ob in spawnPointObjects:
|
||||||
|
ob.parent = groupOB
|
||||||
|
|
||||||
|
return objects
|
||||||
|
|
||||||
def getBlenderProp(self, propData):
|
def getBlenderProp(self, propData):
|
||||||
# First check if we've already loaded the required prop library
|
# First check if we've already loaded the required prop library
|
||||||
@@ -102,4 +145,63 @@ class BattleMapBlenderImporter:
|
|||||||
propOB.rotation_euler = propData.rotation
|
propOB.rotation_euler = propData.rotation
|
||||||
propOB.scale = propData.scale
|
propOB.scale = propData.scale
|
||||||
|
|
||||||
return propOB
|
return propOB
|
||||||
|
|
||||||
|
def createBlenderCollisionTriangles(self, collisionTriangles):
|
||||||
|
objects = []
|
||||||
|
for collisionTriangle in collisionTriangles:
|
||||||
|
# Create the mesh
|
||||||
|
me = bpy.data.meshes.new("collisionTriangle")
|
||||||
|
|
||||||
|
# Create array for coordinate data, blender doesn't like tuples
|
||||||
|
vertices = []
|
||||||
|
vertices += collisionTriangle.v0
|
||||||
|
vertices += collisionTriangle.v1
|
||||||
|
vertices += collisionTriangle.v2
|
||||||
|
|
||||||
|
# Assign coordinates
|
||||||
|
me.vertices.add(3)
|
||||||
|
me.vertices.foreach_set("co", vertices)
|
||||||
|
me.loops.add(3)
|
||||||
|
me.loops.foreach_set("vertex_index", [0, 1, 2])
|
||||||
|
me.polygons.add(1)
|
||||||
|
me.polygons.foreach_set("loop_start", [0])
|
||||||
|
|
||||||
|
me.validate()
|
||||||
|
me.update()
|
||||||
|
|
||||||
|
# Create object
|
||||||
|
ob = bpy.data.objects.new("collisionTriangle", me)
|
||||||
|
ob.location = collisionTriangle.position
|
||||||
|
ob.rotation_mode = "XYZ"
|
||||||
|
ob.rotation_euler = collisionTriangle.rotation
|
||||||
|
#print(collisionTriangle.length) # XXX: how to handle collisionTriangle.length?
|
||||||
|
|
||||||
|
objects.append(ob)
|
||||||
|
|
||||||
|
return objects
|
||||||
|
|
||||||
|
def createBlenderCollisionPlanes(self, collisionPlanes):
|
||||||
|
objects = []
|
||||||
|
for collisionPlane in collisionPlanes:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return objects
|
||||||
|
|
||||||
|
def createBlenderCollisionBoxes(self, collisionBoxes):
|
||||||
|
objects = []
|
||||||
|
for collisionBox in collisionBoxes:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return objects
|
||||||
|
|
||||||
|
def createBlenderSpawnPoint(self, spawnPointData):
|
||||||
|
#TODO: implement spawn type name lookup
|
||||||
|
ob = bpy.data.objects.new(f"SpawnPoint_{spawnPointData.type}", None)
|
||||||
|
ob.empty_display_type = "ARROWS"
|
||||||
|
ob.empty_display_size = 100
|
||||||
|
ob.location = spawnPointData.position
|
||||||
|
ob.rotation_mode = "XYZ"
|
||||||
|
ob.rotation_euler = spawnPointData.rotation
|
||||||
|
|
||||||
|
return ob
|
||||||
@@ -63,7 +63,7 @@ class ImportA3D(Operator, ImportHelper):
|
|||||||
reset_empty_transform: BoolProperty(name="Reset empty transforms", description="Reset rotation and scale if it is set to 0, more useful for version 2 models like props", default=True)
|
reset_empty_transform: BoolProperty(name="Reset empty transforms", description="Reset rotation and scale if it is set to 0, more useful for version 2 models like props", default=True)
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
import_panel_options(self.layout, self)
|
import_panel_options_a3d(self.layout, self)
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
return ImportHelper.invoke(self, context, event)
|
return ImportHelper.invoke(self, context, event)
|
||||||
@@ -101,8 +101,13 @@ class ImportBattleMap(Operator, ImportHelper):
|
|||||||
filter_glob: StringProperty(default="*.bin", options={'HIDDEN'})
|
filter_glob: StringProperty(default="*.bin", options={'HIDDEN'})
|
||||||
directory: StringProperty(subtype="DIR_PATH", options={'HIDDEN'})
|
directory: StringProperty(subtype="DIR_PATH", options={'HIDDEN'})
|
||||||
|
|
||||||
|
# User options
|
||||||
|
import_static_geom: BoolProperty(name="Import static geometry", description="Static geometry includes all the visual aspects of the map", default=True)
|
||||||
|
import_collision_geom: BoolProperty(name="Import collision geometry", description="Collision geometry defines the geometry used for collision checks and cannot normally be seen by players", default=False)
|
||||||
|
import_spawn_points: BoolProperty(name="Import spawn points", description="Places a marker at locations where tanks can spawn", default=False)
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
pass
|
import_panel_options_battlemap(self.layout, self)
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
return ImportHelper.invoke(self, context, event)
|
return ImportHelper.invoke(self, context, event)
|
||||||
@@ -114,8 +119,8 @@ class ImportBattleMap(Operator, ImportHelper):
|
|||||||
mapData.read(file)
|
mapData.read(file)
|
||||||
|
|
||||||
# Import data into blender
|
# Import data into blender
|
||||||
preferences = context.preferences.addons[__package__].preferences
|
preferences = context.preferences.addons[__package__].preferences # TODO: check if this is set before proceeding
|
||||||
mapImporter = BattleMapBlenderImporter(mapData, preferences.propLibrarySourcePath)
|
mapImporter = BattleMapBlenderImporter(mapData, preferences.propLibrarySourcePath, self.import_static_geom, self.import_collision_geom, self.import_spawn_points)
|
||||||
objects = mapImporter.importData()
|
objects = mapImporter.importData()
|
||||||
|
|
||||||
# Link objects
|
# Link objects
|
||||||
@@ -128,7 +133,7 @@ class ImportBattleMap(Operator, ImportHelper):
|
|||||||
'''
|
'''
|
||||||
Menu
|
Menu
|
||||||
'''
|
'''
|
||||||
def import_panel_options(layout, operator):
|
def import_panel_options_a3d(layout, operator):
|
||||||
header, body = layout.panel("alternativa_import_options", default_closed=False)
|
header, body = layout.panel("alternativa_import_options", default_closed=False)
|
||||||
header.label(text="Options")
|
header.label(text="Options")
|
||||||
if body:
|
if body:
|
||||||
@@ -136,6 +141,14 @@ def import_panel_options(layout, operator):
|
|||||||
body.prop(operator, "try_import_textures")
|
body.prop(operator, "try_import_textures")
|
||||||
body.prop(operator, "reset_empty_transform")
|
body.prop(operator, "reset_empty_transform")
|
||||||
|
|
||||||
|
def import_panel_options_battlemap(layout, operator):
|
||||||
|
header, body = layout.panel("tanki_battlemap_import_options", default_closed=False)
|
||||||
|
header.label(text="Options")
|
||||||
|
if body:
|
||||||
|
body.prop(operator, "import_static_geom")
|
||||||
|
body.prop(operator, "import_collision_geom")
|
||||||
|
body.prop(operator, "import_spawn_points")
|
||||||
|
|
||||||
def menu_func_import_a3d(self, context):
|
def menu_func_import_a3d(self, context):
|
||||||
self.layout.operator(ImportA3D.bl_idname, text="Alternativa3D HTML5 (.a3d)")
|
self.layout.operator(ImportA3D.bl_idname, text="Alternativa3D HTML5 (.a3d)")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user