yzt
2023-05-26 de4278af2fd46705a40bac58ec01122db6b7f3d7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import AlphaPipelineStage from "./AlphaPipelineStage.js";
import BatchTexturePipelineStage from "./BatchTexturePipelineStage.js";
import Check from "../../Core/Check.js";
import CustomShaderMode from "./CustomShaderMode.js";
import defaultValue from "../../Core/defaultValue.js";
import defined from "../../Core/defined.js";
import FeatureIdPipelineStage from "./FeatureIdPipelineStage.js";
import CPUStylingPipelineStage from "./CPUStylingPipelineStage.js";
import DequantizationPipelineStage from "./DequantizationPipelineStage.js";
import GeometryPipelineStage from "./GeometryPipelineStage.js";
import LightingPipelineStage from "./LightingPipelineStage.js";
import MaterialPipelineStage from "./MaterialPipelineStage.js";
import ModelExperimentalUtility from "./ModelExperimentalUtility.js";
import PickingPipelineStage from "./PickingPipelineStage.js";
import VertexAttributeSemantic from "../VertexAttributeSemantic.js";
 
/**
 * In memory representation of a single primitive, that is, a primitive
 * and its corresponding mesh.
 *
 * @param {Object} options An object containing the following options:
 * @param {ModelComponents.Primitive} options.primitive The primitive component.
 * @param {ModelExperimental} options.model The {@link ModelExperimental} this primitive belongs to.
 *
 * @alias ModelExperimentalPrimitive
 * @constructor
 *
 * @private
 */
export default function ModelExperimentalPrimitive(options) {
  options = defaultValue(options, defaultValue.EMPTY_OBJECT);
  //>>includeStart('debug', pragmas.debug);
  Check.typeOf.object("options.primitive", options.primitive);
  Check.typeOf.object("options.node", options.node);
  Check.typeOf.object("options.model", options.model);
  //>>includeEnd('debug');
 
  /**
   * The primitive component associated with this primitive.
   *
   * @type {ModelComponents.Primitive}
   *
   * @private
   */
  this.primitive = options.primitive;
 
  /**
   * A reference to the node this primitive belongs to.
   *
   * @type {ModelComponents.Node}
   *
   * @private
   */
  this.node = options.node;
 
  /**
   * A reference to the model
   *
   * @type {ModelExperimental}
   *
   * @private
   */
  this.model = options.model;
 
  /**
   * Pipeline stages to apply to this primitive. This
   * is an array of classes, each with a static method called
   * <code>process()</code>
   *
   * @type {Object[]}
   * @readonly
   *
   * @private
   */
  this.pipelineStages = [];
 
  initialize(this);
}
 
function initialize(runtimePrimitive) {
  var pipelineStages = runtimePrimitive.pipelineStages;
 
  var primitive = runtimePrimitive.primitive;
  var node = runtimePrimitive.node;
  var model = runtimePrimitive.model;
  var customShader = model.customShader;
 
  var hasCustomShader = defined(customShader);
  var hasCustomFragmentShader =
    hasCustomShader && defined(customShader.fragmentShaderText);
  var materialsEnabled =
    !hasCustomFragmentShader ||
    customShader.mode !== CustomShaderMode.REPLACE_MATERIAL;
  var hasQuantization = ModelExperimentalUtility.hasQuantizedAttributes(
    primitive.attributes
  );
 
  pipelineStages.push(GeometryPipelineStage);
 
  if (hasQuantization) {
    pipelineStages.push(DequantizationPipelineStage);
  }
 
  if (materialsEnabled) {
    pipelineStages.push(MaterialPipelineStage);
  }
 
  pipelineStages.push(LightingPipelineStage);
 
  // Add the FeatureIdPipelineStage and BatchTexturePipelineStage when the primitive has features, i.e. when at least one of the following conditions exists:
  // - the node is instanced and has feature ID attributes
  // - the primitive has a feature ID vertex attributes
  // - the primitive has a feature ID texture
  // It must be noted that we check for the presence of feature ID vertex attributes, and not feature ID attributes, because it is possible to have features in a model
  // without a feature table (for example, in 3D Tiles 1.0, where batch length > 0 but a batch table is not defined.)
  var featureIdAttributeIndex = model.featureIdAttributeIndex;
  var featureIdTextureIndex = model.featureIdTextureIndex;
  var hasInstancedFeatureIdAttribute;
  if (
    defined(node.instances) &&
    node.instances.featureIdAttributes.length > 0
  ) {
    var featureIdAttributes = node.instances.featureIdAttributes;
    if (defined(featureIdAttributes[featureIdAttributeIndex])) {
      hasInstancedFeatureIdAttribute = true;
    }
  }
  var hasFeatureIdVertexAttribute = defined(
    ModelExperimentalUtility.getAttributeBySemantic(
      primitive,
      VertexAttributeSemantic.FEATURE_ID
    )
  );
  var hasFeatureIdTexture = defined(
    primitive.featureIdTextures[featureIdTextureIndex]
  );
  var hasFeatureIds =
    hasInstancedFeatureIdAttribute ||
    hasFeatureIdVertexAttribute ||
    hasFeatureIdTexture;
  if (hasInstancedFeatureIdAttribute || hasFeatureIds) {
    pipelineStages.push(FeatureIdPipelineStage);
    pipelineStages.push(BatchTexturePipelineStage);
    pipelineStages.push(CPUStylingPipelineStage);
  }
 
  if (model.allowPicking) {
    pipelineStages.push(PickingPipelineStage);
  }
 
  pipelineStages.push(AlphaPipelineStage);
 
  return;
}