def collider(self, value): # destroy existing collider if value and hasattr(self, 'collider') and self._collider: self._collider.remove() self._collider = value if value == 'box': if self.model: self._collider = BoxCollider(entity=self, center=-self.origin, size=self.model_bounds) else: self._collider = BoxCollider(entity=self) self._collider.name = value elif value == 'sphere': self._collider = SphereCollider(entity=self, center=-self.origin) self._collider.name = value elif value == 'mesh' and self.model: self._collider = MeshCollider(entity=self, mesh=None, center=-self.origin) self._collider.name = value elif isinstance(value, Mesh): self._collider = MeshCollider(entity=self, mesh=value, center=-self.origin) elif isinstance(value, str): m = load_model(value) if not m: return self._collider = MeshCollider(entity=self, mesh=m, center=-self.origin) self._collider.name = value self.collision = bool(self.collider) return
def __setattr__(self, name, value): if name == 'enabled': try: # try calling on_enable() on classes inheriting from Entity if value == True: self.on_enable() else: self.on_disable() except: pass if value == True: if not self.is_singleton(): self.unstash() else: if not self.is_singleton(): self.stash() if name == 'visible': if value == False: object.__setattr__(self, '_parent_before_hidden', self.parent) self.reparent_to(scene.hidden) else: try: self.reparent_to(self._parent_before_hidden) except: pass object.__setattr__(self, name, value) return if name == 'world_parent': self.reparent_to(value) if name == 'model': if value is None: if hasattr(self, 'model') and self.model != None: self.model.removeNode() # print('removed model') return None if isinstance(value, NodePath): # pass procedural model if hasattr(self, 'model') and value != self.model: self.model.removeNode() object.__setattr__(self, name, value) elif isinstance(value, str): # pass model asset name m = load_model(value, application.asset_folder) if not m: m = load_model(value, application.internal_models_folder) if m: if hasattr(self, 'model'): self.model.removeNode() object.__setattr__(self, name, m) if isinstance(m, Mesh): m.recipe = value # needed when duplicating entity # print('loaded model successively') else: print('error loading model:', value) if hasattr(self, 'model') and self.model: self.model.reparentTo(self) self.model.setTransparency(TransparencyAttrib.MAlpha) setattr(self, 'color', self.color) # reapply color after changing model self._vert_cache = None if isinstance(value, Mesh): if hasattr(value, 'on_assign'): value.on_assign(assigned_to=self) return else: print('missing model:', value) if name == 'color' and value is not None: if not isinstance(value, Vec4): value = Vec4(value[0], value[1], value[2], value[3]) if hasattr(self, 'model') and self.model: self.model.setColorScale(value) object.__setattr__(self, name, value) if name == 'texture_scale': if hasattr(self, 'model') and self.model and self.texture: self.model.setTexScale(TextureStage.getDefault(), value[0], value[1]) if name == 'texture_offset': if self.model and self.texture: self.model.setTexOffset(TextureStage.getDefault(), value[0], value[1]) self.texture = self.texture if name == 'position': # automatically add position instead of extending the tuple new_value = Vec3() if len(value) % 2 == 0: for i in range(0, len(value), 2): new_value.add_x(value[i]) new_value.add_y(value[i+1]) new_value.add_z(self.getY()) if len(value) % 3 == 0: for i in range(0, len(value), 3): new_value.add_x(value[i]) new_value.add_y(value[i+1]) new_value.add_z(value[i+2]) try: self.setPos(new_value[0], new_value[2], new_value[1]) except: pass # can't set position if name == 'x': self.setX(value) if name == 'y': self.setZ(value) if name == 'z': self.setY(value) if name == 'origin' and hasattr(self, 'model') and self.model: new_value = Vec3() if len(value) % 2 == 0: for i in range(0, len(value), 2): new_value.add_x(value[i]) new_value.add_y(value[i+1]) new_value.add_z(self.model.getY()) if len(value) % 3 == 0: for i in range(0, len(value), 3): new_value.add_x(value[i]) new_value.add_y(value[i+1]) new_value.add_z(value[i+2]) self.model.setPos(-new_value[0], -new_value[2], -new_value[1]) object.__setattr__(self, name, new_value) return if name == 'rotation': new_value = Vec3() if len(value) % 2 == 0: for i in range(0, len(value), 2): new_value.add_x(value[i]) new_value.add_y(value[i+1]) new_value.add_z(self.getR()) if len(value) % 3 == 0: for i in range(0, len(value), 3): new_value.add_x(value[i]) new_value.add_y(value[i+1]) new_value.add_z(value[i+2]) self.setHpr(Vec3(-new_value[1], -new_value[0], new_value[2])) if name == 'rotation_x': self.setP(-value) if name == 'rotation_y': self.setH(-value) if name == 'rotation_z': self.setR(value) if name == 'scale': if isinstance(value, (int, float, complex)): value = (value, value, value) new_value = Vec3() if len(value) % 2 == 0: for i in range(0, len(value), 2): new_value.add_x(value[i]) new_value.add_y(value[i+1]) new_value.add_z(self.getSy()) if len(value) % 3 == 0: for i in range(0, len(value), 3): new_value.add_x(value[i]) new_value.add_y(value[i+1]) new_value.add_z(value[i+2]) for e in new_value: if e == 0: e = .001 self.setScale(new_value[0], new_value[2], new_value[1]) if name == 'scale_x': if value == 0: value = .001 self.set_scale(value, self.scale_z, self.scale_y) if name == 'scale_y': if value == 0: value = .001 self.set_scale(self.scale_x, self.scale_z, value) if name == 'scale_z': if value == 0: value = .001 self.set_scale(self.scale_x, value, self.scale_y) if name == 'collider': # destroy excisting collider if hasattr(self, 'collider') and self.collider: self.collider.remove() if value == None or isinstance(value, Collider): self.collision = not value == None object.__setattr__(self, name, value) elif value == 'box': if hasattr(self, 'model'): collider = BoxCollider( entity = self, center = -self.origin, size = self.model_bounds ) else: collider = BoxCollider(entity=self) self.collision = True object.__setattr__(self, name, collider) return elif value == 'sphere': collider = SphereCollider(entity=self) self.collision = True object.__setattr__(self, name, collider) return elif value == 'mesh' and self.model: collider = MeshCollider(entity=self, center=-self.origin) self.collision = True object.__setattr__(self, name, collider) return else: print('collider error:', value, 'is not a collider') if name == 'render_queue': if hasattr(self, 'model') and self.model: self.model.setBin('fixed', value) if name == 'double_sided': self.setTwoSided(value) try: super().__setattr__(name, value) except: pass
def __setattr__(self, name, value): if name == 'enabled': try: # try calling on_enable() on classes inheriting from Entity if value == True: self.on_enable() else: self.on_disable() except: pass if value == True: if hasattr(self, 'is_singleton') and not self.is_singleton(): self.unstash() else: if hasattr(self, 'is_singleton') and not self.is_singleton(): self.stash() if name == 'eternal': for c in self.children: c.eternal = value if name == 'world_parent': self.reparent_to(value) if name == 'model': if value is None: if hasattr(self, 'model') and self.model: self.model.removeNode() # print('removed model') object.__setattr__(self, name, value) return None if isinstance(value, NodePath): # pass procedural model if self.model is not None and value != self.model: self.model.removeNode() object.__setattr__(self, name, value) elif isinstance(value, str): # pass model asset name m = load_model(value, application.asset_folder) if not m: m = load_model(value, application.internal_models_compressed_folder) if m: if self.model is not None: self.model.removeNode() object.__setattr__(self, name, m) # if isinstance(m, Mesh): # m.recipe = value # print('loaded model successively') else: # if '.' in value: # print(f'''trying to load model with specific filename extention. please omit it. '{value}' -> '{value.split('.')[0]}' ''') print('missing model:', value) return if self.model: self.model.reparentTo(self) self.model.setTransparency(TransparencyAttrib.M_dual) self.color = self.color # reapply color after changing model self.texture = self.texture # reapply texture after changing model self._vert_cache = None if isinstance(value, Mesh): if hasattr(value, 'on_assign'): value.on_assign(assigned_to=self) return if name == 'color' and value is not None: if isinstance(value, str): value = color.hex(value) if not isinstance(value, Vec4): value = Vec4(value[0], value[1], value[2], value[3]) if self.model: self.model.setColorScaleOff() # prevent inheriting color from parent self.model.setColorScale(value) object.__setattr__(self, name, value) if name == 'collision' and hasattr(self, 'collider') and self.collider: if value: self.collider.node_path.unstash() else: self.collider.node_path.stash() object.__setattr__(self, name, value) return if name == 'render_queue': if self.model: self.model.setBin('fixed', value) if name == 'double_sided': self.setTwoSided(value) try: super().__setattr__(name, value) except: pass
def __setattr__(self, name, value): if name == 'enabled': try: # try calling on_enable() on classes inheriting from Entity if value == True: self.on_enable() else: self.on_disable() except: pass if value == True: if not self.is_singleton(): self.unstash() else: if not self.is_singleton(): self.stash() if name == 'eternal': for c in self.children: c.eternal = value if name == 'world_parent': self.reparent_to(value) if name == 'model': if value is None: if hasattr(self, 'model') and self.model: self.model.removeNode() # print('removed model') object.__setattr__(self, name, value) return None if isinstance(value, NodePath): # pass procedural model if self.model is not None and value != self.model: self.model.removeNode() object.__setattr__(self, name, value) elif isinstance(value, str): # pass model asset name m = load_model(value, application.asset_folder) if not m: m = load_model(value, application.internal_models_folder) if m: if self.model is not None: self.model.removeNode() object.__setattr__(self, name, m) if isinstance(m, Mesh): m.recipe = value # print('loaded model successively') else: print('missing model:', value) return if self.model: self.model.reparentTo(self) self.model.setTransparency(TransparencyAttrib.M_dual) self.color = self.color # reapply color after changing model self.texture = self.texture # reapply texture after changing model self._vert_cache = None if isinstance(value, Mesh): if hasattr(value, 'on_assign'): value.on_assign(assigned_to=self) return if name == 'color' and value is not None: if not isinstance(value, Vec4): value = Vec4(value[0], value[1], value[2], value[3]) if self.model: self.model.setColorScaleOff( ) # prevent inheriting color from parent self.model.setColorScale(value) object.__setattr__(self, name, value) if name == 'texture_scale': if self.model and self.texture: self.model.setTexScale(TextureStage.getDefault(), value[0], value[1]) if name == 'texture_offset': if self.model and self.texture: self.model.setTexOffset(TextureStage.getDefault(), value[0], value[1]) self.texture = self.texture if name == 'collision' and hasattr(self, 'collider') and self.collider: if value: self.collider.node_path.unstash() else: self.collider.node_path.stash() object.__setattr__(self, name, value) return if name == 'render_queue': if self.model: self.model.setBin('fixed', value) if name == 'double_sided': self.setTwoSided(value) if name == 'always_on_top' and value: self.set_bin("fixed", 0) self.set_depth_write(False) self.set_depth_test(False) try: super().__setattr__(name, value) except: pass
def __setattr__(self, name, value): if name == 'enabled': try: # try calling on_enable() on classes inheriting from Entity if value == True: self.on_enable() else: self.on_disable() except: pass if value == True: if not self.is_singleton(): self.unstash() else: if not self.is_singleton(): self.stash() if name == 'eternal': for c in self.children: c.eternal = value if name == 'world_parent': self.reparent_to(value) if name == 'model': if value is None: if hasattr(self, 'model') and self.model: self.model.removeNode() # print('removed model') object.__setattr__(self, name, value) return None if isinstance(value, NodePath): # pass procedural model if self.model is not None and value != self.model: self.model.removeNode() object.__setattr__(self, name, value) elif isinstance(value, str): # pass model asset name m = load_model(value, application.asset_folder) if not m: m = load_model(value, application.internal_models_folder) if m: if self.model is not None: self.model.removeNode() object.__setattr__(self, name, m) if isinstance(m, Mesh): m.recipe = value # print('loaded model successively') else: print('missing model:', value) return if self.model: self.model.reparentTo(self) self.model.setTransparency(TransparencyAttrib.M_dual) self.color = self.color # reapply color after changing model self.texture = self.texture # reapply texture after changing model self._vert_cache = None if isinstance(value, Mesh): if hasattr(value, 'on_assign'): value.on_assign(assigned_to=self) return if name == 'color' and value is not None: if not isinstance(value, Vec4): value = Vec4(value[0], value[1], value[2], value[3]) if self.model: self.model.setColorScale(value) object.__setattr__(self, name, value) if name == 'texture_scale': if self.model and self.texture: self.model.setTexScale(TextureStage.getDefault(), value[0], value[1]) if name == 'texture_offset': if self.model and self.texture: self.model.setTexOffset(TextureStage.getDefault(), value[0], value[1]) self.texture = self.texture if name == 'position': # automatically add position instead of extending the tuple new_value = Vec3() if len(value) % 2 == 0: for i in range(0, len(value), 2): new_value.add_x(value[i]) new_value.add_y(value[i + 1]) new_value.add_z(self.getY()) if len(value) % 3 == 0: for i in range(0, len(value), 3): new_value.add_x(value[i]) new_value.add_y(value[i + 1]) new_value.add_z(value[i + 2]) try: self.setPos(new_value[0], new_value[2], new_value[1]) except: pass # can't set position if name == 'x': self.setX(value) if name == 'y': self.setZ(value) if name == 'z': self.setY(value) if name == 'origin' and self.model: new_value = Vec3() if len(value) % 2 == 0: for i in range(0, len(value), 2): new_value.add_x(value[i]) new_value.add_y(value[i + 1]) new_value.add_z(self.model.getY()) if len(value) % 3 == 0: for i in range(0, len(value), 3): new_value.add_x(value[i]) new_value.add_y(value[i + 1]) new_value.add_z(value[i + 2]) self.model.setPos(-new_value[0], -new_value[2], -new_value[1]) object.__setattr__(self, name, new_value) return if name == 'rotation': new_value = Vec3() if len(value) % 2 == 0: for i in range(0, len(value), 2): new_value.add_x(value[i]) new_value.add_y(value[i + 1]) new_value.add_z(self.getR()) if len(value) % 3 == 0: for i in range(0, len(value), 3): new_value.add_x(value[i]) new_value.add_y(value[i + 1]) new_value.add_z(value[i + 2]) self.setHpr(Vec3(-new_value[1], -new_value[0], new_value[2])) if name == 'rotation_x': self.setP(-value) if name == 'rotation_y': self.setH(-value) if name == 'rotation_z': self.setR(value) if name == 'scale': if isinstance(value, (int, float, complex)): value = (value, value, value) new_value = Vec3() if len(value) % 2 == 0: for i in range(0, len(value), 2): new_value.add_x(value[i]) new_value.add_y(value[i + 1]) new_value.add_z(self.getSy()) if len(value) % 3 == 0: for i in range(0, len(value), 3): new_value.add_x(value[i]) new_value.add_y(value[i + 1]) new_value.add_z(value[i + 2]) for e in new_value: if e == 0: e = .001 self.setScale(new_value[0], new_value[2], new_value[1]) if name == 'scale_x': self.set_scale(value, self.scale_z, self.scale_y) if name == 'scale_y': self.set_scale(self.scale_x, self.scale_z, value) if name == 'scale_z': self.set_scale(self.scale_x, value, self.scale_y) if name == 'collision' and hasattr(self, 'collider') and self.collider: if value: self.collider.node_path.unstash() else: self.collider.node_path.stash() object.__setattr__(self, name, value) return if name == 'render_queue': if self.model: self.model.setBin('fixed', value) if name == 'double_sided': self.setTwoSided(value) try: super().__setattr__(name, value) except: pass
def __setattr__(self, name, value): if name == 'eternal': for c in self.children: c.eternal = value elif name == 'model': if value is None: if hasattr(self, 'model') and self.model: self.model.removeNode() # print('removed model') object.__setattr__(self, name, value) return None if isinstance(value, NodePath): # pass procedural model if self.model is not None and value != self.model: self.model.detachNode() object.__setattr__(self, name, value) elif isinstance(value, str): # pass model asset name m = load_model(value, application.asset_folder) if not m: m = load_model( value, application.internal_models_compressed_folder) if m: if self.model is not None: self.model.removeNode() m.name = value m.setPos(Vec3(0, 0, 0)) object.__setattr__(self, name, m) # if not value in mesh_importer.imported_meshes: # print_info('loaded model successfully:', value) else: if application.raise_exception_on_missing_model: raise ValueError(f"missing model: '{value}'") print_warning(f"missing model: '{value}'") return if self.model: self.model.reparentTo(self) self.model.setTransparency(TransparencyAttrib.M_dual) self.color = self.color # reapply color after changing model self.texture = self.texture # reapply texture after changing model self._vert_cache = None if isinstance(value, Mesh): if hasattr(value, 'on_assign'): value.on_assign(assigned_to=self) return elif name == 'color' and value is not None: if isinstance(value, str): value = color.hex(value) if not isinstance(value, Vec4): value = Vec4(value[0], value[1], value[2], value[3]) if self.model: self.model.setColorScaleOff( ) # prevent inheriting color from parent self.model.setColorScale(value) object.__setattr__(self, name, value) elif name == 'collision' and hasattr(self, 'collider') and self.collider: if value: self.collider.node_path.unstash() else: self.collider.node_path.stash() object.__setattr__(self, name, value) return elif name == 'render_queue': if self.model: self.model.setBin('fixed', value) elif name == 'double_sided': self.setTwoSided(value) elif hasattr(self, '_shader' ) and self.shader and name in self._shader.default_input: # print('set shader input:', name, value) object.__setattr__(self, name, value) self.set_shader_input(name, value) try: super().__setattr__(name, value) except: pass