• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

visgl / luma.gl / 17192022436

24 Aug 2025 06:02PM UTC coverage: 62.079% (-13.2%) from 75.234%
17192022436

Pull #2437

github

web-flow
Merge 562c391b0 into 8314ecefa
Pull Request #2437: test(engine): add ShaderPassRenderer test

956 of 1559 branches covered (61.32%)

Branch coverage included in aggregate %.

491 of 666 new or added lines in 7 files covered. (73.72%)

5291 existing lines in 117 files now uncovered.

23238 of 37414 relevant lines covered (62.11%)

3.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

10.0
/modules/engine/src/scenegraph/scenegraph-node.ts
1
// luma.gl
1✔
2
// SPDX-License-Identifier: MIT
1✔
3
// Copyright (c) vis.gl contributors
1✔
4

1✔
5
import {Vector3, Matrix4, NumericArray} from '@math.gl/core';
1✔
6
import {uid} from '../utils/uid';
1✔
7

1✔
8
/** Properties for creating a new Scenegraph */
1✔
9
export type ScenegraphNodeProps = {
1✔
10
  id?: string;
1✔
11
  /** whether to display the object at all */
1✔
12
  display?: boolean;
1✔
13
  matrix?: NumericArray;
1✔
14
  position?: NumericArray;
1✔
15
  rotation?: NumericArray;
1✔
16
  scale?: NumericArray;
1✔
17
  update?: boolean;
1✔
18
};
1✔
19

