502 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			502 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!BPY
 | |
| 
 | |
| """
 | |
| Name: 'FLT LOD Editor'
 | |
| Blender: 240
 | |
| Group: 'Misc'
 | |
| Tooltip: 'Level of Detail Edtior for FLT nodes'
 | |
| """
 | |
| 
 | |
| __author__ = "Geoffrey Bantle"
 | |
| __version__ = "1.0 11/21/07"
 | |
| __email__ = ('scripts', 'Author, ')
 | |
| __url__ = ('blender', 'blenderartists.org')
 | |
| 
 | |
| __bpydoc__ ="""\
 | |
| This script provides tools for working with OpenFlight databases in Blender. OpenFlight is a
 | |
| registered trademark of MultiGen-Paradigm, Inc.
 | |
| 
 | |
| Feature overview and more availible at:
 | |
| http://wiki.blender.org/index.php/Scripts/Manual/FLTools
 | |
| """
 | |
| 
 | |
| # --------------------------------------------------------------------------
 | |
| # flt_palettemanager.py version 0.1 2005/04/08
 | |
| # --------------------------------------------------------------------------
 | |
| # ***** BEGIN GPL LICENSE BLOCK *****
 | |
| #
 | |
| # Copyright (C) 2007: Blender Foundation
 | |
| #
 | |
| # This program is free software; you can redistribute it and/or
 | |
| # modify it under the terms of the GNU General Public License
 | |
| # as published by the Free Software Foundation; either version 2
 | |
| # of the License, or (at your option) any later version.
 | |
| #
 | |
| # This program is distributed in the hope that it will be useful,
 | |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| # GNU General Public License for more details.
 | |
| #
 | |
| # You should have received a copy of the GNU General Public License
 | |
| # along with this program; if not, write to the Free Software Foundation,
 | |
| # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 | |
| #
 | |
| # ***** END GPL LICENCE BLOCK *****
 | |
| # --------------------------------------------------------------------------
 | |
| 
 | |
| import Blender.Draw as Draw
 | |
| from Blender.BGL import *
 | |
| import Blender
 | |
| import flt_properties
 | |
| reload(flt_properties)
 | |
| from flt_properties import *
 | |
| 
 | |
| #event codes
 | |
| evcode = {
 | |
| 	"LOD_MAKE" : 100,
 | |
| 	"LOD_DELETE" : 101,
 | |
| 	"LOD_CALC_CENTER" : 102,
 | |
| 	"LOD_GRAB_CENTER" : 103,
 | |
| 	"LOD_X" : 104,
 | |
| 	"LOD_Y" : 105,
 | |
| 	"LOD_Z" : 106,
 | |
| 	"LOD_FREEZE" : 107,
 | |
| 	"LOD_SIG" : 108,
 | |
| 	"LOD_IN" : 109,
 | |
| 	"LOD_OUT" : 110,
 | |
| 	"LOD_TRANS" : 111,		
 | |
| 	"LOD_PREVIOUS" : 112
 | |
| }
 | |
| 
 | |
| 
 | |
| #system
 | |
| LOD_MAKE = None			#PushButton
 | |
| LOD_DELETE = None		#PushButton
 | |
| LOD_CALC_CENTER = None	#PushButton
 | |
| LOD_GRAB_CENTER = None	#Pushbutton
 | |
| LOD_FREEZE = None		#Toggle
 | |
| LOD_PREVIOUS = None		#Toggle
 | |
| 
 | |
| LOD_X = None			#Input
 | |
| LOD_Y = None			#Input
 | |
| LOD_Z = None			#Input
 | |
| 
 | |
| LOD_SIG = None			#Input
 | |
| LOD_IN = None			#Input
 | |
| LOD_OUT = None			#Input
 | |
| LOD_TRANS = None		#Input
 | |
| 
 | |
| #labels
 | |
| LOD_EDITLABEL = None
 | |
| LOD_SWITCHLABEL = None
 | |
| LOD_CENTERLABEL = None
 | |
| 
 | |
| LOD_XLABEL = None
 | |
| LOD_YLABEL = None
 | |
