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():
|
||||
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:
|
||||
def __init__(self):
|
||||
self.position = (0.0, 0.0, 0.0)
|
||||
@@ -279,8 +298,8 @@ class BattleMap:
|
||||
def __init__(self):
|
||||
self.atlases = []
|
||||
self.batches = []
|
||||
self.collisionGeometry = []
|
||||
self.collisionGeometryOutsideGamingZone = []
|
||||
self.collisionGeometry = None
|
||||
self.collisionGeometryOutsideGamingZone = None
|
||||
self.materials = []
|
||||
self.spawnPoints = []
|
||||
self.staticGeometry = []
|
||||
|
||||
@@ -22,6 +22,8 @@ SOFTWARE.
|
||||
|
||||
from json import load
|
||||
|
||||
import bpy
|
||||
|
||||
from .A3D import A3D
|
||||
from .A3DBlenderImporter import A3DBlenderImporter
|
||||
|
||||
@@ -67,20 +69,61 @@ class BattleMapBlenderImporter:
|
||||
# Allows subsequent map loads to be faster
|
||||
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.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):
|
||||
print("Importing BattleMap data into blender")
|
||||
|
||||
# Load props
|
||||
propObjects = []
|
||||
if self.import_static_geom:
|
||||
# Load props
|
||||
for propData in self.mapData.staticGeometry:
|
||||
ob = self.getBlenderProp(propData)
|
||||
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)
|
||||
|
||||
return propObjects
|
||||
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):
|
||||
# First check if we've already loaded the required prop library
|
||||
@@ -103,3 +146,62 @@ class BattleMapBlenderImporter:
|
||||
propOB.scale = propData.scale
|
||||
|
||||
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)
|
||||
|
||||
def draw(self, context):
|
||||
import_panel_options(self.layout, self)
|
||||
import_panel_options_a3d(self.layout, self)
|
||||
|
||||
def 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'})
|
||||
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):
|
||||
pass
|
||||
import_panel_options_battlemap(self.layout, self)
|
||||
|
||||
def invoke(self, context, event):
|
||||
return ImportHelper.invoke(self, context, event)
|
||||
@@ -114,8 +119,8 @@ class ImportBattleMap(Operator, ImportHelper):
|
||||
mapData.read(file)
|
||||
|
||||
# Import data into blender
|
||||
preferences = context.preferences.addons[__package__].preferences
|
||||
mapImporter = BattleMapBlenderImporter(mapData, preferences.propLibrarySourcePath)
|
||||
preferences = context.preferences.addons[__package__].preferences # TODO: check if this is set before proceeding
|
||||
mapImporter = BattleMapBlenderImporter(mapData, preferences.propLibrarySourcePath, self.import_static_geom, self.import_collision_geom, self.import_spawn_points)
|
||||
objects = mapImporter.importData()
|
||||
|
||||
# Link objects
|
||||
@@ -128,7 +133,7 @@ class ImportBattleMap(Operator, ImportHelper):
|
||||
'''
|
||||
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.label(text="Options")
|
||||
if body:
|
||||
@@ -136,6 +141,14 @@ def import_panel_options(layout, operator):
|
||||
body.prop(operator, "try_import_textures")
|
||||
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):
|
||||
self.layout.operator(ImportA3D.bl_idname, text="Alternativa3D HTML5 (.a3d)")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user