component_instance.py (18912B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\cosmetics\common\ships\skins\live_data\component_instance.py 2 import math 3 from cosmetics.common.ships.skins.live_data.component_license_type import ComponentLicenseType 4 from cosmetics.common.ships.skins.static_data.component import ComponentsDataLoader 5 from cosmetics.common.ships.skins.static_data.pattern_attribute import PatternAttribute 6 from signals import Signal 7 DEFAULT_SCALING_RATIO = 0.5 8 DEFAULT_OFFSET_RATIO = 0.0 9 DEFAULT_YAW = 0.999 10 DEFAULT_PITCH = 0.999 11 DEFAULT_ROLL = 0.0 12 DEFAULT_MIRRORED = False 13 14 class BaseComponentInstance(object): 15 VECTOR3_PROTO = None 16 VECTOR4_PROTO = None 17 18 def __init__(self, component_id): 19 self._component_id = component_id 20 self._component_license_to_use = None 21 self.on_licence_to_use_changed = Signal('on_licence_to_use_changed') 22 self.on_attribute_changed = Signal('on_attribute_changed') 23 24 @property 25 def component_id(self): 26 return self._component_id 27 28 @property 29 def component_license_to_use(self): 30 return self._component_license_to_use 31 32 @component_license_to_use.setter 33 def component_license_to_use(self, value): 34 self._component_license_to_use = value 35 self.on_licence_to_use_changed(self.component_id, value) 36 37 def get_component_data(self): 38 if not self._component_id: 39 return None 40 return ComponentsDataLoader.get_component_data(self._component_id) 41 42 def copy_params_from_other(self, other_component, should_copy_components_to_use = False): 43 if should_copy_components_to_use: 44 self.component_license_to_use = other_component.component_license_to_use 45 46 def build_params_from_proto(self, payload): 47 raise NotImplementedError 48 49 def build_proto(self): 50 raise NotImplementedError 51 52 def get_component_license(self): 53 return self.component_license_to_use 54 55 @property 56 def sequence_binder_type_id(self): 57 return self.get_component_data().sequence_binder_type_id 58 59 @property 60 def category(self): 61 return self.get_component_data().category 62 63 @property 64 def sequence_binder_amount_required(self): 65 if self.component_license_to_use and self.component_license_to_use.license_type == ComponentLicenseType.UNLIMITED: 66 return self.get_component_data().sequence_binder_required_amount 67 limited_item_type = self.get_component_data().get_item_type(ComponentLicenseType.LIMITED) 68 unlimited_item_type = self.get_component_data().get_item_type(ComponentLicenseType.UNLIMITED) 69 if unlimited_item_type and not limited_item_type: 70 return self.get_component_data().sequence_binder_required_amount 71 return 0 72 73 @property 74 def sequence_binder_amount_required_if_bound(self): 75 return self.get_component_data().sequence_binder_required_amount 76 77 def apply_user_authored_values(self): 78 pass 79 80 def _apply_user_authored_values(self): 81 pass 82 83 84 class BaseMaterialComponentInstance(BaseComponentInstance): 85 COATING_CONFIGURATION_PROTO = None 86 87 def __init__(self, component_id): 88 super(BaseMaterialComponentInstance, self).__init__(component_id) 89 self._diffuse_color = [0, 90 0, 91 0, 92 0] 93 self._dust_diffuse_color = [0, 94 0, 95 0, 96 0] 97 self._fresnel_color = [0, 98 0, 99 0, 100 0] 101 self._gloss = [0, 102 0, 103 0, 104 0] 105 106 @property 107 def diffuse_color(self): 108 return self._diffuse_color 109 110 @diffuse_color.setter 111 def diffuse_color(self, value): 112 self._diffuse_color = value 113 114 @property 115 def dust_diffuse_color(self): 116 return self._dust_diffuse_color 117 118 @dust_diffuse_color.setter 119 def dust_diffuse_color(self, value): 120 self._dust_diffuse_color = value 121 122 @property 123 def fresnel_color(self): 124 return self._fresnel_color 125 126 @fresnel_color.setter 127 def fresnel_color(self, value): 128 self._fresnel_color = value 129 130 @property 131 def gloss(self): 132 return self._gloss 133 134 @gloss.setter 135 def gloss(self, value): 136 self._gloss = value 137 138 def copy_params_from_other(self, other_component, should_copy_components_to_use = False): 139 self.diffuse_color = other_component.diffuse_color 140 self.dust_diffuse_color = other_component.dust_diffuse_color 141 self.fresnel_color = other_component.fresnel_color 142 self.gloss = other_component.gloss 143 super(BaseMaterialComponentInstance, self).copy_params_from_other(other_component, should_copy_components_to_use) 144 145 def build_params_from_proto(self, payload): 146 self.diffuse_color = [payload.diffuse_color.x, 147 payload.diffuse_color.y, 148 payload.diffuse_color.z, 149 payload.diffuse_color.w] 150 self.dust_diffuse_color = [payload.dust_diffuse_color.x, 151 payload.dust_diffuse_color.y, 152 payload.dust_diffuse_color.z, 153 payload.dust_diffuse_color.w] 154 self.fresnel_color = [payload.fresnel_color.x, 155 payload.fresnel_color.y, 156 payload.fresnel_color.z, 157 payload.fresnel_color.w] 158 self.gloss = [payload.gloss.x, 159 payload.gloss.y, 160 payload.gloss.z, 161 payload.gloss.w] 162 163 def build_proto(self): 164 config = self.COATING_CONFIGURATION_PROTO() 165 config.diffuse_color.CopyFrom(self.VECTOR4_PROTO(x=self._diffuse_color[0], y=self._diffuse_color[1], z=self._diffuse_color[2], w=self._diffuse_color[3])) 166 config.dust_diffuse_color.CopyFrom(self.VECTOR4_PROTO(x=self._dust_diffuse_color[0], y=self._dust_diffuse_color[1], z=self._dust_diffuse_color[2], w=self._dust_diffuse_color[3])) 167 config.fresnel_color.CopyFrom(self.VECTOR4_PROTO(x=self._fresnel_color[0], y=self._fresnel_color[1], z=self._fresnel_color[2], w=self._fresnel_color[3])) 168 config.gloss.CopyFrom(self.VECTOR4_PROTO(x=self._gloss[0], y=self._gloss[1], z=self._gloss[2], w=self._gloss[3])) 169 return config 170 171 def __eq__(self, other): 172 if other is None: 173 return False 174 return self.component_id == other.component_id and self.diffuse_color == other.diffuse_color and self.dust_diffuse_color == other.dust_diffuse_color and self.fresnel_color == other.fresnel_color and self.gloss == other.gloss 175 176 def __ne__(self, other): 177 return not self.__eq__(other) 178 179 def __str__(self): 180 result = '' 181 result += 'component id: %s\n' % self.component_id 182 result += 'params: \n' 183 result += 'diffuse color: %s %s %s %s\n' % (self.diffuse_color[0], 184 self.diffuse_color[1], 185 self.diffuse_color[2], 186 self.diffuse_color[3]) 187 result += 'dust diffuse color: %s %s %s %s\n' % (self.dust_diffuse_color[0], 188 self.dust_diffuse_color[1], 189 self.dust_diffuse_color[2], 190 self.dust_diffuse_color[3]) 191 result += 'fresnel color: %s %s %s %s\n' % (self.fresnel_color[0], 192 self.fresnel_color[1], 193 self.fresnel_color[2], 194 self.fresnel_color[3]) 195 result += 'gloss: %s %s %s %s' % (self.gloss[0], 196 self.gloss[1], 197 self.gloss[2], 198 self.gloss[3]) 199 return result 200 201 202 K_MIN_SCALE = 0.1 203 K_MAX_SCALE = 3.6 204 205 def ratio_to_scale(ratio, scaling_multiplier): 206 return scaling_multiplier * (K_MIN_SCALE + ratio ** 2 * K_MAX_SCALE) 207 208 209 def scale_to_ratio(scale, scaling_multiplier): 210 return math.sqrt(max(0, (scale / scaling_multiplier - K_MIN_SCALE) / K_MAX_SCALE)) 211 212 213 default_scaling_ratio = 0.5 214 215 class BasePatternComponentInstance(BaseComponentInstance): 216 PATTERN_CONFIGURATION_PROTO = None 217 218 def __init__(self, component_id, scaling_multiplier = 1.0): 219 super(BasePatternComponentInstance, self).__init__(component_id) 220 component_data = self.get_component_data() 221 self._projection_area1 = True 222 self._projection_area2 = True 223 self._projection_area3 = True 224 self._projection_area4 = True 225 self._projection_type_u = component_data.projection_type_uv[0] if component_data else 0 226 self._projection_type_v = component_data.projection_type_uv[1] if component_data else 0 227 self._position = [0, 0, 0] 228 self._rotation = [0, 229 0, 230 0, 231 0] 232 self._ellipsoid_center = [0, 0, 0] 233 self._ellipsoid_radii = [1.0, 1.0, 1.0] 234 default_scaling_ratio = DEFAULT_SCALING_RATIO 235 s = ratio_to_scale(default_scaling_ratio, scaling_multiplier) 236 self._scaling = [s, s, s] 237 self._scaling_ratio = default_scaling_ratio 238 self._scaling_multiplier = scaling_multiplier 239 self._offset_u_ratio = DEFAULT_OFFSET_RATIO 240 self._offset_v_ratio = DEFAULT_OFFSET_RATIO 241 self._yaw = DEFAULT_YAW 242 self._pitch = DEFAULT_PITCH 243 self._roll = DEFAULT_ROLL 244 self._mirrored = DEFAULT_MIRRORED 245 self.is_built_from_proto = False 246 247 @property 248 def projection_area1(self): 249 return self._projection_area1 250 251 @projection_area1.setter 252 def projection_area1(self, value): 253 self._projection_area1 = value 254 self.on_attribute_changed(self, PatternAttribute.PROJECT_TO_AREA_1, value) 255 256 @property 257 def projection_area2(self): 258 return self._projection_area2 259 260 @projection_area2.setter 261 def projection_area2(self, value): 262 self._projection_area2 = value 263 self.on_attribute_changed(self, PatternAttribute.PROJECT_TO_AREA_2, value) 264 265 @property 266 def projection_area3(self): 267 return self._projection_area3 268 269 @projection_area3.setter 270 def projection_area3(self, value): 271 self._projection_area3 = value 272 self.on_attribute_changed(self, PatternAttribute.PROJECT_TO_AREA_3, value) 273 274 @property 275 def projection_area4(self): 276 return self._projection_area4 277 278 @projection_area4.setter 279 def projection_area4(self, value): 280 self._projection_area4 = value 281 self.on_attribute_changed(self, PatternAttribute.PROJECT_TO_AREA_4, value) 282 283 def get_projection_areas(self): 284 return [self.projection_area1, 285 self.projection_area2, 286 self.projection_area3, 287 self.projection_area4] 288 289 @property 290 def projection_type_u(self): 291 return self._projection_type_u or 0 292 293 @property 294 def projection_type_v(self): 295 return self._projection_type_v or 0 296 297 @property 298 def position(self): 299 return self._position 300 301 @position.setter 302 def position(self, value): 303 self._position = list(value) 304 self.on_attribute_changed(self, PatternAttribute.POSITION, value) 305 306 @property 307 def rotation(self): 308 return self._rotation 309 310 @rotation.setter 311 def rotation(self, value): 312 self._rotation = list(value) 313 self.on_attribute_changed(self, PatternAttribute.ROTATION, value) 314 315 @property 316 def ellipsoid_center(self): 317 return self._ellipsoid_center 318 319 @ellipsoid_center.setter 320 def ellipsoid_center(self, value): 321 self._ellipsoid_center = value 322 323 @property 324 def ellipsoid_radii(self): 325 return self._ellipsoid_radii 326 327 @ellipsoid_radii.setter 328 def ellipsoid_radii(self, value): 329 if 0 in value: 330 raise ValueError('Zero value passed in as ellipsoid radius') 331 self._ellipsoid_radii = value 332 333 @property 334 def offset_u_ratio(self): 335 return self._offset_u_ratio 336 337 @offset_u_ratio.setter 338 def offset_u_ratio(self, value): 339 value = max(-1.0, min(value, 1.0)) 340 self._offset_u_ratio = value 341 self.apply_user_authored_values() 342 self.on_attribute_changed(self, PatternAttribute.OFFSET_U_RATIO, value) 343 344 @property 345 def offset_v_ratio(self): 346 return self._offset_v_ratio 347 348 @offset_v_ratio.setter 349 def offset_v_ratio(self, value): 350 value = max(-1.0, min(value, 1.0)) 351 self._offset_v_ratio = value 352 self.apply_user_authored_values() 353 self.on_attribute_changed(self, PatternAttribute.OFFSET_V_RATIO, value) 354 355 @property 356 def yaw(self): 357 return self._yaw 358 359 @yaw.setter 360 def yaw(self, value): 361 if value >= 1.0: 362 value -= 2.0 363 elif value < -1.0: 364 value += 2.0 365 self._yaw = value 366 self.apply_user_authored_values() 367 self.on_attribute_changed(self, PatternAttribute.YAW_RATIO, value) 368 369 @property 370 def pitch(self): 371 return self._pitch 372 373 @pitch.setter 374 def pitch(self, value): 375 value = max(-0.999, min(value, 0.999)) 376 self._pitch = value 377 self.apply_user_authored_values() 378 self.on_attribute_changed(self, PatternAttribute.PITCH_RATIO, value) 379 380 @property 381 def roll(self): 382 return self._roll 383 384 @roll.setter 385 def roll(self, value): 386 if value > 1.0: 387 value -= 2.0 388 elif value < -1.0: 389 value += 2.0 390 self._roll = value 391 self.apply_user_authored_values() 392 self.on_attribute_changed(self, PatternAttribute.ROLL_RATIO, value) 393 394 @property 395 def scaling(self): 396 return self._scaling 397 398 @scaling.setter 399 def scaling(self, value): 400 self._scaling = list(value) 401 self.on_attribute_changed(self, PatternAttribute.SCALE, value) 402 403 @property 404 def scaling_ratio(self): 405 return scale_to_ratio(self.scaling[0], self.scaling_multiplier) 406 407 @scaling_ratio.setter 408 def scaling_ratio(self, value): 409 value = max(0.0, min(value, 1.0)) 410 self._scaling_ratio = value 411 scale = ratio_to_scale(value, self.scaling_multiplier) 412 self.scaling = (scale, scale, scale) 413 414 @property 415 def scaling_multiplier(self): 416 return self._scaling_multiplier 417 418 @scaling_multiplier.setter 419 def scaling_multiplier(self, value): 420 self._scaling_multiplier = value 421 self.scaling_ratio = self.scaling_ratio 422 423 @property 424 def mirrored(self): 425 return self._mirrored 426 427 @mirrored.setter 428 def mirrored(self, value): 429 self._mirrored = value 430 self.on_attribute_changed(self, PatternAttribute.MIRROR, value) 431 432 def reset_rotation_scale_and_offset(self): 433 self.yaw = DEFAULT_YAW 434 self.pitch = DEFAULT_PITCH 435 self.roll = DEFAULT_ROLL 436 self.offset_u_ratio = DEFAULT_OFFSET_RATIO 437 self.offset_v_ratio = DEFAULT_OFFSET_RATIO 438 self.scaling_ratio = DEFAULT_SCALING_RATIO 439 440 def copy_params_from_other(self, other_component, should_copy_components_to_use = False): 441 self._projection_area1 = other_component.projection_area1 442 self._projection_area2 = other_component.projection_area2 443 self._projection_area3 = other_component.projection_area3 444 self._projection_area4 = other_component.projection_area4 445 self._position = other_component._position 446 self._rotation = other_component._rotation 447 self._scaling = other_component._scaling 448 self._mirrored = other_component.mirrored 449 self._yaw = other_component.yaw 450 self._pitch = other_component.pitch 451 self._roll = other_component.roll 452 self._offset_u_ratio = other_component.offset_u_ratio 453 self._offset_v_ratio = other_component.offset_v_ratio 454 self._ellipsoid_radii = other_component.ellipsoid_radii 455 self._ellipsoid_center = other_component.ellipsoid_center 456 self.is_built_from_proto = other_component.is_built_from_proto 457 if not other_component.is_built_from_proto: 458 self._apply_user_authored_values() 459 super(BasePatternComponentInstance, self).copy_params_from_other(other_component, should_copy_components_to_use) 460 461 def build_params_from_proto(self, payload): 462 self._projection_area1 = payload.projection.area1 463 self._projection_area2 = payload.projection.area2 464 self._projection_area3 = payload.projection.area3 465 self._projection_area4 = payload.projection.area4 466 self._projection_type_u = payload.projection.projection_type_u 467 self._projection_type_v = payload.projection.projection_type_v 468 self._position = [payload.transform.position.x, payload.transform.position.y, payload.transform.position.z] 469 self._rotation = [payload.transform.rotation.x, 470 payload.transform.rotation.y, 471 payload.transform.rotation.z, 472 payload.transform.rotation.w] 473 self._scaling = [payload.transform.scaling.x, payload.transform.scaling.y, payload.transform.scaling.z] 474 self._mirrored = payload.mirrored 475 self.is_built_from_proto = True 476 477 def build_proto(self): 478 config = self.PATTERN_CONFIGURATION_PROTO() 479 config.projection.area1 = self._projection_area1 480 config.projection.area2 = self._projection_area2 481 config.projection.area3 = self._projection_area3 482 config.projection.area4 = self._projection_area4 483 config.projection.projection_type_u = self._projection_type_u 484 config.projection.projection_type_v = self._projection_type_v 485 config.transform.position.CopyFrom(self.VECTOR3_PROTO(x=self._position[0], y=self._position[1], z=self._position[2])) 486 config.transform.rotation.CopyFrom(self.VECTOR4_PROTO(x=self._rotation[0], y=self._rotation[1], z=self._rotation[2], w=self._rotation[3])) 487 config.transform.scaling.CopyFrom(self.VECTOR3_PROTO(x=self._scaling[0], y=self._scaling[1], z=self._scaling[2])) 488 config.mirrored = self.mirrored 489 return config 490 491 def __eq__(self, other): 492 if other is None: 493 return False 494 return self.component_id == other.component_id and self.position == other.position and self.rotation == other.rotation and self.scaling == other.scaling and self.projection_area1 == other.projection_area1 and self.projection_area2 == other.projection_area2 and self.projection_area3 == other.projection_area3 and self.projection_area4 == other.projection_area4 and self.projection_type_u == other.projection_type_u and self.projection_type_v == other.projection_type_v and self.mirrored == other.mirrored 495 496 def __ne__(self, other): 497 return not self.__eq__(other) 498 499 def __str__(self): 500 result = '' 501 result += 'component id: %s\n' % self.component_id 502 result += 'params: \n' 503 result += 'projection areas: %s %s %s %s\n' % (self.projection_area1, 504 self.projection_area2, 505 self.projection_area3, 506 self.projection_area4) 507 result += 'projection type u: %s v: %s\n' % (self.projection_type_u, self.projection_type_v) 508 result += 'position: %s\n' % self.position 509 result += 'rotation: %s\n' % self.rotation 510 result += 'scaling: %s\n' % self.scaling 511 result += 'mirrored: %s\n' % self.mirrored 512 result += 'ellipsoid_radii: %s\n' % repr(self.ellipsoid_radii) 513 result += 'ellipsoid_center: %s\n' % repr(self.ellipsoid_center) 514 return result