| LOD_ZLABEL = None
 | |
| LOD_SIGLABEL = None
 | |
| LOD_INLABEL = None
 | |
| LOD_OUTLABEL = None
 | |
| LOD_TRANSLABEL = None
 | |
| 
 | |
| 
 | |
| #ID Props
 | |
| switch_in = '5d!switch in'
 | |
| switch_out = '6d!switch out'
 | |
| xco = '10d!X co'
 | |
| yco = '11d!Y co'
 | |
| zco = '12d!Z co'
 | |
| trans = '13d!Transition'
 | |
| sig_size = '14d!Sig Size'
 | |
| 
 | |
| #Flags
 | |
| lodflag = '9I!flags'
 | |
| previous_mask = (1 << 31)
 | |
| freeze_mask = (1 << 29)
 | |
| 
 | |
| def update_state():
 | |
| 	state = dict()
 | |
| 	state["activeScene"] = Blender.Scene.GetCurrent()
 | |
| 	state["activeObject"] = state["activeScene"].objects.active
 | |
| 	if state["activeObject"] and not state["activeObject"].sel:
 | |
| 		state["activeObject"] = None
 | |
| 	state["activeMesh"] = None
 | |
| 	if state["activeObject"] and state["activeObject"].type == 'Mesh':
 | |
| 		state["activeMesh"] = state["activeObject"].getData(mesh=True)
 | |
| 	
 | |
| 	state["activeFace"] = None
 | |
| 	if state["activeMesh"]:
 | |
| 		if state["activeMesh"].faceUV and state["activeMesh"].activeFace != None:
 | |
| 			state["activeFace"] = state["activeMesh"].faces[state["activeMesh"].activeFace]
 | |
| 		
 | |
| 		
 | |
| 	#update editmode
 | |
| 	state["editmode"]	= Blender.Window.EditMode()
 | |
| 
 | |
| 	return state
 | |
| 	
 | |
| def idprops_append(object, typecode, props):
 | |
| 	object.properties["FLT"] = dict()
 | |
| 	object.properties["FLT"]['type'] = typecode 
 | |
| 	for prop in props:
 | |
| 		object.properties["FLT"][prop] = props[prop]
 | |
| 	object.properties["FLT"]['3t8!id'] = object.name
 | |
| 
 | |
| def idprops_kill():
 | |
| 	state = update_state()
 | |
| 	if state["activeObject"] and state["activeObject"].properties.has_key('FLT'):
 | |
| 		state["activeObject"].properties.pop('FLT')
 | |
| 
 | |
| def idprops_copy(source):
 | |
| 	state = update_state()
 | |
| 	if source.properties.has_key('FLT'):
 | |
| 		for object in state["activeScene"].objects:
 | |
| 			if object.sel and object != source and (state["activeScene"].Layers & object.Layers):
 | |
| 				idprops_kill(object)
 | |
| 				object.properties['FLT'] = dict()
 | |
| 				for key in source.properties['FLT']:
 | |
| 					object.properties['FLT'][key] = source.properties['FLT'][key]
 | |
| 
 | |
| def select_by_typecode(typecode):
 | |
| 	state = update_state()
 | |
| 	
 | |
| 	for object in state["activeScene"].objects:
 | |
| 		if object.properties.has_key('FLT') and object.properties['FLT']['type'] == typecode and state["activeScene"].Layers & object.Layers:
 | |
| 				object.select(1)
 | |
| 
 | |
| def idprops_type(object, typecode):
 | |
| 	if object.properties.has_key('FLT') and object.properties['FLT'].has_key('type') and object.properties['FLT']['type'] == typecode:
 | |
| 		return True
 | |
| 	return False
 | |
| 
 | |
| #ui type code
 | |
| def get_prop(typecode, prop):
 | |
| 	
 | |
| 	state = update_state()
 | |
| 	if state["activeObject"] and idprops_type(state["activeObject"], typecode):
 | |
| 		props = state["activeObject"].properties['FLT']
 | |
| 	else:
 | |
| 		props =  flt_properties.FLTLOD
 | |
| 		
 | |
| 	return props[prop]	
 | |