1✔
20
export class ScenegraphNode {
1!
UNCOV
21
  readonly id: string;
×
UNCOV
22
  matrix: Matrix4 = new Matrix4();
×
UNCOV
23

×
UNCOV
24
  display = true;
×
UNCOV
25
  position = new Vector3();
×
UNCOV
26
  rotation = new Vector3();
×
UNCOV
27
  scale = new Vector3(1, 1, 1);
×
UNCOV
28
  userData: Record<string, unknown> = {};
×
UNCOV
29

×
UNCOV
30
  props: ScenegraphNodeProps = {};
×
UNCOV
31

×
UNCOV
32
  constructor(props: ScenegraphNodeProps = {}) {
×
UNCOV
33
    const {id} = props;
×
UNCOV
34

×
UNCOV
35
    this.id = id || uid(this.constructor.name);
×
UNCOV
36

×
UNCOV
37
    this._setScenegraphNodeProps(props);
×
UNCOV
38
  }
×
UNCOV
39

×
UNCOV
40
  getBounds(): [number[], number[]] | null {
×
41
    return null;
×
42
  }
×
UNCOV
43

×
UNCOV
44
  destroy(): void {}
×
UNCOV
45

×
UNCOV
46
  /** @deprecated use .destroy() */
×
UNCOV
47
  delete(): void {
×
48
    this.destroy();
×
49
  }
×
UNCOV
50
  setProps(props: ScenegraphNodeProps): this {
×
UNCOV
51
    this._setScenegraphNodeProps(props);
×
UNCOV
52
    return this;
×
UNCOV
53
  }
×
UNCOV
54

×
UNCOV
55
  toString(): string {
×
UNCOV
56
    return `{type: ScenegraphNode, id: ${this.id})}`;
×
UNCOV
57
  }
×
UNCOV
58

×
UNCOV
59
  setPosition(position: any): this {
×
UNCOV
60
    // assert(position.length === 3, 'setPosition requires vector argument');
×
UNCOV
61
    this.position = position;
×
UNCOV
62
    return this;
×
UNCOV
63
  }
×
UNCOV
64

×
UNCOV
65
  setRotation(rotation: any): this {
×
UNCOV
66
    // assert(rotation.length === 3, 'setRotation requires vector argument');
×
UNCOV
67
    this.rotation = rotation;
×
UNCOV
68
    return this;
×
UNCOV
69
  }
×
UNCOV
70

×
UNCOV
71
  setScale(scale: any): this {
×
UNCOV
72
    // assert(scale.length === 3, 'setScale requires vector argument');
×
UNCOV
73
    this.scale = scale;
×
UNCOV
74
    return this;
×
UNCOV
75
  }
×
UNCOV
76

×
UNCOV
77
  setMatrix(matrix: any, copyMatrix: boolean = true): void {
×
UNCOV
78
    if (copyMatrix) {
×
UNCOV
79
      this.matrix.copy(matrix);
×
UNCOV
80
    } else {
×
UNCOV
81
      this.matrix = matrix;
×
UNCOV
82
    }
×
UNCOV
83
  }
×
UNCOV
84

×
UNCOV
85
  setMatrixComponents(components: {
×
UNCOV
86
    position?: any;
×
UNCOV
87
    rotation?: any;
×
UNCOV
88
    scale?: any;
×
UNCOV
89
    update?: boolean;
×
UNCOV
90
  }): this {
×
UNCOV
91
    const {position, rotation, scale, update = true} = components;
×
UNCOV
92
    if (position) {
×
UNCOV
93
      this.setPosition(position);
×
UNCOV
94
    }
×
UNCOV
95
    if (rotation) {
×
UNCOV
96
      this.setRotation(rotation);
×
UNCOV
97
    }
×
UNCOV
98
    if (scale) {
×
UNCOV
99
      this.setScale(scale);
×
UNCOV
100
    }
×
UNCOV
101
    if (update) {
×
UNCOV
102
      this.updateMatrix();
×
UNCOV
103
    }
×
UNCOV
104
    return this;
×
UNCOV
105
  }
×
UNCOV
106

×
UNCOV
107
  updateMatrix(): this {
×
UNCOV
108
    const pos = this.position;
×
UNCOV
109
    const rot = this.rotation;
×
UNCOV
110
    const scale = this.scale;
×
UNCOV
111

×
UNCOV
112
    this.matrix.identity();
×
UNCOV
113
    this.matrix.translate(pos);
×
UNCOV
114
    this.matrix.rotateXYZ(rot);
×
UNCOV
115
    this.matrix.scale(scale);
×
UNCOV
116
    return this;
×
UNCOV
117
  }
×
UNCOV
118

×
UNCOV
119
  update(options: {position?: any; rotation?: any; scale?: any} = {}): this {
×
UNCOV
120
    const {position, rotation, scale} = options;
×
UNCOV
121
    if (position) {
×
UNCOV
122
      this.setPosition(position);
×
UNCOV
123
    }
×
UNCOV
124
    if (rotation) {
×
UNCOV
125
      this.setRotation(rotation);
×
UNCOV
126
    }
×
UNCOV
127
    if (scale) {
×
UNCOV
128
      this.setScale(scale);
×
UNCOV
129
    }
×
UNCOV
130
    this.updateMatrix();
×
UNCOV
131
    return this;
×
UNCOV
132
  }
×
UNCOV
133

×
UNCOV
134
  getCoordinateUniforms(
×
UNCOV
135
    viewMatrix: any,
×
UNCOV
136
    modelMatrix?: any
×
UNCOV
137
  ): {
×
UNCOV
138
    viewMatrix: any;
×
UNCOV
139
    modelMatrix: any;
×
UNCOV
140
    objectMatrix: any;
×
UNCOV
141
    worldMatrix: any;
×
UNCOV
142
    worldInverseMatrix: any;
×
UNCOV
143
    worldInverseTransposeMatrix: any;
×
UNCOV
144
  } {
×
UNCOV
145
    // TODO - solve multiple class problem
×
UNCOV
146
    // assert(viewMatrix instanceof Matrix4);
×
UNCOV
147
    // assert(viewMatrix);
×
UNCOV
148
    modelMatrix = modelMatrix || this.matrix;
×
UNCOV
149
    const worldMatrix = new Matrix4(viewMatrix).multiplyRight(modelMatrix);
×
UNCOV
150
    const worldInverse = worldMatrix.invert();
×
UNCOV
151
    const worldInverseTranspose = worldInverse.transpose();
×
UNCOV
152

×
UNCOV
153
    return {
×
UNCOV
154
      viewMatrix,
×
UNCOV
155
      modelMatrix,
×
UNCOV
156
      objectMatrix: modelMatrix,
×
UNCOV
157
      worldMatrix,
×
UNCOV
158
      worldInverseMatrix: worldInverse,
×
UNCOV
159
      worldInverseTransposeMatrix: worldInverseTranspose
×
UNCOV
160
    };
×
UNCOV
161
  }
×
UNCOV
162

×
UNCOV
163
  // TODO - copied code, not yet vetted
×
UNCOV
164
  /*
×
UNCOV
165
  transform() {
×
UNCOV
166
    if (!this.parent) {
×
UNCOV
167
      this.endPosition.set(this.position);
×
UNCOV
168
      this.endRotation.set(this.rotation);
×
UNCOV
169
      this.endScale.set(this.scale);
×
UNCOV
170
    } else {
×
UNCOV
171
      const parent = this.parent;
×
UNCOV
172
      this.endPosition.set(this.position.add(parent.endPosition));
×
UNCOV
173
      this.endRotation.set(this.rotation.add(parent.endRotation));
×
UNCOV
174
      this.endScale.set(this.scale.add(parent.endScale));
×
UNCOV
175
    }
×
UNCOV
176

×
UNCOV
177
    const ch = this.children;
×
UNCOV
178
    for (let i = 0; i < ch.length; ++i) {
×
UNCOV
179
      ch[i].transform();
×
UNCOV
180
    }
×
UNCOV
181

×
UNCOV
182
    return this;
×
UNCOV
183
  }
×
UNCOV
184
  */
×
UNCOV
185

×
UNCOV
186
  _setScenegraphNodeProps(props: ScenegraphNodeProps): void {
×
UNCOV
187
    // if ('display' in props) {
×
UNCOV
188
    //   this.display = props.display;
×
UNCOV
189
    // }
×
UNCOV
190

×
UNCOV
191
    if ('position' in props) {
×
UNCOV
192
      this.setPosition(props.position);
×
UNCOV
193
    }
×
UNCOV
194
    if ('rotation' in props) {
×
UNCOV
195
      this.setRotation(props.rotation);
×
UNCOV
196
    }
×
UNCOV
197
    if ('scale' in props) {
×
UNCOV
198
      this.setScale(props.scale);
×
UNCOV
199
    }
×
UNCOV
200

×
UNCOV
201
    // Matrix overwrites other props
×
UNCOV
202
    if ('matrix' in props) {
×
UNCOV
203
      this.setMatrix(props.matrix);
×
UNCOV
204
    }
×
UNCOV
205

×
UNCOV
206
    Object.assign(this.props, props);
×
UNCOV
207
  }
×
UNCOV
208
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc