lod-item.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. 'use strict';
  2. const { trackEventWithTimer } = require('../../utils/metrics');
  3. const { getMessageProtocolScene } = require('../../utils/prop');
  4. exports.template = `
  5. <ui-section :cache-expand="cacheExpandId">
  6. <header class="header" slot="header">
  7. <div class="left">
  8. <span>LOD {{ index }}</span>
  9. </div>
  10. <div class="right">
  11. <div class="info">
  12. <span> {{ totalTriangles }} Triangles - </span>
  13. <span>{{ data.value.renderers.value.length }} Sub Mesh(es)</span>
  14. </div>
  15. <div class="operator">
  16. <ui-icon value="add" @click.stop="updateLODs('insert')" tooltip="insert after this LOD"></ui-icon>
  17. <ui-icon value="reduce" @click.stop="updateLODs('delete')" tooltip="delete this LOD"></ui-icon>
  18. </div>
  19. </div>
  20. </header>
  21. <div class="content">
  22. <ui-prop>
  23. <ui-label slot="label" value="Screen Ratio (%)"></ui-label>
  24. <div class="screen-size-content" slot="content">
  25. <ui-num-input
  26. :ref="screenUsagePercentageRef"
  27. :min="minScreenUsagePercentage"
  28. :max="maxScreenUsagePercentage"
  29. :value="Editor.Utils.Math.multi(data.value.screenUsagePercentage.value, 100)"
  30. @confirm="onScreenSizeConfirm($event)">
  31. </ui-num-input>
  32. <ui-button @confirm="applyCameraSize" tooltip="i18n:ENGINE.components.lod.applyCameraSizeTip">
  33. <ui-label value="Apply Current Screen Ratio"></ui-label>
  34. </ui-button>
  35. </div>
  36. </ui-prop>
  37. <ui-prop ref="lod-item-dump" type="dump"></ui-prop>
  38. <ui-section whole class="mesh-renderers config" header="Mesh Renderers">
  39. <template v-for="(mesh, meshIndex) in data.value.renderers.value">
  40. <div class="mesh"
  41. :key="meshIndex"
  42. >
  43. <ui-component class="component" droppable="cc.MeshRenderer" placeholder="cc.MeshRenderer"
  44. :value="mesh.value.uuid"
  45. @change="onMeshConfirm($event, meshIndex)">
  46. </ui-component>
  47. <ui-label class="label"
  48. :value="handleTriangleLabel(meshIndex)"
  49. ></ui-label>
  50. </div>
  51. </template>
  52. <footer>
  53. <ui-button @confirm="updateRenderers('insert')">
  54. <ui-icon value="add"></ui-icon>
  55. </ui-button>
  56. <ui-button @confirm="updateRenderers('delete')">
  57. <ui-icon value="reduce"></ui-icon>
  58. </ui-button>
  59. </footer>
  60. </ui-section>
  61. </div>
  62. </ui-section>
  63. `;
  64. exports.props = ['dump', 'index'];
  65. exports.data = function() {
  66. const that = this;
  67. return {
  68. totalTriangles: 0,
  69. data: that.dump.value.LODs.value[that.index],
  70. minScreenUsagePercentage: null,
  71. maxScreenUsagePercentage: null,
  72. enableUpdateScreenUsagePercentage: false,
  73. };
  74. };
  75. exports.watch = {
  76. 'data.value.triangleCount': {
  77. immediate: true,
  78. handler(triangleCount) {
  79. const that = this;
  80. const res = triangleCount.value.reduce((sum, item) => {
  81. return sum += item.value;
  82. }, 0);
  83. that.totalTriangles = res;
  84. },
  85. },
  86. dump:{
  87. immediate: true,
  88. deep: true,
  89. handler(obj) {
  90. const that = this;
  91. that.enableUpdateScreenUsagePercentage = false;
  92. if (obj.value.LODs.value[that.index].value.screenUsagePercentage.value) {
  93. const LODs = obj.value.LODs.value;
  94. const min = LODs[that.index + 1] ? LODs[that.index + 1].value.screenUsagePercentage.value : 0;
  95. const max = LODs[that.index - 1] ? LODs[that.index - 1].value.screenUsagePercentage.value : null;
  96. // The minimum value is 0, and there is no restriction on the maximum value
  97. that.minScreenUsagePercentage = Editor.Utils.Math.multi(min, 100);
  98. that.maxScreenUsagePercentage = max ? Editor.Utils.Math.multi(max, 100) : null;
  99. }
  100. that.$nextTick(() => {
  101. that.data = obj.value.LODs.value[that.index];
  102. that.enableUpdateScreenUsagePercentage = true;
  103. });
  104. },
  105. },
  106. };
  107. exports.computed = {
  108. cacheExpandId() {
  109. const that = this;
  110. return `${that.dump.value.uuid.value}-lod-${that.index}`;
  111. },
  112. screenUsagePercentageRef() {
  113. const that = this;
  114. return `screenUsagePercentage-${that.index}`;
  115. },
  116. };
  117. exports.methods = {
  118. onScreenSizeConfirm(event) {
  119. const that = this;
  120. if (!that.enableUpdateScreenUsagePercentage) {
  121. return;
  122. }
  123. that.data.value.screenUsagePercentage.value = Editor.Utils.Math.divide(event.target.value, 100);
  124. that.updateDump(that.data.value.screenUsagePercentage);
  125. trackEventWithTimer('LOD', 'A100009');
  126. },
  127. onMeshConfirm(event, meshIndex) {
  128. const that = this;
  129. that.data.value.renderers.value[meshIndex].value.uuid = event.target.value;
  130. that.updateDump(that.data.value.renderers);
  131. },
  132. updateRenderers(operator) {
  133. const that = this;
  134. if (operator === 'insert') {
  135. that.data.value.renderers.value.push(that.data.value.renderers.elementTypeData);
  136. trackEventWithTimer('LOD', 'A100007');
  137. } else if (operator === 'delete') {
  138. that.data.value.renderers.value.pop();
  139. trackEventWithTimer('LOD', 'A100008');
  140. }
  141. that.updateDump(that.data.value.renderers);
  142. },
  143. updateDump(dump) {
  144. const that = this;
  145. that.$refs['lod-item-dump'].dump = dump;
  146. that.$refs['lod-item-dump'].dispatch('change-dump');
  147. that.$refs['lod-item-dump'].dispatch('confirm-dump');
  148. },
  149. updateLODs(operator) {
  150. const that = this;
  151. // emit method is recommended to all lowercase, camel case may be automatically converted to lowercase resulting in failure to match
  152. that.$emit('update-lods', operator, that.index);
  153. },
  154. async applyCameraSize() {
  155. const that = this;
  156. let size = await Editor.Message.request(getMessageProtocolScene(that.$el), 'lod-apply-current-camera-size', that.dump.value.uuid.value);
  157. if (that.$refs[that.screenUsagePercentageRef]) {
  158. const min = Editor.Utils.Math.divide(that.$refs[that.screenUsagePercentageRef].min, 100) || 0;
  159. let max = null;
  160. if (that.$refs[that.screenUsagePercentageRef].max && that.$refs[that.screenUsagePercentageRef].max !== Infinity) {
  161. max = Editor.Utils.Math.divide(that.$refs[that.screenUsagePercentageRef].max, 100);
  162. }
  163. if (size < min) {
  164. size = min;
  165. console.log(Editor.I18n.t('ENGINE.components.lod.applyCameraSizeLessThanMinimum'));
  166. } else if (max && size > max) {
  167. size = max;
  168. console.log(Editor.I18n.t('ENGINE.components.lod.applyCameraSizeGreaterThanMaximum'));
  169. }
  170. }
  171. that.data.value.screenUsagePercentage.value = size;
  172. that.updateDump(that.data.value.screenUsagePercentage);
  173. trackEventWithTimer('LOD', 'A100004');
  174. },
  175. handleTriangleLabel(meshIndex) {
  176. const that = this;
  177. return `${ that.data.value.triangleCount.value[meshIndex] ? that.data.value.triangleCount.value[meshIndex].value : 0 } Triangles`;
  178. },
  179. };