| 
 | |
| def set_prop(typecode, prop, value):
 | |
| 	state = update_state()
 | |
| 	if state["activeObject"] and idprops_type(state["activeObject"],typecode):
 | |
| 		state["activeObject"].properties['FLT'][prop] = value		
 | |
| 
 | |
| 
 | |
| 
 | |
| def get_lockmask(mask):
 | |
| 	global lodflag
 | |
| 	state = update_state()
 | |
| 	if state["activeObject"]:
 | |
| 		flag = get_prop(73,lodflag)
 | |
| 		if flag & mask:
 | |
| 			return True
 | |
| 	return False	
 | |
| 
 | |
| def set_lockmask(mask):
 | |
| 	state = update_state()
 | |
| 	if state["activeObject"] and idprops_type(state["activeObject"], 73):
 | |
| 		oldvalue = state["activeObject"].properties['FLT'][lodflag]
 | |
| 		oldvalue = struct.unpack('>I', struct.pack('>i', oldvalue))[0]
 | |
| 		oldvalue |= mask
 | |
| 		state["activeObject"].properties['FLT'][lodflag] = struct.unpack('>i', struct.pack(">I", oldvalue))[0]
 | |
| 
 | |
| def clear_lockmask(mask):
 | |
| 	state = update_state()
 | |
| 	if state["activeObject"] and idprops_type(state["activeObject"], 73):
 | |
| 		oldvalue = state["activeObject"].properties['FLT'][lodflag]
 | |
| 		oldvalue = struct.unpack('>I', struct.pack('>i', oldvalue))[0]
 | |
| 		oldvalue &= ~mask
 | |
| 		state["activeObject"].properties['FLT'][lodflag] = struct.unpack('>i',struct.pack('>I',oldvalue))[0]	
 | |
| 
 | |
| def findchildren(object):
 | |
| 	state = update_state()
 | |
| 	children = list()
 | |
| 	for candidate in state["activeScene"].objects:
 | |
| 		if candidate.parent == object:
 | |
| 			children.append(candidate)
 | |
| 	retlist = list(children)
 | |
| 	for child in children:
 | |
| 		retlist = retlist + findchildren(child)
 | |
| 	return retlist
 | |
| 
 | |
| def get_object_center(object):
 | |
| 	bbox = object.getBoundBox(1)
 | |
| 	average = Blender.Mathutils.Vector(0.0, 0.0, 0.0)
 | |
| 	
 | |
| 	for point in bbox:
 | |
| 		average[0] += point[0]
 | |
| 		average[1] += point[1]
 | |
| 		average[2] += point[2]
 | |
| 	
 | |
| 	average[0] = average[0] / 8.0
 | |
| 	average[1] = average[1] / 8.0
 | |
| 	average[2] = average[2] / 8.0
 | |
| 	
 | |
| 	return average
 | |
| 	
 | |
| 
 | |
| def calc_center():
 | |
| 	
 | |
| 	global xco
 | |
| 	global yco
 | |
| 	global zco
 | |
| 	
 | |
| 	state = update_state()
 | |
| 	if state["activeObject"] and idprops_type(state["activeObject"], 73):
 | |
| 		average = Blender.Mathutils.Vector(0.0, 0.0, 0.0)
 | |
| 		children = findchildren(state["activeObject"]) #get children objects	
 | |
| 		if children:
 | |
| 			for child in children:
 | |
| 				center = get_object_center(child)
 | |
| 				average[0] += center[0]
 | |
| 				average[1] += center[1]
 | |
| 				average[2] += center[2]
 | |
| 			
 | |
| 			average[0] = average[0] / len(children)
 | |
| 			average[1] = average[1] / len(children)
 | |
| 			average[2] = average[2] / len(children)
 | |
| 			
 | |
| 		set_prop(73, xco, average[0])
 | |
| 		set_prop(73, yco, average[1])
 | |
| 		set_prop(73, zco, average[2])
 | |
| 		
 | |
| 
 | |
| def grab_center():
 | |
| 	
 | |
| 	global xco
 | |
| 	global yco
 | |
| 	global zco
 | |
| 	
 | |
