|
|
@@ -1,1567 +0,0 @@
|
|
|
-import sys, string, math, types
|
|
|
-from pandac.PandaModules import *
|
|
|
-import direct.gui.DirectGuiGlobals as DGG
|
|
|
-from direct.gui.DirectGui import *
|
|
|
-
|
|
|
-from PieMenu import *
|
|
|
-from ScrollMenu import *
|
|
|
-
|
|
|
-dnaDirectory = Filename.expandFrom(base.config.GetString("dna-directory", "$TTMODELS/src/dna"))
|
|
|
-
|
|
|
-
|
|
|
-# Colors used by all color menus
|
|
|
-DEFAULT_COLORS = [
|
|
|
- Vec4(1, 1, 1, 1),
|
|
|
- Vec4(0.75, 0.75, 0.75, 1.0),
|
|
|
- Vec4(0.5, 0.5, 0.5, 1.0),
|
|
|
- Vec4(0.25, 0.25, 0.25, 1.0)
|
|
|
- ]
|
|
|
-# The list of items with color attributes
|
|
|
-COLOR_TYPES = ['wall_color', 'window_color',
|
|
|
- 'window_awning_color', 'sign_color', 'door_color',
|
|
|
- 'door_awning_color', 'cornice_color',
|
|
|
- 'prop_color']
|
|
|
-# The list of dna components maintained in the style attribute dictionary
|
|
|
-DNA_TYPES = ['wall', 'window', 'sign', 'door_double', 'door_single', 'cornice', 'toon_landmark',
|
|
|
- 'prop', 'street']
|
|
|
-BUILDING_TYPES = ['10_10', '20', '10_20', '20_10', '10_10_10',
|
|
|
- '4_21', '3_22', '4_13_8', '3_13_9', '10',
|
|
|
- '12_8', '13_9_8', '4_10_10', '4_10', '4_20',
|
|
|
- ]
|
|
|
-BUILDING_HEIGHTS = [10, 14, 20, 24, 25, 30]
|
|
|
-NUM_WALLS = [1, 2, 3]
|
|
|
-LANDMARK_SPECIAL_TYPES = ['', 'hq', 'gagshop', 'clotheshop', 'petshop', 'kartshop']
|
|
|
-
|
|
|
-OBJECT_SNAP_POINTS = {
|
|
|
- 'street_5x20': [(Vec3(5.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_10x20': [(Vec3(10.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_20x20': [(Vec3(20.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_30x20': [(Vec3(30.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_40x20': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_80x20': [(Vec3(80.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_5x40': [(Vec3(5.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_10x40': [(Vec3(10.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_20x40': [(Vec3(20.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_20x40_15': [(Vec3(20.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_30x40': [(Vec3(30.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_40x40': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_20x60': [(Vec3(20.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_40x60': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_40x40_15': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_80x40': [(Vec3(80.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_angle_30': [(Vec3(0), Vec3(-30, 0, 0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_angle_45': [(Vec3(0), Vec3(-45, 0, 0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_angle_60': [(Vec3(0), Vec3(-60, 0, 0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_inner_corner': [(Vec3(20.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_outer_corner': [(Vec3(20.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_full_corner': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_tight_corner': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_tight_corner_mirror': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_double_corner': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_curved_corner': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_curved_corner_15': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_t_intersection': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_y_intersection': [(Vec3(30.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_street_20x20': [(Vec3(20.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_street_40x40': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_sidewalk_20x20': [(Vec3(20.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_sidewalk_40x40': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_divided_transition': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_divided_40x70': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_divided_transition_15': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_divided_40x70_15': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_stairs_40x10x5': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_4way_intersection': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_incline_40x40x5': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_square_courtyard': [(Vec3(0.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_courtyard_70': [(Vec3(0.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_courtyard_70_exit': [(Vec3(0.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_courtyard_90': [(Vec3(0.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_courtyard_90_exit': [(Vec3(0.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_courtyard_70_15': [(Vec3(0.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_courtyard_70_15_exit': [(Vec3(0.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_courtyard_90_15': [(Vec3(0.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_courtyard_90_15_exit': [(Vec3(0.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_50_transition': [(Vec3(10.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_20x50': [(Vec3(20.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_40x50': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_keyboard_10x40': [(Vec3(10.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_keyboard_20x40': [(Vec3(20.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_keyboard_40x40': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- 'street_sunken_40x40': [(Vec3(40.0, 0, 0), Vec3(0)),
|
|
|
- (Vec3(0), Vec3(0))],
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-# Precompute class types for type comparisons
|
|
|
-DNA_CORNICE = DNACornice.getClassType()
|
|
|
-DNA_DOOR = DNADoor.getClassType()
|
|
|
-DNA_FLAT_DOOR = DNAFlatDoor.getClassType()
|
|
|
-DNA_FLAT_BUILDING = DNAFlatBuilding.getClassType()
|
|
|
-DNA_NODE = DNANode.getClassType()
|
|
|
-DNA_GROUP = DNAGroup.getClassType()
|
|
|
-DNA_VIS_GROUP = DNAVisGroup.getClassType()
|
|
|
-DNA_LANDMARK_BUILDING = DNALandmarkBuilding.getClassType()
|
|
|
-DNA_NODE = DNANode.getClassType()
|
|
|
-DNA_PROP = DNAProp.getClassType()
|
|
|
-DNA_SIGN = DNASign.getClassType()
|
|
|
-DNA_SIGN_BASELINE = DNASignBaseline.getClassType()
|
|
|
-DNA_SIGN_TEXT = DNASignText.getClassType()
|
|
|
-DNA_SIGN_GRAPHIC = DNASignGraphic.getClassType()
|
|
|
-DNA_STREET = DNAStreet.getClassType()
|
|
|
-DNA_WALL = DNAWall.getClassType()
|
|
|
-DNA_WINDOWS = DNAWindows.getClassType()
|
|
|
-
|
|
|
-# DNA Utility functions (possible class extensions?)
|
|
|
-def DNARemoveChildren(dnaObject):
|
|
|
- """ Utility function to delete all the children of a DNANode """
|
|
|
- children = []
|
|
|
- for i in range(dnaObject.getNumChildren()):
|
|
|
- children.append(dnaObject.at(i))
|
|
|
- for child in children:
|
|
|
- dnaObject.remove(child)
|
|
|
- DNASTORE.removeDNAGroup(child)
|
|
|
-
|
|
|
-def DNARemoveChildOfClass(dnaNode, classType, childNum = 0):
|
|
|
- """ Remove the nth object of that type you come across """
|
|
|
- childCount = 0
|
|
|
- for i in range(dnaNode.getNumChildren()):
|
|
|
- child = dnaNode.at(i)
|
|
|
- if DNAClassEqual(child, classType):
|
|
|
- if childCount == childNum:
|
|
|
- dnaNode.remove(child)
|
|
|
- DNASTORE.removeDNAGroup(child)
|
|
|
- return 1
|
|
|
- childCount = childCount + 1
|
|
|
- # None found
|
|
|
- return 0
|
|
|
-
|
|
|
-def DNARemoveAllChildrenOfClass(dnaNode, classType):
|
|
|
- """ Remove the objects of that type """
|
|
|
- children = []
|
|
|
- for i in range(dnaNode.getNumChildren()):
|
|
|
- child=dnaNode.at(i)
|
|
|
- if DNAClassEqual(child, classType):
|
|
|
- children.append(child)
|
|
|
- for child in children:
|
|
|
- dnaNode.remove(child)
|
|
|
- DNASTORE.removeDNAGroup(child)
|
|
|
-
|
|
|
-def DNAGetChildren(dnaNode, classType=None):
|
|
|
- """ Return the objects of that type """
|
|
|
- children = []
|
|
|
- for i in range(dnaNode.getNumChildren()):
|
|
|
- child=dnaNode.at(i)
|
|
|
- if ((not classType)
|
|
|
- or DNAClassEqual(child, classType)):
|
|
|
- children.append(child)
|
|
|
- return children
|
|
|
-
|
|
|
-def DNAGetChild(dnaObject, type = DNA_NODE, childNum = 0):
|
|
|
- childCount = 0
|
|
|
- for i in range(dnaObject.getNumChildren()):
|
|
|
- child = dnaObject.at(i)
|
|
|
- if DNAClassEqual(child, type):
|
|
|
- if childCount == childNum:
|
|
|
- return child
|
|
|
- childCount = childCount + 1
|
|
|
- # Not found
|
|
|
- return None
|
|
|
-
|
|
|
-def DNAGetChildRecursive(dnaObject, type = DNA_NODE, childNum = 0):
|
|
|
- childCount = 0
|
|
|
- for i in range(dnaObject.getNumChildren()):
|
|
|
- child = dnaObject.at(i)
|
|
|
- if DNAClassEqual(child, type):
|
|
|
- if childCount == childNum:
|
|
|
- return child
|
|
|
- childCount = childCount + 1
|
|
|
- else:
|
|
|
- child = DNAGetChildRecursive(child, type, childNum-childCount)
|
|
|
- if child:
|
|
|
- return child
|
|
|
-
|
|
|
- # Not found
|
|
|
- return None
|
|
|
-
|
|
|
-def DNAGetChildOfClass(dnaNode, classType):
|
|
|
- for i in range(dnaNode.getNumChildren()):
|
|
|
- child = dnaNode.at(i)
|
|
|
- if DNAClassEqual(child, classType):
|
|
|
- return child
|
|
|
- # Not found
|
|
|
- return None
|
|
|
-
|
|
|
-def DNAGetClassType(dnaObject):
|
|
|
- return dnaObject.__class__.getClassType()
|
|
|
-
|
|
|
-def DNAClassEqual(dnaObject, classType):
|
|
|
- return DNAGetClassType(dnaObject).eq(classType)
|
|
|
-
|
|
|
-def DNAIsDerivedFrom(dnaObject, classType):
|
|
|
- return DNAGetClassType(dnaObject).isDerivedFrom(classType)
|
|
|
-
|
|
|
-def DNAGetWallHeights(aDNAFlatBuilding):
|
|
|
- """ Get a list of wall heights for a given flat building """
|
|
|
- # Init variables
|
|
|
- heightList = []
|
|
|
- offsetList = []
|
|
|
- offset = 0.0
|
|
|
- # Compute wall heights
|
|
|
- for i in range(aDNAFlatBuilding.getNumChildren()):
|
|
|
- child = aDNAFlatBuilding.at(i)
|
|
|
- if DNAClassEqual(child, DNA_WALL):
|
|
|
- height = child.getHeight()
|
|
|
- heightList.append(height)
|
|
|
- offsetList.append(offset)
|
|
|
- offset = offset + height
|
|
|
- return heightList, offsetList
|
|
|
-
|
|
|
-def DNAGetBaselineString(baseline):
|
|
|
- s=""
|
|
|
- for i in range(baseline.getNumChildren()):
|
|
|
- child = baseline.at(i)
|
|
|
- if DNAClassEqual(child, DNA_SIGN_TEXT):
|
|
|
- s=s+child.getLetters()
|
|
|
- elif DNAClassEqual(child, DNA_SIGN_GRAPHIC):
|
|
|
- s=s+'['+child.getCode()+']'
|
|
|
- return s
|
|
|
-
|
|
|
-def DNASetBaselineString(baseline, text):
|
|
|
- # TODO: Instead of removing all the text and replacing it,
|
|
|
- # replace each text item and then add or remove at the end.
|
|
|
- # This should allow inlined graphics to stay in place.
|
|
|
- # end of todo.
|
|
|
- DNARemoveAllChildrenOfClass(baseline, DNA_SIGN_TEXT)
|
|
|
-
|
|
|
- # We can't just blindly iterate through the text, because it might
|
|
|
- # be utf-8 encoded, meaning some characters are represented using
|
|
|
- # multi-byte sequences. Instead, create a TextNode and use it to
|
|
|
- # iterate through the characters of the text.
|
|
|
- t = TextNode('')
|
|
|
- t.setText(text)
|
|
|
- for i in range(t.getNumChars()):
|
|
|
- ch = t.getEncodedChar(i)
|
|
|
- text=DNASignText("text")
|
|
|
- text.setLetters(ch)
|
|
|
- baseline.add(text)
|
|
|
-
|
|
|
-class LevelStyleManager:
|
|
|
- """Class which reads in style files and manages class variables"""
|
|
|
- def __init__(self, NEIGHBORHOODS = [], NEIGHBORHOOD_CODES = {} ):
|
|
|
- self.NEIGHBORHOODS = NEIGHBORHOODS
|
|
|
- self.NEIGHBORHOOD_CODES = NEIGHBORHOOD_CODES
|
|
|
- # The main dictionary holding all attribute objects
|
|
|
- self.attributeDictionary = {}
|
|
|
- # Create the style samples
|
|
|
- self.createBaselineStyleAttributes()
|
|
|
- self.createWallStyleAttributes()
|
|
|
- self.createBuildingStyleAttributes()
|
|
|
- self.createColorAttributes()
|
|
|
- self.createDNAAttributes()
|
|
|
- self.createMiscAttributes()
|
|
|
-
|
|
|
- # BASELINE STYLE FUNCTIONS
|
|
|
- def createBaselineStyleAttributes(self):
|
|
|
- """
|
|
|
- Create a baselineStyle entry in the attribute dictionary
|
|
|
- This will be a dictionary of style attributes, one per neighborhood
|
|
|
- """
|
|
|
- # First create an empty dictionary
|
|
|
- dict = self.attributeDictionary['baseline_style'] = {}
|
|
|
- # Create a attribute object for each neighborhood
|
|
|
- for neighborhood in self.NEIGHBORHOODS:
|
|
|
- attribute = LevelAttribute('baseline_style')
|
|
|
- attribute.setDict(
|
|
|
- # Create a baseline style dictionary for each neighborhood
|
|
|
- self.createBaselineStyleDictionary(neighborhood))
|
|
|
- # Using this dictionary, create style pie menus
|
|
|
- attribute.setMenu(
|
|
|
- self.createBaselineStyleMenu(neighborhood, attribute.getDict()))
|
|
|
- dict[neighborhood] = attribute
|
|
|
-
|
|
|
- def createBaselineStyleDictionary(self, neighborhood):
|
|
|
- """
|
|
|
- Create a dictionary of baseline styles for a neighborhood
|
|
|
- """
|
|
|
- filename = neighborhood + '_baseline_styles.txt'
|
|
|
- print 'Loading baseline styles from: ' + filename
|
|
|
- styleData = self.getStyleFileData(filename)
|
|
|
- return self.initializeBaselineStyleDictionary(styleData, neighborhood)
|
|
|
-
|
|
|
- def initializeBaselineStyleDictionary(self, styleData, neighborhood):
|
|
|
- """
|
|
|
- Fill in the baseline style dictionary with data from the style file
|
|
|
- """
|
|
|
- styleDictionary = {}
|
|
|
- styleCount = 0
|
|
|
- code = self.NEIGHBORHOOD_CODES[neighborhood]
|
|
|
- while styleData:
|
|
|
- l = styleData[0]
|
|
|
- if l == 'baselineStyle':
|
|
|
- # Start of new style, strip off first line then extract style
|
|
|
- style, styleData = self.extractBaselineStyle(styleData)
|
|
|
- style.name = code + '_baseline_style_' + `styleCount`
|
|
|
- # Store style in dictionary
|
|
|
- styleDictionary[style.name] = style
|
|
|
- styleCount = styleCount + 1
|
|
|
- # Move to next line
|
|
|
- styleData = styleData[1:]
|
|
|
- return styleDictionary
|
|
|
-
|
|
|
- def extractBaselineStyle(self, styleData):
|
|
|
- """
|
|
|
- Pull out one style from a list of style data. Will keep
|
|
|
- processing data until endBaselineStyle of end of data is reached.
|
|
|
- Returns a baseline style and remaining styleData.
|
|
|
- """
|
|
|
- # Create default style
|
|
|
- style = DNABaselineStyle()
|
|
|
- # Strip off first line
|
|
|
- styleData = styleData[1:]
|
|
|
- while styleData:
|
|
|
- l = styleData[0]
|
|
|
- if l == 'endBaselineStyle':
|
|
|
- # End of style found, break out of while loop
|
|
|
- # Note, endBaselineStyle line is *not* stripped off
|
|
|
- return style, styleData
|
|
|
- else:
|
|
|
- pair = map(string.strip, l.split(':'))
|
|
|
- if style.__dict__.has_key(pair[0]):
|
|
|
- pair_0 = pair[0]
|
|
|
- # Convert some numerical values
|
|
|
- if (pair_0 == 'color'
|
|
|
- or pair_0 == 'kern'
|
|
|
- or pair_0 == 'wiggle'
|
|
|
- or pair_0 == 'stumble'
|
|
|
- or pair_0 == 'stomp'
|
|
|
- or pair_0 == 'curve'
|
|
|
- or pair_0 == 'x'
|
|
|
- or pair_0 == 'z'
|
|
|
- or pair_0 == 'scaleX'
|
|
|
- or pair_0 == 'scaleZ'
|
|
|
- or pair_0 == 'roll'):
|
|
|
- style[pair_0] = eval(pair[1])
|
|
|
- else:
|
|
|
- style[pair_0] = pair[1]
|
|
|
- else:
|
|
|
- print 'extractBaselineStyle: Invalid Key'
|
|
|
- print pair[0]
|
|
|
- styleData = styleData[1:]
|
|
|
- # No end of style found, return style data as is
|
|
|
- return style, None
|
|
|
-
|
|
|
- def createBaselineStyleMenu(self, neighborhood, dictionary):
|
|
|
- """
|
|
|
- Create a baseline style pie menu
|
|
|
- """
|
|
|
- numItems = len(dictionary)
|
|
|
- newStyleMenu = hidden.attachNewNode(neighborhood + '_style_menu')
|
|
|
- radius = 0.7
|
|
|
- angle = deg2Rad(360.0/numItems)
|
|
|
- keys = dictionary.keys()
|
|
|
- keys.sort()
|
|
|
- styles = map(lambda x, d = dictionary: d[x], keys)
|
|
|
- sf = 0.1
|
|
|
- aspectRatio = (base.direct.dr.getWidth()/float(base.direct.dr.getHeight()))
|
|
|
- for i in range(numItems):
|
|
|
- # Get the node
|
|
|
- node = self.createBaselineStyleSample(styles[i])
|
|
|
- bounds = node.getBounds()
|
|
|
- center = bounds.getCenter()
|
|
|
- center = center * sf
|
|
|
- # Reposition it
|
|
|
- node.setPos((radius * math.cos(i * angle)) - center[0],
|
|
|
- 0.0,
|
|
|
- ((radius * aspectRatio * math.sin(i * angle)) -
|
|
|
- center[2]))
|
|
|
- # Scale it
|
|
|
- node.setScale(sf)
|
|
|
- # Add it to the styleMenu
|
|
|
- node.reparentTo(newStyleMenu)
|
|
|
- # Scale the whole shebang down by 0.5
|
|
|
- newStyleMenu.setScale(0.5)
|
|
|
- # Create and return a pie menu
|
|
|
- return PieMenu(newStyleMenu, styles)
|
|
|
-
|
|
|
- def createBaselineStyleSample(self, baselineStyle):
|
|
|
- """
|
|
|
- Create a style sample using the DNA info in the style
|
|
|
- """
|
|
|
- baseline = DNASignBaseline()
|
|
|
- # Set some example text:
|
|
|
- DNASetBaselineString(baseline, "Example Text")
|
|
|
- baselineStyle.copyTo(baseline)
|
|
|
- return baseline.traverse(hidden, DNASTORE, 1)
|
|
|
-
|
|
|
- # WALL STYLE FUNCTIONS
|
|
|
- def createWallStyleAttributes(self):
|
|
|
- """
|
|
|
- Create a wallStyle entry in the attribute dictionary
|
|
|
- This will be a dictionary of style attributes, one per neighborhood
|
|
|
- """
|
|
|
- # First create an empty dictionary
|
|
|
- dict = self.attributeDictionary['wall_style'] = {}
|
|
|
- # Create a attribute object for each neighborhood
|
|
|
- for neighborhood in self.NEIGHBORHOODS:
|
|
|
- attribute = LevelAttribute('wall_style')
|
|
|
- attribute.setDict(
|
|
|
- # Create a wall style dictionary for each neighborhood
|
|
|
- self.createWallStyleDictionary(neighborhood))
|
|
|
- # Using this dictionary, create color pie menus
|
|
|
- attribute.setMenu(
|
|
|
- self.createWallStyleMenu(neighborhood, attribute.getDict()))
|
|
|
- dict[neighborhood] = attribute
|
|
|
-
|
|
|
- def createWallStyleDictionary(self, neighborhood):
|
|
|
- """
|
|
|
- Create a dictionary of wall styles for a neighborhood
|
|
|
- """
|
|
|
- filename = neighborhood + '_wall_styles.txt'
|
|
|
- print 'Loading wall styles from: ' + filename
|
|
|
- styleData = self.getStyleFileData(filename)
|
|
|
- return self.initializeWallStyleDictionary(styleData, neighborhood)
|
|
|
-
|
|
|
- def initializeWallStyleDictionary(self, styleData, neighborhood):
|
|
|
- """
|
|
|
- Fill in the wall style dictionary with data from the style file
|
|
|
- """
|
|
|
- styleDictionary = {}
|
|
|
- styleCount = 0
|
|
|
- code = self.NEIGHBORHOOD_CODES[neighborhood]
|
|
|
- while styleData:
|
|
|
- l = styleData[0]
|
|
|
- if l == 'wallStyle':
|
|
|
- # Start of new style, strip off first line then extract style
|
|
|
- style, styleData = self.extractWallStyle(styleData)
|
|
|
- style.name = code + '_wall_style_' + `styleCount`
|
|
|
- # Store style in dictionary
|
|
|
- styleDictionary[style.name] = style
|
|
|
- styleCount = styleCount + 1
|
|
|
- # Move to next line
|
|
|
- styleData = styleData[1:]
|
|
|
- return styleDictionary
|
|
|
-
|
|
|
- def extractWallStyle(self, styleData):
|
|
|
- """
|
|
|
- Pull out one style from a list of style data. Will keep
|
|
|
- processing data until endWallStyle of end of data is reached.
|
|
|
- Returns a wall style and remaining styleData.
|
|
|
- """
|
|
|
- # Create default style
|
|
|
- style = DNAWallStyle()
|
|
|
- # Strip off first line
|
|
|
- styleData = styleData[1:]
|
|
|
- while styleData:
|
|
|
- l = styleData[0]
|
|
|
- if l == 'endWallStyle':
|
|
|
- # End of style found, break out of while loop
|
|
|
- # Note, endWallStyle line is *not* stripped off
|
|
|
- return style, styleData
|
|
|
- else:
|
|
|
- pair = map(string.strip, l.split(':'))
|
|
|
- if style.__dict__.has_key(pair[0]):
|
|
|
- # Convert colors and count strings to numerical values
|
|
|
- if ((string.find(pair[0],'_color') >= 0) or
|
|
|
- (string.find(pair[0],'_count') >= 0)):
|
|
|
- style[pair[0]] = eval(pair[1])
|
|
|
- else:
|
|
|
- style[pair[0]] = pair[1]
|
|
|
- else:
|
|
|
- print 'getStyleDictionaryFromStyleData: Invalid Key'
|
|
|
- print pair[0]
|
|
|
- styleData = styleData[1:]
|
|
|
- # No end of style found, return style data as is
|
|
|
- return style, None
|
|
|
-
|
|
|
- def createWallStyleMenu(self, neighborhood, dictionary):
|
|
|
- """
|
|
|
- Create a wall style pie menu
|
|
|
- """
|
|
|
- numItems = len(dictionary)
|
|
|
- newStyleMenu = hidden.attachNewNode(neighborhood + '_style_menu')
|
|
|
- radius = 0.7
|
|
|
- angle = deg2Rad(360.0/numItems)
|
|
|
- keys = dictionary.keys()
|
|
|
- keys.sort()
|
|
|
- styles = map(lambda x, d = dictionary: d[x], keys)
|
|
|
- sf = 0.03
|
|
|
- aspectRatio = (base.direct.dr.getWidth()/float(base.direct.dr.getHeight()))
|
|
|
- for i in range(numItems):
|
|
|
- # Get the node
|
|
|
- node = self.createWallStyleSample(styles[i])
|
|
|
- bounds = node.getBounds()
|
|
|
- center = bounds.getCenter()
|
|
|
- center = center * sf
|
|
|
- # Reposition it
|
|
|
- node.setPos((radius * math.cos(i * angle)) - center[0],
|
|
|
- 0.0,
|
|
|
- ((radius * aspectRatio * math.sin(i * angle)) -
|
|
|
- center[2]))
|
|
|
- # Scale it
|
|
|
- node.setScale(sf)
|
|
|
- # Add it to the styleMenu
|
|
|
- node.reparentTo(newStyleMenu)
|
|
|
- # Scale the whole shebang down by 0.5
|
|
|
- newStyleMenu.setScale(0.5)
|
|
|
- # Create and return a pie menu
|
|
|
- return PieMenu(newStyleMenu, styles)
|
|
|
-
|
|
|
- def createWallStyleSample(self, wallStyle):
|
|
|
- """
|
|
|
- Create a style sample using the DNA info in the style
|
|
|
- """
|
|
|
- bldg = DNAFlatBuilding()
|
|
|
- bldgStyle = DNAFlatBuildingStyle(styleList = [(wallStyle, 10.0)])
|
|
|
- self.setDNAFlatBuildingStyle(bldg, bldgStyle, width = 12.0,
|
|
|
- name = 'wall_style_sample')
|
|
|
- return bldg.traverse(hidden, DNASTORE, 1)
|
|
|
-
|
|
|
- # BUILDING STYLE FUNCTIONS
|
|
|
- def createBuildingStyleAttributes(self):
|
|
|
- """
|
|
|
- Create a buildingStyle entry in the attribute dictionary
|
|
|
- This will be a dictionary of style attributes, one per neighborhood
|
|
|
- This information is sorted and stored by num walls, building height,
|
|
|
- and building type (e.g. 10_20, or 10_10_10).
|
|
|
- """
|
|
|
- # First create an attribute which holds one dictionary per
|
|
|
- # neighborhood which stores all of the styles for each neighborhood.
|
|
|
- styleDict = self.attributeDictionary['building_style_all'] = {}
|
|
|
- # Keep track of all building types
|
|
|
- typeDict = {}
|
|
|
- masterTypeList = []
|
|
|
- for neighborhood in self.NEIGHBORHOODS:
|
|
|
- attribute = LevelAttribute('building_style_all')
|
|
|
- # Create a building style dictionary for each neighborhood
|
|
|
- attribute.setDict(
|
|
|
- self.createBuildingStyleDictionary(neighborhood))
|
|
|
- # Using this dictionary, create building style pie menus
|
|
|
- attribute.setMenu(
|
|
|
- self.createBuildingStyleMenu(neighborhood,
|
|
|
- attribute.getDict()))
|
|
|
- # Store attribute in dictionary keyed by neighborhood
|
|
|
- styleDict[neighborhood] = attribute
|
|
|
- # Generate a list of building types for this neighborhood
|
|
|
- # and a list of building types for all neighborhoods,
|
|
|
- # to be used in creating attribute dicts below
|
|
|
- typeList = typeDict[neighborhood] = []
|
|
|
- for style in attribute.getList():
|
|
|
- heightType = string.strip(string.split(style.name, ':')[1])
|
|
|
- if heightType not in typeList:
|
|
|
- typeList.append(heightType)
|
|
|
- if heightType not in masterTypeList:
|
|
|
- masterTypeList.append(heightType)
|
|
|
-
|
|
|
- # Now sort styles according to the building type and number of walls
|
|
|
- # in the building style. Each of these attributes is also sorted by
|
|
|
- # neighborhood
|
|
|
- for i in masterTypeList:
|
|
|
- typeKey = i + '_styles'
|
|
|
- self.attributeDictionary[typeKey] = {}
|
|
|
- for i in NUM_WALLS:
|
|
|
- numWallKey = `i` + '_wall_styles'
|
|
|
- self.attributeDictionary[numWallKey] = {}
|
|
|
- # Also sort height lists according to total height of the building
|
|
|
- for i in BUILDING_HEIGHTS:
|
|
|
- heightKey = `i` + '_ft_wall_heights'
|
|
|
- self.attributeDictionary[heightKey] = {}
|
|
|
- # Now distribute data for each neighborhood
|
|
|
- for neighborhood in self.NEIGHBORHOODS:
|
|
|
- # Create temp dicts to accumulate styles and heights for that
|
|
|
- # neighborhood
|
|
|
- typeAttributes = {}
|
|
|
- numWallsAttributes = {}
|
|
|
- heightAttributes = {}
|
|
|
- # Store atributes for the different categories
|
|
|
- # Building type
|
|
|
- for i in typeDict[neighborhood]:
|
|
|
- typeAttrName = neighborhood + '_' + i + '_styles'
|
|
|
- typeAttributes[i] = LevelAttribute(typeAttrName)
|
|
|
- # Number of walls
|
|
|
- for i in NUM_WALLS:
|
|
|
- styleAttrName = neighborhood + '_' + `i` + '_wall_styles'
|
|
|
- numWallsAttributes[i] = LevelAttribute(styleAttrName)
|
|
|
- # Building height
|
|
|
- for i in BUILDING_HEIGHTS:
|
|
|
- heightAttrName = neighborhood + '_' + `i` + '_ft_wall_heights'
|
|
|
- heightAttributes[i] = LevelAttribute(heightAttrName)
|
|
|
- # Sort through the styles and store in separate lists
|
|
|
- for style in styleDict[neighborhood].getList():
|
|
|
- # Put in code for number of walls into building styles
|
|
|
- heightType = string.strip(string.split(style.name, ':')[1])
|
|
|
- heightList = map(string.atof, string.split(heightType, '_'))
|
|
|
- numWalls = len(heightList)
|
|
|
- # This one stores styles sorted by type
|
|
|
- typeAttributes[heightType].add(style)
|
|
|
- # This one stores styles sorted by number of walls
|
|
|
- numWallsAttributes[numWalls].add(style)
|
|
|
- # A record of all the unique height lists
|
|
|
- height = calcHeight(heightList)
|
|
|
- if heightList not in heightAttributes[height].getList():
|
|
|
- heightAttributes[height].add(heightList)
|
|
|
- # Now store these sorted style and height attributes
|
|
|
- # in the appropriate top-level attribute dictionary
|
|
|
- for i in typeDict[neighborhood]:
|
|
|
- # Styles
|
|
|
- typeKey = i + '_styles'
|
|
|
- self.attributeDictionary[typeKey][neighborhood] = (
|
|
|
- typeAttributes[i])
|
|
|
- for i in NUM_WALLS:
|
|
|
- # Styles
|
|
|
- numWallKey = `i` + '_wall_styles'
|
|
|
- self.attributeDictionary[numWallKey][neighborhood] = (
|
|
|
- numWallsAttributes[i])
|
|
|
- for i in BUILDING_HEIGHTS:
|
|
|
- # Heights
|
|
|
- heightKey = `i` + '_ft_wall_heights'
|
|
|
- self.attributeDictionary[heightKey][neighborhood] = (
|
|
|
- heightAttributes[i])
|
|
|
-
|
|
|
- def createBuildingStyleDictionary(self, neighborhood):
|
|
|
- """
|
|
|
- Create a dictionary of wall styles for a neighborhood
|
|
|
- """
|
|
|
- filename = neighborhood + '_building_styles.txt'
|
|
|
- print 'Loading building styles from: ' + filename
|
|
|
- styleData = self.getStyleFileData(filename)
|
|
|
- return self.initializeBuildingStyleDictionary(styleData, neighborhood)
|
|
|
-
|
|
|
- def initializeBuildingStyleDictionary(self, styleData, neighborhood):
|
|
|
- """
|
|
|
- Fill in the building style dictionary with data from the style file
|
|
|
- """
|
|
|
- # Create a dictionary of all building styles, this will later be
|
|
|
- # split out into a separate dictionary for each building type
|
|
|
- # e.g. 20, 10-10, 10-20....
|
|
|
- bldgStyleDictionary = {}
|
|
|
- styleCount = 0
|
|
|
- code = self.NEIGHBORHOOD_CODES[neighborhood]
|
|
|
- while styleData:
|
|
|
- # Pull out first line
|
|
|
- l = styleData[0]
|
|
|
- if l[:13] == 'buildingStyle':
|
|
|
- # Start with empty style list
|
|
|
- bldgStyle = DNAFlatBuildingStyle(styleList = [])
|
|
|
- # Extract height information found at end of line
|
|
|
- heightCode = string.strip(string.split(l, ':')[1])
|
|
|
- heightList = map(string.atof, string.split(heightCode, '_'))
|
|
|
- # Construct name for building style. Tack on height code
|
|
|
- # to be used later to split styles by heightCode
|
|
|
- bldgStyle.name = (
|
|
|
- code + '_building_style_' + `styleCount` +
|
|
|
- ':' + heightCode)
|
|
|
- # Increment counter
|
|
|
- styleCount = styleCount + 1
|
|
|
- # Reset wall counter to zero
|
|
|
- wallCount = 0
|
|
|
-
|
|
|
- elif l == 'endBuildingStyle':
|
|
|
- # Done, add new style to dictionary
|
|
|
- bldgStyleDictionary[bldgStyle.name] = bldgStyle
|
|
|
-
|
|
|
- elif l[:9] == 'wallStyle':
|
|
|
- # Beginning of next wall style
|
|
|
- wallStyle, styleData = self.extractWallStyle(styleData)
|
|
|
- wallStyle.name = bldgStyle.name + '_wall_' + `wallCount`
|
|
|
- try:
|
|
|
- height = heightList[wallCount]
|
|
|
- except IndexError:
|
|
|
- height = 10.0
|
|
|
- # Add wall style to building style
|
|
|
- bldgStyle.add(wallStyle, height)
|
|
|
- # Increment wall counter
|
|
|
- wallCount = wallCount + 1
|
|
|
- # Move to next line
|
|
|
- styleData = styleData[1:]
|
|
|
- return bldgStyleDictionary
|
|
|
-
|
|
|
- def createBuildingStyleMenu(self, neighborhood, dictionary):
|
|
|
- """
|
|
|
- Create a wall style pie menu
|
|
|
- """
|
|
|
- numItems = len(dictionary)
|
|
|
- newStyleMenu = hidden.attachNewNode(neighborhood + '_style_menu')
|
|
|
- radius = 0.7
|
|
|
- angle = deg2Rad(360.0/numItems)
|
|
|
- keys = dictionary.keys()
|
|
|
- keys.sort()
|
|
|
- styles = map(lambda x, d = dictionary: d[x], keys)
|
|
|
- sf = 0.02
|
|
|
- aspectRatio = (base.direct.dr.getWidth()/float(base.direct.dr.getHeight()))
|
|
|
- for i in range(numItems):
|
|
|
- # Get the node
|
|
|
- node = self.createBuildingStyleSample(styles[i])
|
|
|
- bounds = node.getBounds()
|
|
|
- center = bounds.getCenter()
|
|
|
- center = center * sf
|
|
|
- # Reposition it
|
|
|
- node.setPos((radius * math.cos(i * angle)) - center[0],
|
|
|
- 0.0,
|
|
|
- ((radius * aspectRatio * math.sin(i * angle)) -
|
|
|
- center[2]))
|
|
|
- # Scale it
|
|
|
- node.setScale(sf)
|
|
|
- # Add it to the styleMenu
|
|
|
- node.reparentTo(newStyleMenu)
|
|
|
- # Scale the whole shebang down by 0.5
|
|
|
- newStyleMenu.setScale(0.5)
|
|
|
- # Create and return a pie menu
|
|
|
- return PieMenu(newStyleMenu, styles)
|
|
|
-
|
|
|
- def createBuildingStyleSample(self, bldgStyle):
|
|
|
- """
|
|
|
- Create a style sample using the DNA info in the style
|
|
|
- """
|
|
|
- bldg = DNAFlatBuilding()
|
|
|
- self.setDNAFlatBuildingStyle(bldg, bldgStyle, width = 10.0,
|
|
|
- name = 'building_style_sample')
|
|
|
- return bldg.traverse(hidden, DNASTORE, 1)
|
|
|
-
|
|
|
- def setDNAFlatBuildingStyle(self, fb, bldgStyle, width = 10.0,
|
|
|
- heightList = None, name = 'building'):
|
|
|
- """ Set DNAFlatBuilding style. """
|
|
|
- # Remove flat building's children
|
|
|
- DNARemoveChildren(fb)
|
|
|
- # Update the name
|
|
|
- fb.setName(name)
|
|
|
- # Create the walls
|
|
|
- styleList = bldgStyle.styleList
|
|
|
- # Height list not specified, use styles default heights
|
|
|
- if not heightList:
|
|
|
- heightList = bldgStyle.heightList
|
|
|
- for i in range(len(styleList)):
|
|
|
- wallStyle = styleList[i]
|
|
|
- # Get Style
|
|
|
- if not wallStyle:
|
|
|
- # If set to None use default style
|
|
|
- wallStyle = DNAWallStyle()
|
|
|
- # Try to get height
|
|
|
- try:
|
|
|
- wallHeight = heightList[i]
|
|
|
- except IndexError:
|
|
|
- wallHeight = 10.0
|
|
|
- # Create wall accordingly
|
|
|
- wall = DNAWall()
|
|
|
- self.setDNAWallStyle(wall, wallStyle, wallHeight,
|
|
|
- width = width)
|
|
|
- # Add it to building DNA
|
|
|
- fb.add(wall)
|
|
|
- # Set the buildings width
|
|
|
- fb.setWidth(width)
|
|
|
-
|
|
|
- def setDNAWallStyle(self, wall, style, height = 10.0, width = None):
|
|
|
- """ Set DNAWall to input style. """
|
|
|
- # Remove wall's children
|
|
|
- DNARemoveChildren(wall)
|
|
|
- # Update wall attributes
|
|
|
- wall.setCode(style['wall_texture'])
|
|
|
- wall.setColor(style['wall_color'])
|
|
|
- wall.setHeight(height)
|
|
|
- # Add windows if necessary
|
|
|
- if style['window_texture']:
|
|
|
- windows = DNAWindows()
|
|
|
- windowCount = style['window_count']
|
|
|
- if width:
|
|
|
- if (width < 15.0):
|
|
|
- windowCount = min(1, windowCount)
|
|
|
- windows.setWindowCount(windowCount)
|
|
|
- # Set window's attributes
|
|
|
- windows.setCode(style['window_texture'])
|
|
|
- windows.setColor(style['window_color'])
|
|
|
- # Add windows to the wall
|
|
|
- wall.add(windows)
|
|
|
- # Add a window awning if necessary
|
|
|
- if style['window_awning_texture']:
|
|
|
- awning = DNAProp()
|
|
|
- # Update awning's attributes
|
|
|
- awning.setCode(style['window_awning_texture'])
|
|
|
- awning.setColor(style['window_awning_color'])
|
|
|
- # Add awning to window
|
|
|
- windows.add(awning)
|
|
|
- # Add a door if necessary
|
|
|
- if style['door_texture']:
|
|
|
- door = DNAFlatDoor()
|
|
|
- # Set the door's attributes
|
|
|
- door.setCode(style['door_texture'])
|
|
|
- door.setColor(style['door_color'])
|
|
|
- # Add door to wall
|
|
|
- wall.add(door)
|
|
|
- # Add a door awning if necessary
|
|
|
- if style['door_awning_texture']:
|
|
|
- awning = DNAProp()
|
|
|
- awning.setCode(style['door_awning_texture'])
|
|
|
- awning.setColor(style['door_awning_color'])
|
|
|
- door.add(awning)
|
|
|
- # And a cornice if necessary
|
|
|
- if style['cornice_texture']:
|
|
|
- cornice = DNACornice()
|
|
|
- # Set the cornice's attributes
|
|
|
- cornice.setCode(style['cornice_texture'])
|
|
|
- cornice.setColor(style['cornice_color'])
|
|
|
- # Add cornice to wall
|
|
|
- wall.add(cornice)
|
|
|
-
|
|
|
- def printFlatBuildingStyle(self, building):
|
|
|
- for i in range(building.getNumChildren()):
|
|
|
- child = building.at(i)
|
|
|
- if DNAClassEqual(child, DNA_WALL):
|
|
|
- self.printWallStyle(child)
|
|
|
-
|
|
|
- def printWallStyle(self, wall):
|
|
|
- print 'wall_texture: ' + wall.getCode()
|
|
|
- color = wall.getColor()
|
|
|
- print ('wall_color: Vec4(%.3f, %.3f, %.3f, 1.0)' %
|
|
|
- (color[0], color[1], color[2]))
|
|
|
- for i in range(wall.getNumChildren()):
|
|
|
- child = wall.at(i)
|
|
|
- if DNAClassEqual(child, DNA_WINDOWS):
|
|
|
- print 'window_texture: ' + child.getCode()
|
|
|
- color = child.getColor()
|
|
|
- print ('window_color: Vec4(%.3f, %.3f, %.3f, 1.0)' %
|
|
|
- (color[0], color[1], color[2]))
|
|
|
- # MRM: Check for awnings here
|
|
|
- elif DNAClassEqual(child, DNA_DOOR):
|
|
|
- print 'door_texture: ' + child.getCode()
|
|
|
- color = child.getColor()
|
|
|
- print ('door_color: Vec4(%.3f, %.3f, %.3f, 1.0)' %
|
|
|
- (color[0], color[1], color[2]))
|
|
|
- elif DNAClassEqual(child, DNA_FLAT_DOOR):
|
|
|
- print 'door_texture: ' + child.getCode()
|
|
|
- color = child.getColor()
|
|
|
- print ('door_color: Vec4(%.3f, %.3f, %.3f, 1.0)' %
|
|
|
- (color[0], color[1], color[2]))
|
|
|
- elif DNAClassEqual(child, DNA_CORNICE):
|
|
|
- print 'cornice_texture: ' + child.getCode()
|
|
|
- color = child.getColor()
|
|
|
- print ('cornice_color: Vec4(%.3f, %.3f, %.3f, 1.0)' %
|
|
|
- (color[0], color[1], color[2]))
|
|
|
-
|
|
|
- # COLOR PALETTE FUNCTIONS
|
|
|
- def createColorAttributes(self):
|
|
|
- # First compile color information for each neighborhood
|
|
|
- colorDictionary = {}
|
|
|
- colorMenuDictionary = {}
|
|
|
- for neighborhood in self.NEIGHBORHOODS:
|
|
|
- colorDictionary[neighborhood] = (
|
|
|
- # Create a wall style dictionary for each neighborhood
|
|
|
- self.createColorDictionary(neighborhood))
|
|
|
- # Using this dictionary, create color pie menus
|
|
|
- colorMenuDictionary[neighborhood] = (
|
|
|
- self.createColorMenus(
|
|
|
- neighborhood, colorDictionary[neighborhood]))
|
|
|
- # Now store this info in the appropriate place in the attribute dict
|
|
|
- for colorType in COLOR_TYPES:
|
|
|
- neighborhoodDict = self.attributeDictionary[colorType] = {}
|
|
|
- for neighborhood in self.NEIGHBORHOODS:
|
|
|
- attribute = LevelAttribute(colorType)
|
|
|
- dict = {}
|
|
|
- # Add colors to attribute dictionary
|
|
|
- colorList = colorDictionary[neighborhood][colorType]
|
|
|
- for i in range(len(colorList)):
|
|
|
- dict[i] = colorList[i]
|
|
|
- attribute.setDict(dict)
|
|
|
- attribute.setMenu(
|
|
|
- colorMenuDictionary[neighborhood][colorType])
|
|
|
- neighborhoodDict[neighborhood] = attribute
|
|
|
-
|
|
|
- def createColorDictionary(self, neighborhood):
|
|
|
- filename = neighborhood + '_colors.txt'
|
|
|
- print 'Loading Color Palettes from: ' + filename
|
|
|
- colorData = self.getStyleFileData(filename)
|
|
|
- return self.getColorDictionary(colorData)
|
|
|
-
|
|
|
- def getColorDictionary(self, colorData):
|
|
|
- # Initialze neighborhod color dictionary
|
|
|
- dict = {}
|
|
|
- for colorType in COLOR_TYPES:
|
|
|
- dict[colorType] = DEFAULT_COLORS[:]
|
|
|
- # Add color information to appropriate sub-list
|
|
|
- for line in colorData:
|
|
|
- pair = map(string.strip, line.split(':'))
|
|
|
- key = pair[0]
|
|
|
- if dict.has_key(key):
|
|
|
- dict[key].append(eval(pair[1]))
|
|
|
- else:
|
|
|
- print 'LevelStyleManager.getColorDictionary key not found'
|
|
|
- return dict
|
|
|
-
|
|
|
- def createColorMenus(self, neighborhood, dictionary):
|
|
|
- menuDict = {}
|
|
|
- keys = dictionary.keys()
|
|
|
- for key in keys:
|
|
|
- menuDict[key] = (
|
|
|
- self.createColorMenu(neighborhood + key, dictionary[key]))
|
|
|
- return menuDict
|
|
|
-
|
|
|
- def createColorMenu(self, menuName, colorList, radius = 0.7, sf = 2.0):
|
|
|
- # Create color chips for each color
|
|
|
- numItems = len(colorList)
|
|
|
- # Attach it to hidden for now
|
|
|
- newColorMenu = hidden.attachNewNode(menuName + 'Menu')
|
|
|
- # Compute the angle per item
|
|
|
- angle = deg2Rad(360.0/float(numItems))
|
|
|
- aspectRatio = (base.direct.dr.getWidth() / float(base.direct.dr.getHeight()))
|
|
|
- # Attach the color chips to the new menu and adjust sizes
|
|
|
- for i in range (numItems):
|
|
|
- # Create a text node--just a card, really--of the right color.
|
|
|
- tn = TextNode('colorChip')
|
|
|
- tn.setFont(DGG.getDefaultFont())
|
|
|
- tn.setTransform(Mat4.scaleMat(0.07, 0.07, 0.07 * aspectRatio))
|
|
|
- tn.setCardColor(colorList[i])
|
|
|
- tn.setCardActual(0, 1.1111, 0, 0.8333)
|
|
|
- tn.setText(' ')
|
|
|
-
|
|
|
- # Reposition it
|
|
|
- card = tn.getCardTransformed()
|
|
|
- center = (card[1] - card[0], card[3] - card[2])
|
|
|
-
|
|
|
- node = newColorMenu.attachNewNode(tn)
|
|
|
- node.setScale(sf)
|
|
|
- node.setPos(radius * math.cos(i * angle) - center[0], 0.0,
|
|
|
- ((radius * aspectRatio * math.sin(i * angle)) -
|
|
|
- center[1]))
|
|
|
- # Scale the whole shebang down by 0.5
|
|
|
- newColorMenu.setScale(0.5)
|
|
|
- # Create and return resulting pie menu
|
|
|
- return PieMenu(newColorMenu, colorList)
|
|
|
-
|
|
|
- # DNA ATTRIBUTES
|
|
|
- def createDNAAttributes(self):
|
|
|
- # Create the DNA Attribute entries
|
|
|
- # Most objects are oriented with graphical menu items
|
|
|
- # Street and props aren't oiented and use text menus
|
|
|
- for dnaType in DNA_TYPES:
|
|
|
- # Create a dictionary of dna types
|
|
|
- dict = {}
|
|
|
- if ((dnaType == 'street') or (dnaType == 'prop') or
|
|
|
- (dnaType == 'toon_landmark')):
|
|
|
- dnaList = self.getCatalogCodes(dnaType)
|
|
|
- if dnaType == 'prop':
|
|
|
- dnaList = dnaList + self.getCatalogCodes('holiday_prop')
|
|
|
- elif (dnaType == 'sign'):
|
|
|
- dnaList = [''] + self.getCatalogCodes(dnaType)
|
|
|
- elif (dnaType == 'wall'):
|
|
|
- # Add in suit walls here for now
|
|
|
- dnaList = ([None] +
|
|
|
- self.getCatalogCodesSuffix(dnaType, '_ur') +
|
|
|
- self.getCatalogCodesSuffix('suit_wall', '_ur'))
|
|
|
- else:
|
|
|
- dnaList = [None] + self.getCatalogCodesSuffix(dnaType, '_ur')
|
|
|
- # Add dnaCodes to attribute dictionary
|
|
|
- for i in range(len(dnaList)):
|
|
|
- dict[i] = dnaList[i]
|
|
|
- # Create a LevelAttribute
|
|
|
- attribute = LevelAttribute(dnaType + '_texture')
|
|
|
- attribute.setDict(dict)
|
|
|
- # Prepend None to allow option of no item
|
|
|
- if ((dnaType == 'street') or (dnaType == 'prop') or
|
|
|
- (dnaType == 'toon_landmark')):
|
|
|
- # attribute.setMenu(self.createTextPieMenu(dnaType, dnaList))
|
|
|
- attribute.setMenu(self.createScrollMenu(dnaType, dnaList))
|
|
|
- attribute.getMenu().createScrolledList()
|
|
|
- elif (dnaType == 'wall'):
|
|
|
- attribute.setMenu(self.createDNAPieMenu(dnaType, dnaList,
|
|
|
- sf = 0.25))
|
|
|
- elif (dnaType == 'sign'):
|
|
|
- attribute.setMenu(self.createDNAPieMenu(dnaType, dnaList,
|
|
|
- sf = 0.05))
|
|
|
- elif (dnaType == 'door_double'):
|
|
|
- attribute.setMenu(self.createDNAPieMenu(dnaType, dnaList,
|
|
|
- sf = 0.035))
|
|
|
- elif (dnaType == 'door_single'):
|
|
|
- attribute.setMenu(self.createDNAPieMenu(dnaType, dnaList,
|
|
|
- sf = 0.035))
|
|
|
- elif (dnaType == 'cornice'):
|
|
|
- attribute.setMenu(self.createDNAPieMenu(dnaType, dnaList,
|
|
|
- sf = 0.5))
|
|
|
- elif (dnaType == 'window'):
|
|
|
- attribute.setMenu(self.createDNAPieMenu(dnaType, dnaList,
|
|
|
- sf = 0.125))
|
|
|
- else:
|
|
|
- print 'unknown attribute'
|
|
|
- # Add it to the attributeDictionary
|
|
|
- self.attributeDictionary[dnaType + '_texture'] = attribute
|
|
|
-
|
|
|
- def createDNAPieMenu(self, dnaType, dnaList, radius = 0.7, sf = 1.0):
|
|
|
- # Get the currently available window options
|
|
|
- numItems = len(dnaList)
|
|
|
- # Create a top level node to hold the menu
|
|
|
- newMenu = hidden.attachNewNode(dnaType + 'Menu')
|
|
|
- # Compute angle increment per item
|
|
|
- angle = deg2Rad(360.0/numItems)
|
|
|
- aspectRatio = base.direct.dr.getWidth() /float(base.direct.dr.getHeight())
|
|
|
- # Add items
|
|
|
- for i in range(0, numItems):
|
|
|
- if dnaList[i]:
|
|
|
- # Get the node
|
|
|
- node = DNASTORE.findNode(dnaList[i])
|
|
|
- else:
|
|
|
- node = None
|
|
|
- if node:
|
|
|
- # Add it to the window menu
|
|
|
- # This instance was causing problems for dna nodes that were
|
|
|
- # loaded as singletons, so I changed it to copyTo.
|
|
|
- # path = node.instanceTo(newMenu)
|
|
|
- path = node.copyTo(newMenu)
|
|
|
- # Place menu nodes in a circle, offset each in X and Z
|
|
|
- # by half node width/height
|
|
|
- bounds = path.getBounds()
|
|
|
- center = bounds.getCenter()
|
|
|
- center = center * sf
|
|
|
- path.setPos((radius * math.cos(i * angle)) - center[0],
|
|
|
- 0.0,
|
|
|
- ((radius * aspectRatio * math.sin(i * angle)) -
|
|
|
- center[2]))
|
|
|
- path.setScale(sf)
|
|
|
- # Scale the whole shebang down by 0.5
|
|
|
- newMenu.setScale(0.5)
|
|
|
- # Create and return a pie menu
|
|
|
- return PieMenu(newMenu, dnaList)
|
|
|
-
|
|
|
- def createTextPieMenu(self, dnaType, textList, radius = 0.7, sf = 1.0):
|
|
|
- numItems = len(textList)
|
|
|
- # Create top level node for new menu
|
|
|
- newMenu = hidden.attachNewNode(dnaType + 'Menu')
|
|
|
- # Compute angle per item
|
|
|
- if numItems == 0:
|
|
|
- angle = 0.0
|
|
|
- else:
|
|
|
- angle = deg2Rad(360.0/numItems)
|
|
|
- aspectRatio = base.direct.dr.getWidth()/float(base.direct.dr.getHeight())
|
|
|
- # Add items
|
|
|
- for i in range (numItems):
|
|
|
- # Create text node for each item
|
|
|
- if (textList[i] != None):
|
|
|
- tn = TextNode('TextItem')
|
|
|
- tn.setFont(DGG.getDefaultFont())
|
|
|
- tn.setTransform(Mat4.scaleMat(0.07, 0.07, 0.07 * aspectRatio))
|
|
|
- tn.setTextColor(0, 0, 0, 1)
|
|
|
- tn.setCardColor(1, 1, 1, 1)
|
|
|
- tn.setCardAsMargin(0.1, 0.1, 0.1, 0.1)
|
|
|
- tn.setText(str(textList[i]))
|
|
|
-
|
|
|
- # Reposition it
|
|
|
- card = tn.getCardTransformed()
|
|
|
- center = (card[1] - card[0], card[3] - card[2])
|
|
|
-
|
|
|
- node = newMenu.attachNewNode(tn)
|
|
|
- node.setScale(sf)
|
|
|
- node.setPos(radius * math.cos(i * angle) - center[0], 0.0,
|
|
|
- ((radius * aspectRatio * math.sin(i * angle)) -
|
|
|
- center[1]))
|
|
|
-
|
|
|
- # Scale the whole shebang down by 0.5
|
|
|
- newMenu.setScale(0.5)
|
|
|
- # Create and return a pie menu
|
|
|
- return PieMenu(newMenu, textList)
|
|
|
-
|
|
|
- def createScrollMenu(self, dnaType, textList):
|
|
|
- newMenu = hidden.attachNewNode(dnaType+'ScrollMenu')
|
|
|
-
|
|
|
- return ScrollMenu(newMenu, textList)
|
|
|
-
|
|
|
- # MISCELLANEOUS MENUS
|
|
|
- def createMiscAttributes(self):
|
|
|
- # Num windows menu
|
|
|
- self.createMiscAttribute('window_count', [0, 1, 2, 3, 4])
|
|
|
- # Building width menu
|
|
|
- self.createMiscAttribute('building_width', [5, 10, 15, 15.6, 20, 20.7, 25])
|
|
|
- # Building types
|
|
|
- self.createMiscAttribute('building_type', BUILDING_TYPES)
|
|
|
- # Building heights
|
|
|
- self.createMiscAttribute('building_height', [10, 14, 20, 24, 25, 30])
|
|
|
- # MRM: Need offset on these menus
|
|
|
- # Wall orientation menu
|
|
|
- self.createMiscAttribute('wall_orientation', ['ur','ul','dl','dr'])
|
|
|
- # Wall height menu
|
|
|
- self.createMiscAttribute('wall_height', [10, 20])
|
|
|
- # Window orientation menu
|
|
|
- self.createMiscAttribute('window_orientation', ['ur','ul', None, None])
|
|
|
- # Sign orientation menu
|
|
|
- self.createMiscAttribute('sign_orientation', ['ur','ul', None, None])
|
|
|
- # Door orientation menu
|
|
|
- self.createMiscAttribute('door_orientation', ['ur','ul', None, None])
|
|
|
- # Cornice orientation menu
|
|
|
- self.createMiscAttribute('cornice_orientation', ['ur','ul', None, None])
|
|
|
-
|
|
|
- def createMiscAttribute(self, miscType, miscList, sf = 3.0):
|
|
|
- # Create a dictionary from miscList
|
|
|
- dict = {}
|
|
|
- # Add items to attribute dictionary
|
|
|
- for i in range(len(miscList)):
|
|
|
- dict[i] = miscList[i]
|
|
|
- # Create the miscellaneous Attribute entries
|
|
|
- attribute = LevelAttribute(miscType)
|
|
|
- attribute.setDict(dict)
|
|
|
- # Now create a pie menu
|
|
|
- attribute.setMenu(self.createTextPieMenu(miscType, miscList,
|
|
|
- sf = sf))
|
|
|
- # Add it to the attributeDictionary
|
|
|
- self.attributeDictionary[miscType] = attribute
|
|
|
-
|
|
|
- # GENERAL FUNCTIONS
|
|
|
- def getStyleFileData(self, filename):
|
|
|
- """
|
|
|
- Open the specified file and strip out unwanted whitespace and
|
|
|
- empty lines. Return file as list, one file line per element.
|
|
|
- """
|
|
|
- fname = Filename(dnaDirectory.getFullpath() +
|
|
|
- '/stylefiles/' + filename)
|
|
|
-
|
|
|
- # We use binary mode to avoid Windows' end-of-line convention
|
|
|
- f = open(fname.toOsSpecific(), 'rb')
|
|
|
- rawData = f.readlines()
|
|
|
- f.close()
|
|
|
- styleData = []
|
|
|
- for line in rawData:
|
|
|
- l = string.strip(line)
|
|
|
- if l:
|
|
|
- styleData.append(l)
|
|
|
- return styleData
|
|
|
-
|
|
|
- # UTILITY FUNCTIONS
|
|
|
- def getAttribute(self, attribute):
|
|
|
- """ Return specified attribute for current neighborhood """
|
|
|
- levelAttribute = self.attributeDictionary[attribute]
|
|
|
- # Get attribute for current neighborhood
|
|
|
- if (type(levelAttribute) == types.DictionaryType):
|
|
|
- levelAttribute = levelAttribute[self.getEditMode()]
|
|
|
- return levelAttribute
|
|
|
-
|
|
|
- # UTILITY FUNCTIONS
|
|
|
- def hasAttribute(self, attribute):
|
|
|
- """ Return specified attribute for current neighborhood """
|
|
|
- if not self.attributeDictionary.has_key(attribute):
|
|
|
- return 0
|
|
|
- else:
|
|
|
- levelAttribute = self.attributeDictionary[attribute]
|
|
|
- # Get attribute for current neighborhood
|
|
|
- if (type(levelAttribute) == types.DictionaryType):
|
|
|
- editMode = self.getEditMode()
|
|
|
- return levelAttribute.has_key(editMode)
|
|
|
- else:
|
|
|
- return 1
|
|
|
-
|
|
|
- def getCatalogCode(self, category, i):
|
|
|
- return DNASTORE.getCatalogCode(category, i)
|
|
|
-
|
|
|
- def getCatalogCodes(self, category):
|
|
|
- numCodes = DNASTORE.getNumCatalogCodes(category)
|
|
|
- codes = []
|
|
|
- for i in range(numCodes):
|
|
|
- codes.append(DNASTORE.getCatalogCode(category, i))
|
|
|
- return codes
|
|
|
-
|
|
|
- def getCatalogCodesSuffix(self, category, suffix):
|
|
|
- codes = self.getCatalogCodes(category)
|
|
|
- orientedCodes = []
|
|
|
- for code in codes:
|
|
|
- if code[-3:] == suffix:
|
|
|
- orientedCodes.append(code)
|
|
|
- return orientedCodes
|
|
|
-
|
|
|
- def setEditMode(self, mode):
|
|
|
- """Set current neighborhood editing mode"""
|
|
|
- self._editMode = mode
|
|
|
-
|
|
|
- def getEditMode(self):
|
|
|
- """Get current neighborhood editing mode"""
|
|
|
- return self._editMode
|
|
|
-
|
|
|
-class LevelAttribute:
|
|
|
- """Class which encapsulates a pie menu and a set of items"""
|
|
|
- def __init__(self, name):
|
|
|
- # Record name
|
|
|
- self.name = name
|
|
|
- # Pie menu used to pick an option
|
|
|
- self._menu = None
|
|
|
- # Dictionary of available options
|
|
|
- self._dict = {}
|
|
|
- self._list = []
|
|
|
- self.count = 0
|
|
|
- # Currently selected option
|
|
|
- self._current = None
|
|
|
- def setCurrent(self, newValue, fEvent = 1):
|
|
|
- self._current = newValue
|
|
|
- # Send event if specified
|
|
|
- if fEvent:
|
|
|
- messenger.send('select_' + self.name, [self._current])
|
|
|
- def setMenu(self, menu):
|
|
|
- self._menu = menu
|
|
|
- self._menu.action = self.setCurrent
|
|
|
- def setDict(self, dict):
|
|
|
- self._dict = dict
|
|
|
- # Create a list from the dictionary
|
|
|
- self._list = dict.values()
|
|
|
- # Update count
|
|
|
- self.count = len(self._list)
|
|
|
- # Initialize current to first item
|
|
|
- if (len(self._list) > 0):
|
|
|
- self._current = self._list[0]
|
|
|
- def setList(self, list):
|
|
|
- self._list = list
|
|
|
- # Create a dictionary from the list
|
|
|
- self._dict = {}
|
|
|
- self.count = 0
|
|
|
- for item in list:
|
|
|
- self._dict[self.count] = item
|
|
|
- self.count += 1
|
|
|
- # Initialize current to first item
|
|
|
- if (self.count > 0):
|
|
|
- self._current = self._list[0]
|
|
|
- def add(self, item):
|
|
|
- self._dict[self.count] = item
|
|
|
- self._list.append(item)
|
|
|
- self.count += 1
|
|
|
- def getCurrent(self):
|
|
|
- return self._current
|
|
|
- def getMenu(self):
|
|
|
- return self._menu
|
|
|
- def getDict(self):
|
|
|
- return self._dict
|
|
|
- def getList(self):
|
|
|
- return self._list
|
|
|
- def getCount(self):
|
|
|
- return self.count
|
|
|
-
|
|
|
-class DNAFlatBuildingStyle:
|
|
|
- """Class to hold attributes of a building style"""
|
|
|
- def __init__(self, building = None, styleList = None, name = 'bldg_style'):
|
|
|
- self.name = name
|
|
|
- if building:
|
|
|
- # Passed in a building
|
|
|
- self.copy(building)
|
|
|
- elif styleList != None:
|
|
|
- # Passed in a list of style-height pairs
|
|
|
- self.styleList = []
|
|
|
- self.heightList = []
|
|
|
- self.numWalls = 0
|
|
|
- for pair in styleList:
|
|
|
- self.add(pair[0], pair[1])
|
|
|
- else:
|
|
|
- # Use default style/height
|
|
|
- self.styleList = [DNAWallStyle()]
|
|
|
- self.heightList = [10]
|
|
|
- self.numWalls = 1
|
|
|
-
|
|
|
- def add(self, style, height):
|
|
|
- self.styleList.append(style)
|
|
|
- self.heightList.append(height)
|
|
|
- self.numWalls += 1
|
|
|
-
|
|
|
- def copy(self, building):
|
|
|
- self.styleList = []
|
|
|
- self.heightList = DNAGetWallHeights(building)[0]
|
|
|
- self.numWalls = 0
|
|
|
- for i in range(building.getNumChildren()):
|
|
|
- child = building.at(i)
|
|
|
- if DNAClassEqual(child, DNA_WALL):
|
|
|
- wallStyle = DNAWallStyle(wall = child)
|
|
|
- self.styleList.append(wallStyle)
|
|
|
- self.numWalls += 1
|
|
|
-
|
|
|
- def output(self, file = sys.stdout):
|
|
|
- file.write('buildingStyle: %s\n' % createHeightCode(self.heightList))
|
|
|
- for style in self.styleList:
|
|
|
- style.output(file)
|
|
|
- file.write('endBuildingStyle\n')
|
|
|
-
|
|
|
-def createHeightCode(heightList):
|
|
|
- def joinHeights(h1, h2):
|
|
|
- return '%s_%s' % (h1, h2)
|
|
|
- hl = map(ROUND_INT, heightList)
|
|
|
- if len(hl) == 1:
|
|
|
- return `hl[0]`
|
|
|
- return reduce(joinHeights, hl)
|
|
|
-
|
|
|
-def calcHeight(heightList):
|
|
|
- height = 0
|
|
|
- for h in heightList:
|
|
|
- height = height + h
|
|
|
- return int(height)
|
|
|
-
|
|
|
-class DNABaselineStyle:
|
|
|
- """Class to hold attributes of a baseline style (wiggle, colors, etc)"""
|
|
|
- def __init__(self, baseline = None, name = 'baseline_style'):
|
|
|
- # First initialize everything
|
|
|
- self.name = name
|
|
|
- self.code = None # i.e. font
|
|
|
- self.kern = None
|
|
|
- self.wiggle = None
|
|
|
- self.stumble = None
|
|
|
- self.stomp = None
|
|
|
- self.curve = None
|
|
|
- self.x = None
|
|
|
- self.z = None
|
|
|
- self.scaleX = 1.0
|
|
|
- self.scaleZ = 1.0
|
|
|
- self.roll = None
|
|
|
- self.flags = None
|
|
|
- self.color = Vec4(1.0)
|
|
|
- # Then copy the specifics for the baseline if input
|
|
|
- if baseline:
|
|
|
- self.copy(baseline)
|
|
|
-
|
|
|
- def copy(self, baseline):
|
|
|
- self.code = baseline.getCode()
|
|
|
- self.kern = baseline.getKern()
|
|
|
- self.wiggle = baseline.getWiggle()
|
|
|
- self.stumble = baseline.getStumble()
|
|
|
- self.stomp = baseline.getStomp()
|
|
|
- width=baseline.getWidth()
|
|
|
- if width:
|
|
|
- self.curve = 1.0/width
|
|
|
- else:
|
|
|
- self.curve = 0.0
|
|
|
- pos = baseline.getPos()
|
|
|
- self.x = pos[0]
|
|
|
- self.z = pos[2]
|
|
|
- scale = baseline.getScale()
|
|
|
- self.scaleX = scale[0]
|
|
|
- self.scaleZ = scale[2]
|
|
|
- hpr = baseline.getHpr()
|
|
|
- self.roll = hpr[2]
|
|
|
- self.flags = baseline.getFlags()
|
|
|
- self.color = baseline.getColor()
|
|
|
-
|
|
|
- def copyTo(self, baseline):
|
|
|
- if self.code != None:
|
|
|
- baseline.setCode(self.code)
|
|
|
- if self.kern != None:
|
|
|
- baseline.setKern(self.kern)
|
|
|
- if self.wiggle != None:
|
|
|
- baseline.setWiggle(self.wiggle)
|
|
|
- if self.stumble != None:
|
|
|
- baseline.setStumble(self.stumble)
|
|
|
- if self.stomp != None:
|
|
|
- baseline.setStomp(self.stomp)
|
|
|
- if self.curve != None:
|
|
|
- diameter=0.0
|
|
|
- if self.curve:
|
|
|
- diameter=1.0/self.curve
|
|
|
- baseline.setWidth(diameter)
|
|
|
- baseline.setHeight(diameter)
|
|
|
- if (self.x != None) or (self.z != None):
|
|
|
- pos=baseline.getPos()
|
|
|
- if self.x != None:
|
|
|
- pos=Vec3(self.x, pos[1], pos[2])
|
|
|
- if self.z != None:
|
|
|
- pos=Vec3(pos[0], pos[1], self.z)
|
|
|
- baseline.setPos(pos)
|
|
|
- if self.roll != None:
|
|
|
- baseline.setHpr(Vec3(0.0, 0.0, self.roll))
|
|
|
- if (self.scaleX != None) or (self.scaleZ != None):
|
|
|
- scale=baseline.getScale()
|
|
|
- if self.scaleX != None:
|
|
|
- scale=Vec3(self.scaleX, scale[1], scale[2])
|
|
|
- if self.scaleZ != None:
|
|
|
- scale=Vec3(scale[0], scale[1], self.scaleZ)
|
|
|
- baseline.setScale(scale)
|
|
|
- if self.flags != None:
|
|
|
- baseline.setFlags(self.flags)
|
|
|
- if self.color != None:
|
|
|
- baseline.setColor(self.color)
|
|
|
-
|
|
|
- def output(self, file = sys.stdout):
|
|
|
- """ Output style description to a file """
|
|
|
- file.write('baselineStyle\n')
|
|
|
- if self.name != None:
|
|
|
- file.write('name: %s\n' % self.name)
|
|
|
- if self.code != None:
|
|
|
- file.write('code: %s\n' % self.code)
|
|
|
- if self.kern != None:
|
|
|
- file.write('kern: %s\n' % self.kern)
|
|
|
- if self.wiggle != None:
|
|
|
- file.write('wiggle: %s\n' % self.wiggle)
|
|
|
- if self.stumble != None:
|
|
|
- file.write('stumble: %s\n' % self.stumble)
|
|
|
- if self.stomp != None:
|
|
|
- file.write('stomp: %s\n' % self.stomp)
|
|
|
- if self.curve != None:
|
|
|
- file.write('curve: %s\n' % self.curve)
|
|
|
- if self.x != None:
|
|
|
- file.write('x: %s\n' % self.x)
|
|
|
- if self.z != None:
|
|
|
- file.write('z: %s\n' % self.z)
|
|
|
- if self.scaleX != None:
|
|
|
- file.write('scaleX: %s\n' % self.scaleX)
|
|
|
- if self.scaleZ != None:
|
|
|
- file.write('scaleZ: %s\n' % self.scaleZ)
|
|
|
- if self.roll != None:
|
|
|
- file.write('roll: %s\n' % self.roll)
|
|
|
- if self.flags != None:
|
|
|
- file.write('flags: %s\n' % self.flags)
|
|
|
- if self.color != None:
|
|
|
- file.write('color: Vec4(%.2f, %.2f, %.2f, 1.0)\n'
|
|
|
- % (self.color[0], self.color[1], self.color[2]))
|
|
|
- file.write('endBaselineStyle\n')
|
|
|
-
|
|
|
- # Convience functions to facilitate class use
|
|
|
- def __setitem__(self, index, item):
|
|
|
- self.__dict__[index] = item
|
|
|
-
|
|
|
- def __getitem__(self, index):
|
|
|
- return self.__dict__[index]
|
|
|
-
|
|
|
- def __repr__(self):
|
|
|
- return(
|
|
|
- 'name: %s\n' % self.name +
|
|
|
- 'code: %s\n' % self.code +
|
|
|
- 'kern: %s\n' % self.kern +
|
|
|
- 'wiggle: %s\n' % self.wiggle +
|
|
|
- 'stumble: %s\n' % self.stumble +
|
|
|
- 'stomp: %s\n' % self.stomp +
|
|
|
- 'curve: %s\n' % self.curve +
|
|
|
- 'x: %s\n' % self.x +
|
|
|
- 'z: %s\n' % self.z +
|
|
|
- 'scaleX: %s\n' % self.scaleX +
|
|
|
- 'scaleZ: %s\n' % self.scaleZ +
|
|
|
- 'roll: %s\n' % self.roll +
|
|
|
- 'flags: %s\n' % self.flags +
|
|
|
- 'color: %s\n' % self.color
|
|
|
- )
|
|
|
-
|
|
|
-class DNAWallStyle:
|
|
|
- """Class to hold attributes of a wall style (textures, colors, etc)"""
|
|
|
- def __init__(self, wall = None, name = 'wall_style'):
|
|
|
- # First initialize everything
|
|
|
- self.name = name
|
|
|
- self.wall_texture = 'wall_md_blank_ur'
|
|
|
- self.wall_color = Vec4(1.0)
|
|
|
- self.window_count = 2
|
|
|
- self.window_texture = None
|
|
|
- self.window_color = Vec4(1.0)
|
|
|
- self.window_awning_texture = None
|
|
|
- self.window_awning_color = Vec4(1.0)
|
|
|
- self.door_texture = None
|
|
|
- self.door_color = Vec4(1.0)
|
|
|
- self.door_awning_texture = None
|
|
|
- self.door_awning_color = Vec4(1.0)
|
|
|
- self.cornice_texture = None
|
|
|
- self.cornice_color = Vec4(1.0)
|
|
|
- # Then copy the specifics for the wall if input
|
|
|
- if wall:
|
|
|
- self.copy(wall)
|
|
|
-
|
|
|
- def copy(self, wall):
|
|
|
- self.wall_texture = wall.getCode()
|
|
|
- self.wall_color = wall.getColor()
|
|
|
- for i in range(wall.getNumChildren()):
|
|
|
- child = wall.at(i)
|
|
|
- if DNAClassEqual(child, DNA_WINDOWS):
|
|
|
- self.window_count = child.getWindowCount()
|
|
|
- self.window_texture = child.getCode()
|
|
|
- self.window_color = child.getColor()
|
|
|
- # MRM: Check for awnings here
|
|
|
- elif DNAClassEqual(child, DNA_DOOR):
|
|
|
- self.door_texture = child.getCode()
|
|
|
- self.door_color = child.getColor()
|
|
|
- elif DNAClassEqual(child, DNA_FLAT_DOOR):
|
|
|
- self.door_texture = child.getCode()
|
|
|
- self.door_color = child.getColor()
|
|
|
- # MRM: Check for awnings here
|
|
|
- elif DNAClassEqual(child, DNA_CORNICE):
|
|
|
- self.cornice_texture = child.getCode()
|
|
|
- self.cornice_color = child.getColor()
|
|
|
-
|
|
|
- def output(self, file = sys.stdout):
|
|
|
- """ Output style description to a file """
|
|
|
- def writeAttributes(f, type, s = self):
|
|
|
- color = s[type + '_color']
|
|
|
- f.write('%s_texture: %s\n' % (type, s[type + '_texture']))
|
|
|
- f.write('%s_color: Vec4(%.2f, %.2f, %.2f, 1.0)\n' %
|
|
|
- (type, color[0], color[1], color[2]))
|
|
|
- file.write('wallStyle\n')
|
|
|
- writeAttributes(file, 'wall')
|
|
|
- if self['window_texture']:
|
|
|
- writeAttributes(file, 'window')
|
|
|
- file.write('window_count: %s\n' % self['window_count'])
|
|
|
- if self['window_awning_texture']:
|
|
|
- writeAttributes(file, 'window_awning')
|
|
|
- if self['door_texture']:
|
|
|
- writeAttributes(file, 'door')
|
|
|
- if self['door_awning_texture']:
|
|
|
- writeAttributes(file, 'door_awning')
|
|
|
- if self['cornice_texture']:
|
|
|
- writeAttributes(file, 'cornice')
|
|
|
- file.write('endWallStyle\n')
|
|
|
-
|
|
|
- # Convience functions to facilitate class use
|
|
|
- def __setitem__(self, index, item):
|
|
|
- self.__dict__[index] = item
|
|
|
-
|
|
|
- def __getitem__(self, index):
|
|
|
- return self.__dict__[index]
|
|
|
-
|
|
|
- def __repr__(self):
|
|
|
- return(
|
|
|
- 'Name: %s\n' % self.name +
|
|
|
- 'Wall Texture: %s\n' % self.wall_texture +
|
|
|
- 'Wall Color: %s\n' % self.wall_color +
|
|
|
- 'Window Texture: %s\n' % self.window_texture +
|
|
|
- 'Window Color: %s\n' % self.window_color +
|
|
|
- 'Window Awning Texture: %s\n' % self.window_awning_texture +
|
|
|
- 'Window Awning Color: %s\n' % self.window_awning_color +
|
|
|
- 'Door Texture: %s\n' % self.door_texture +
|
|
|
- 'Door Color: %s\n' % self.door_color +
|
|
|
- 'Door Awning Texture: %s\n' % self.door_awning_texture +
|
|
|
- 'Door Awning Color: %s\n' % self.door_awning_color +
|
|
|
- 'Cornice Texture: %s\n' % self.cornice_texture +
|
|
|
- 'Cornice Color: %s\n' % self.cornice_color
|
|
|
- )
|