def setUp(self): self.directory = tempfile.mkdtemp() f = open(os.path.join(self.directory, "color_levels.xml"), "w") f.write(toxml(tag.Object({"class" : "CloudColorLevels"}))) f.close() f = open(os.path.join(self.directory, "opacity_levels.xml"), "w") f.write(toxml(tag.Object({"class" : "CloudOpacityLevels"}))) f.close() f = open(os.path.join(self.directory, "lod.xml"), "w") f.write(toxml(tag.Object({"class" : "CloudLOD"}))) f.close()
def generate(self): # Things to improve: # * Remove sprites that are too close. What distance should this be? # # * Sprites near the center of the cloudbox could be much larger than # the ones near the edges? This to reduce the number of sprites # needed. if not os.path.exists(self.directory): raise IOError, "Directory %s not found" % self.directory if not self.filename.endswith(".xml"): raise CloudBoxException, "Filename doesn't have .xml extension" class Sprite(object): def __init__(self, position, rotation, size): self.position = position self.rotation = rotation self.size = size sprites = [] def inside_ellipsoid(x, y, z): value1 = \ (x * x) / (self.width * self.width) + \ (y * y) / (self.depth * self.depth) value2 = \ (x * x) / (self.width * self.width) + \ (z * z) / (self.height * self.height) value3 = \ (y * y) / (self.depth * self.depth) + \ (z * z) / (self.height * self.height) return value1 < 1 and value2 < 1 and value3 < 1 def inside_box(x, y, z): return True bounds_checker = inside_box if self.ellipsoid: bounds_checker = inside_ellipsoid # first we generate X number of sprites. while len(sprites) < self.sprite_count: x = random.uniform(0 - self.width, self.width) y = random.uniform(0 - self.depth, self.depth) z = random.uniform(0 - self.height, self.height) if bounds_checker(x, y, z): rotation = random.uniform(0, 6.28) width = self.sprite_size height = self.sprite_size sprites.append(Sprite((x, y, z), rotation, (width, height))) # This section provides detection if sprites are too close to each # other. Commented it out for the time beeing since it doesn't # work well. Wonder what distance is best to use? # index = len(sprites) - 1 # while index >= 0: # index2 = len(sprites) - 1 # # while index2 >= 0: # # don't compare with myself # if index != index2: # s1 = sprites[index] # s2 = sprites[index2] # delta = ( # s1.position[0] - s2.position[0], # s1.position[1] - s2.position[1], # s1.position[2] - s2.position[2]) # distance = math.sqrt(delta[0] * delta[0] + delta[1] * delta[1] + delta[2] * delta[2]) # if distance < self.sprite_size: # # print("Removing sprite since distance was only: %.2f" % distance) # del sprites[index] # break # index2 = index2 - 1 # # index = index - 1 with open(os.path.join(self.directory, self.filename), "w") as f: xml = tag.Object( {"class" : "CloudBox"}, tag.Path(self.lod_path, name="lod"), tag.Path(self.color_path, name="color"), tag.Path(self.opacity_path, name="opacity"), tag.Vector3("%d %d %d" % (self.width, self.depth, self.height), name="size"), tag.List(*tuple([( tag.Object({"class":"CloudSprite"}, tag.Vector3("%.1f %.1f %.1f" % (sprite.position[0], sprite.position[1], sprite.position[2]), name="position"), tag.Float("%.1f" % sprite.rotation, name="rotation"), tag.Vector2("%.1f %.1f" % (sprite.size[0], sprite.size[1]), name="size")) ) for sprite in sprites]), name="sprites") ) xml_str = toxml(xml, pretty_print=True) f.write(xml_str) f.flush() return xml_str