| 	state = update_state()
 | |
| 	if state["activeObject"] and idprops_type(state["activeObject"], 73):
 | |
| 		center = Blender.Window.GetCursorPos()
 | |
| 		
 | |
| 		set_prop(73, xco, center[0])
 | |
| 		set_prop(73, yco, center[1])
 | |
| 		set_prop(73, zco, center[2])	
 | |
| 
 | |
| 
 | |
| def create_lod():
 | |
| 	state = update_state()
 | |
| 	actobj = state["activeObject"]
 | |
| 	if actobj and not idprops_type(actobj, 73):
 | |
| 		idprops_kill()
 | |
| 		idprops_append(actobj,73, flt_properties.FLTLOD)
 | |
| 		calc_center()
 | |
| 
 | |
| 	
 | |
| 		
 | |
| def event(evt,val):
 | |
| 	if evt == Draw.ESCKEY:
 | |
| 		Draw.Exit()
 | |
| 		
 | |
| def but_event(evt):
 | |
| 
 | |
| 	global LOD_MAKE
 | |
| 	global LOD_DELETE
 | |
| 	global LOD_CALC_CENTER
 | |
| 	global LOD_GRAB_CENTER
 | |
| 	global LOD_FREEZE
 | |
| 	global LOD_PREVIOUS
 | |
| 	global LOD_X
 | |
| 	global LOD_Y
 | |
| 	global LOD_Z
 | |
| 	global LOD_SIG
 | |
| 	global LOD_IN
 | |
| 	global LOD_OUT
 | |
| 	global LOD_TRANS
 | |
| 	
 | |
| 	global switch_in
 | |
| 	global switch_out
 | |
| 	global xco
 | |
| 	global yco
 | |
| 	global zco
 | |
| 	global trans
 | |
| 	global sig_size
 | |
| 	
 | |
| 	global lodflag
 | |
| 	global previous_mask
 | |
| 	global freeze_mask
 | |
| 	
 | |
| 	global evcode
 | |
| 	
 | |
| 	#do "system" events
 | |
| 	if evt == evcode["LOD_MAKE"]:
 | |
| 		create_lod()
 | |
| 
 | |
| 	if evt == evcode["LOD_CALC_CENTER"]:
 | |
| 		calc_center()
 | |
| 	
 | |
| 	if evt == evcode["LOD_DELETE"]:
 | |
| 		idprops_kill()
 | |
| 	
 | |
| 	if evt == evcode["LOD_GRAB_CENTER"]:
 | |
| 		grab_center()
 | |
| 
 | |
| 	#do mask events
 | |
| 	if evt == evcode["LOD_FREEZE"]:
 | |
| 		if LOD_FREEZE.val == True:
 | |
| 			set_lockmask(freeze_mask)
 | |
| 		else:
 | |
| 			clear_lockmask(freeze_mask)
 | |
| 			
 | |
| 	if evt == evcode["LOD_PREVIOUS"]:
 | |
| 		if LOD_PREVIOUS.val == True:
 | |
| 			set_lockmask(previous_mask)
 | |
| 		else:
 | |
| 			clear_lockmask(previous_mask)
 | |
| 			
 | |
| 	#do input events
 | |
| 	if evt == evcode["LOD_X"]:
 | |
| 		set_prop(73, xco, LOD_X.val)
 | |
| 	if evt == evcode["LOD_Y"]:
 | |
| 		set_prop(73, yco, LOD_Y.val)
 | |
| 	if evt == evcode["LOD_Z"]:
 | |
| 		set_prop(73, zco, LOD_Z.val)
 | |
| 	if evt == evcode["LOD_SIG"]:
 | |
| 		set_prop(73, sig_size, LOD_SIG.val)
 | |
| 	if evt == evcode["LOD_IN"]:
 | |
| 		set_prop(73, switch_in, LOD_IN.val)
 | |
| 	if evt == evcode["LOD_OUT"]:
 | |
| 		set_prop(73, switch_out, LOD_OUT.val)
 | |
| 	if evt == evcode["LOD_TRANS"]:
 | |
| 		set_prop(73, trans, LOD_TRANS.val)	
 | |
| 				
 | |
| 
 | |
| 	Draw.Redraw(1)
 | |
| 	Blender.Window.RedrawAll()
 | |
| 
 | |
| def draw_propsheet(x,y):
 | |
| 
 | |
| 	global LOD_MAKE
 | |
| 	global LOD_DELETE
 | |
| 	global LOD_CALC_CENTER
 | |
| 	global LOD_GRAB_CENTER
 | |
| 	global LOD_FREEZE
 | |
| 	global LOD_PREVIOUS
 | |
| 	global LOD_X
 | |
| 	global LOD_Y
 | |
| 	global LOD_Z
 | |
| 	global LOD_SIG
 | |
| 	global LOD_IN
 | |
| 	global LOD_OUT
 | |
| 	global LOD_TRANS
 | |
| 
 | |
| 	#labels
 | |
| 	global LOD_EDITLABEL
 | |
| 	global LOD_SWITCHLABEL
 | |
| 	global LOD_CENTERLABEL
 | |
| 	global LOD_XLABEL
 | |
| 	global LOD_YLABEL
 | |
| 	global LOD_ZLABEL
 | |
| 	global LOD_SIGLABEL
 | |
| 	global LOD_INLABEL
 | |
| 	global LOD_OUTLABEL
 | |
| 	global LOD_TRANSLABEL
 | |
| 	
 | |
| 	
 | |
| 	global switch_in
 | |
| 	global switch_out
 | |
| 	global xco
 | |
| 	global yco
 | |
| 	global zco
 | |
| 	global trans
 | |
| 	global sig_size
 | |
| 	
 | |
| 	global lodflag
 | |
| 	global previous_mask
 | |
| 	global freeze_mask
 | |
| 	
 | |
| 	global evcode
 | |
| 
 | |
| 
 | |
| 	global evcode
 | |
| 	
 | |
| 	state = update_state()
 | |
| 
 | |
| 	label_width = 100	
 | |
| 	row_height = 20
 | |
| 	toggle_width = 50
 | |
| 	input_width = 100
 | |
| 	pad = 10
 | |
| 	origx = x
 | |
| 	origy = (row_height * 16) + (pad * 16)
 | |
| 
 | |
| 
 | |
| 	#editor label
 | |
| 	x = origx
 | |
| 	y = origy
 | |
| 	LOD_EDITLABEL = Blender.Draw.Label("FLT Level of Detail Editor", x, y, 250, row_height)
 | |
| 
 | |
| 
 | |
| 	#Center inputs
 | |
| 	x = origx
 | |
| 	y = y- (row_height + pad)
 | |
| 	LOD_CENTERLABEL = Blender.Draw.Label("LOD center", x, y, label_width, row_height)
 | |
| 	y = y- (row_height + pad)
 | |
| 	LOD_XLABEL = Blender.Draw.Label("X Coordinate", x, y, label_width, row_height)
 | |
| 	x = origx + (label_width + pad)
 | |
| 	LOD_X = Blender.Draw.Number("", evcode["LOD_X"], x, y, input_width, row_height,get_prop(73,xco),  -1000000.0, 1000000.0, "")
 | |
| 	x = origx
 | |
| 	y = y- (row_height + pad)
 | |
| 	LOD_YLABEL = Blender.Draw.Label("Y Coordinate", x, y, label_width, row_height)	
 | |
| 	x = origx + (label_width + pad)
 | |
| 	LOD_Y = Blender.Draw.Number("", evcode["LOD_Y"], x, y, input_width, row_height,get_prop(73,yco), -1000000.0,  1000000.0, "")
 | |
| 	x = origx
 | |
| 	y = y- (row_height + pad)
 | |
| 	LOD_ZLABEL = Blender.Draw.Label("Z Coordinate", x, y, label_width, row_height)
 | |
| 	x = origx + (label_width + pad)		
 | |
| 	LOD_Z = Blender.Draw.Number("", evcode["LOD_Z"], x, y, input_width, row_height,get_prop(73,zco), -1000000.0, 1000000.0, "")
 | |
| 
 | |
| 
 | |
| 	#Switch inputs
 | |
| 	x = origx
 | |
| 	y = y- (row_height + pad)
 | |
| 	LOD_SWITCHLABEL = Blender.Draw.Label("Switch Settings", x, y, input_width, row_height)
 | |
| 	y = y- (row_height + pad)
 | |
| 	LOD_SIGLABEL = Blender.Draw.Label("Significant Size", x, y, label_width, row_height)
 | |
| 	x = origx + (label_width + pad)
 | |
| 	LOD_SIG = Blender.Draw.Number("", evcode["LOD_SIG"], x, y, input_width, row_height, get_prop(73,sig_size),  -1000000.0, 1000000.0, "")
 | |
| 	x = origx
 | |
| 	y = y- (row_height + pad)
 | |
| 	LOD_INLABEL = Blender.Draw.Label("Switch In", x, y, label_width, row_height)
 | |
| 	x = origx + (label_width + pad)
 | |
| 	LOD_IN = Blender.Draw.Number("", evcode["LOD_IN"], x, y, input_width, row_height, get_prop(73,switch_in), -1000000.0, 1000000.0, "")
 | |
| 	x = origx
 | |
| 	y = y- (row_height + pad)
 | |
| 	LOD_OUTLABEL = Blender.Draw.Label("Switch Out", x, y, label_width, row_height)	
 | |
| 	x = origx + (label_width + pad)
 | |
| 	LOD_OUT = Blender.Draw.Number("", evcode["LOD_OUT"], x, y, input_width, row_height, get_prop(73,switch_out), -1000000.0, 1000000.0, "")
 | |
| 	x = origx
 | |
| 	y = y- (row_height + pad)
 | |
| 	LOD_TRANSLABEL = Blender.Draw.Label("Transition", x, y, label_width, row_height)		
 | |
| 	x = origx + (label_width + pad)
 | |
| 	LOD_TRANS = Blender.Draw.Number("", evcode["LOD_TRANS"], x, y, input_width, row_height, get_prop(73,trans), -1000000.0, 1000000.0, "")	
 | |
| 
 | |
| 
 | |
| 	x = origx
 | |
| 	y = y - (row_height + pad)	
 | |
|  	LOD_MAKE = Blender.Draw.PushButton("Make LOD", evcode["LOD_MAKE"], x, y, input_width + label_width + pad, row_height, "Make a LOD Node out of Active Object")
 | |
| 	y = y - (row_height + pad)	
 | |
| 	LOD_DELETE = Blender.Draw.PushButton("Delete LOD", evcode["LOD_DELETE"], x, y, input_width + label_width + pad, row_height, "Delete the LOD Node properties")
 | |
| 	y = y - (row_height + pad)
 | |
| 	LOD_CALC_CENTER = Blender.Draw.PushButton("Calculate Center", evcode["LOD_CALC_CENTER"], x, y, input_width + label_width + pad, row_height, "Calculate the center of this LOD")
 | |
| 	y = y - (row_height + pad)
 | |
| 	LOD_GRAB_CENTER = Blender.Draw.PushButton("Grab Center", evcode["LOD_GRAB_CENTER"], x, y, input_width + label_width + pad, row_height, "Grab center from 3d cursor")
 | |
| 	y = y - (row_height + pad)
 | |
| 	LOD_FREEZE = Blender.Draw.Toggle("Freeze Center", evcode["LOD_FREEZE"], x, y, input_width + label_width + pad, row_height, get_lockmask(freeze_mask), "")
 | |
| 	y = y - (row_height + pad)
 | |
| 	LOD_PREVIOUS = Blender.Draw.Toggle("Previous Range", evcode["LOD_PREVIOUS"], x, y, input_width + label_width + pad, row_height, get_lockmask(previous_mask), "")
 | |
| 
 | |
| def gui():
 | |
| 	#draw the propsheet/toolbox.
 | |
| 	psheety = 800
 | |
| 	#psheetx = psheety + 10
 | |
| 	draw_propsheet(20,psheety)
 | |
| 
 | |
| Draw.Register(gui,event,but_event)
 | |
| 	 |