-
Notifications
You must be signed in to change notification settings - Fork 0
/
_grutil.pyi
1604 lines (1513 loc) · 74.7 KB
/
_grutil.pyi
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
from _typeshed import StrOrBytesPath
from typing import Any, ClassVar, overload
from typing_extensions import Final, Literal, TypeAlias
from panda3d._typing import DoubleVec3Like, Vec3Like, Vec4Like
from panda3d.core._audio import AudioSound
from panda3d.core._display import DisplayRegion, GraphicsOutput
from panda3d.core._dtoolbase import TypedObject
from panda3d.core._express import Namable
from panda3d.core._gobj import InternalName, Lens, Texture, TextureStage, VertexTransform
from panda3d.core._linmath import LColor, LPoint3, LVecBase2, LVecBase2d, LVecBase2f, LVector3, LVertex
from panda3d.core._movies import MovieVideo, MovieVideoCursor
from panda3d.core._pgraph import CullTraverser, GeomNode, NodePath, PandaNode, RenderAttrib, RenderState, TransformState
from panda3d.core._pnmimage import PfmFile, PNMFileType, PNMImage
from panda3d.core._putil import ClockObject, DrawMask
from panda3d.core._text import TextNode
_ClockObject_Mode: TypeAlias = Literal[0, 1, 2, 3, 4, 5, 6, 7]
_PfmVizzer_ColumnType: TypeAlias = Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
_PfmVizzer_MeshFace: TypeAlias = Literal[1, 2, 3]
class CardMaker(Namable):
"""This class generates 2-d "cards", that is, rectangular polygons,
particularly useful for showing textures etc. in the 2-d scene graph.
"""
@overload
def __init__(self, __param0: CardMaker) -> None: ...
@overload
def __init__(self, name: str) -> None: ...
def reset(self) -> None:
"""Resets all the parameters to their initial defaults."""
@overload
def set_uv_range(self, tex: Texture) -> None:
"""`(self, ll: LTexCoord, ur: LTexCoord)`; `(self, ll: LTexCoord, lr: LTexCoord, ur: LTexCoord, ul: LTexCoord)`; `(self, ll: LTexCoord3, lr: LTexCoord3, ur: LTexCoord3, ul: LTexCoord3)`; `(self, x: LVector4, y: LVector4, z: LVector4)`:
Sets the range of UV's that will be applied to the vertices. If
set_has_uvs() is true (as it is by default), the vertices will be generated
with the indicated range of UV's, which will be useful if a texture is
applied.
`(self, tex: Texture)`:
Sets the range of UV's that will be applied to the vertices appropriately
to show the non-pad region of the texture.
"""
@overload
def set_uv_range(self, ll: LVecBase2f, ur: LVecBase2f) -> None: ...
@overload
def set_uv_range(self, x: Vec4Like, y: Vec4Like, z: Vec4Like) -> None: ...
@overload
def set_uv_range(self, ll: LVecBase2f, lr: LVecBase2f, ur: LVecBase2f, ul: LVecBase2f) -> None: ...
@overload
def set_uv_range(self, ll: Vec3Like, lr: Vec3Like, ur: Vec3Like, ul: Vec3Like) -> None: ...
def set_uv_range_cube(self, face: int) -> None:
"""Sets the range of UV's that will be applied to the vertices appropriately
for a cube-map face.
"""
def set_has_uvs(self, flag: bool) -> None:
"""Sets the flag indicating whether vertices will be generated with UV's or
not.
"""
def set_has_3d_uvs(self, flag: bool) -> None:
"""Sets the flag indicating whether vertices will be generated with
3-component UVW's (true) or 2-component UV's (the default, false).
Normally, this will be implicitly set by setting the uv_range.
"""
@overload
def set_frame(self, frame: Vec4Like) -> None:
"""Sets the size of the card."""
@overload
def set_frame(self, ll: Vec3Like, lr: Vec3Like, ur: Vec3Like, ul: Vec3Like) -> None: ...
@overload
def set_frame(self, left: float, right: float, bottom: float, top: float) -> None: ...
def set_frame_fullscreen_quad(self) -> None:
"""Sets the card to (-1,1,-1,1), which is appropriate if you plan to parent it
to render2d and use it as a fullscreen quad.
"""
@overload
def set_color(self, color: Vec4Like) -> None:
"""Sets the color of the card."""
@overload
def set_color(self, r: float, g: float, b: float, a: float) -> None: ...
def set_has_normals(self, flag: bool) -> None:
"""Sets the flag indicating whether vertices will be generated with normals or
not. Normals are required if you intend to enable lighting on the card,
but are just wasted space and bandwidth otherwise, so there is a (slight)
optimization for disabling them. If enabled, the normals will be generated
perpendicular to the card's face.
"""
def set_source_geometry(self, node: PandaNode, frame: Vec4Like) -> None:
"""Sets a node that will be copied (and scaled and translated) to generate the
frame, instead of generating a new polygon. The node may contain arbitrary
geometry that describes a flat polygon contained within the indicated left,
right, bottom, top frame.
When generate() is called, the geometry in this node will be scaled and
translated appropriately to give it the size and aspect ratio specified by
set_frame().
"""
def clear_source_geometry(self) -> None:
"""Removes the node specified by an earlier call to set_source_geometry()."""
def generate(self) -> PandaNode:
"""Generates a GeomNode that renders the specified geometry."""
setUvRange = set_uv_range
setUvRangeCube = set_uv_range_cube
setHasUvs = set_has_uvs
setHas3dUvs = set_has_3d_uvs
setFrame = set_frame
setFrameFullscreenQuad = set_frame_fullscreen_quad
setColor = set_color
setHasNormals = set_has_normals
setSourceGeometry = set_source_geometry
clearSourceGeometry = clear_source_geometry
class FisheyeMaker(Namable):
"""This class is similar to CardMaker, but instead of generating ordinary
cards, it generates a circular rose that represents the projection of a 3-D
scene through a fisheye lens. The texture coordinates of the rose are
defined so that each 2-D vertex has a 3-D UVW that reflects the
corresponding position in 3-D space of that particular vertex.
This class is particularly suited for converting cube maps to sphere maps.
"""
@overload
def __init__(self, __param0: FisheyeMaker) -> None: ...
@overload
def __init__(self, name: str) -> None: ...
def reset(self) -> None:
"""Resets all the parameters to their initial defaults."""
def set_fov(self, fov: float) -> None:
"""Specifies the field of view of the fisheye projection. A sphere map will
have a 360-degree field of view (and this is the default).
"""
def set_num_vertices(self, num_vertices: int) -> None:
"""Specifies the approximate number of vertices to be used to generate the
rose. This is the approximate number of vertices that will be located
within the rose's unit circle, not counting the inscribing square (if any).
The actual number of vertices used may be +/- 25% of this value.
"""
def set_square_inscribed(self, square_inscribed: bool, square_radius: float) -> None:
"""Sets the flag that indicates whether the rose should be inscribed within a
square. When this is true, an additional square is generated to inscribed
the circular rose, with the indicated "radius" (the sides of the square
will be 2 * square_radius). The texture coordinates of the square will
uniformly map to the back pole of the cube map.
This is mainly useful to provide a good uniform background color for a
sphere map so that it does not have a sharp circular edge that might
produce artifacts due to numerical imprecision when mapping.
"""
def set_reflection(self, reflection: bool) -> None:
"""Sets the flag indicating whether the texture image should be mirrored
(true) or normal (false). When this is true, the 3-D texture coordinates
will be reversed so that the image is appropriate for a reflection. This
is the best choice for generating a sphere map from a cube map. The
default is false.
"""
def generate(self) -> PandaNode:
"""Generates a GeomNode that renders the specified geometry."""
setFov = set_fov
setNumVertices = set_num_vertices
setSquareInscribed = set_square_inscribed
setReflection = set_reflection
class FrameRateMeter(TextNode):
"""This is a special TextNode that automatically updates itself with the
current frame rate. It can be placed anywhere in the world where you'd
like to see the frame rate.
It also has a special mode in which it may be attached directly to a
channel or window. If this is done, it creates a DisplayRegion for itself
and renders itself in the upper-right-hand corner.
"""
@overload
def __init__(self, __param0: FrameRateMeter) -> None: ...
@overload
def __init__(self, name: str) -> None: ...
def setup_window(self, window: GraphicsOutput) -> None:
"""Sets up the frame rate meter to create a DisplayRegion to render itself
into the indicated window.
"""
def clear_window(self) -> None:
"""Undoes the effect of a previous call to setup_window()."""
def get_window(self) -> GraphicsOutput:
"""Returns the GraphicsOutput that was passed to setup_window(), or NULL if
setup_window() has not been called.
"""
def get_display_region(self) -> DisplayRegion:
"""Returns the DisplayRegion that the meter has created to render itself into
the window to setup_window(), or NULL if setup_window() has not been
called.
"""
def set_update_interval(self, update_interval: float) -> None:
"""Specifies the number of seconds that should elapse between updates to the
frame rate indication. This should be reasonably slow (e.g. 0.2 to 1.0)
so that the calculation of the frame rate text does not itself dominate the
frame rate.
"""
def get_update_interval(self) -> float:
"""Returns the number of seconds that will elapse between updates to the frame
rate indication.
"""
def set_text_pattern(self, text_pattern: str) -> None:
"""Sets the sprintf() pattern that is used to format the text. The string
"%f" or some variant will be replaced with the current frame rate in frames
per second.
"""
def get_text_pattern(self) -> str:
"""Returns the sprintf() pattern that is used to format the text."""
def set_clock_object(self, clock_object: ClockObject | _ClockObject_Mode) -> None:
"""Sets the clock that is used to determine the frame rate. The default is
the application's global clock (ClockObject::get_global_clock()).
"""
def get_clock_object(self) -> ClockObject:
"""Returns the clock that is used to determine the frame rate."""
def update(self) -> None:
"""You can call this to explicitly force the FrameRateMeter to update itself
with the latest frame rate information. Normally, it is not necessary to
call this explicitly.
"""
setupWindow = setup_window
clearWindow = clear_window
getWindow = get_window
getDisplayRegion = get_display_region
setUpdateInterval = set_update_interval
getUpdateInterval = get_update_interval
setTextPattern = set_text_pattern
getTextPattern = get_text_pattern
setClockObject = set_clock_object
getClockObject = get_clock_object
class GeoMipTerrain(TypedObject):
"""GeoMipTerrain, meaning Panda3D GeoMipMapping, can convert a heightfield
image into a 3D terrain, consisting of several GeomNodes. It uses the
GeoMipMapping algorithm, or Geometrical MipMapping, based on the LOD (Level
of Detail) algorithm. For more information about the GeoMipMapping
algoritm, see this paper, written by Willem H. de Boer:
https://flipcode.com/articles/article_geomipmaps.pdf
"""
AFM_off: Final[Literal[0]]
AFMOff: Final[Literal[0]]
AFM_light: Final[Literal[1]]
AFMLight: Final[Literal[1]]
AFM_medium: Final[Literal[2]]
AFMMedium: Final[Literal[2]]
AFM_strong: Final[Literal[3]]
AFMStrong: Final[Literal[3]]
def __init__(self, name: str) -> None: ...
def heightfield(self) -> PNMImage:
"""Returns a reference to the heightfield (a PNMImage) contained inside
GeoMipTerrain. You can use the reference to alter the heightfield.
"""
@overload
def set_heightfield(self, image: PNMImage) -> bool:
"""Loads the specified heightmap image file into the heightfield. Returns
true if succeeded, or false if an error has occured. If the heightmap is
not a power of two plus one, it is scaled up using a gaussian filter.
"""
@overload
def set_heightfield(self, filename: StrOrBytesPath, type: PNMFileType = ...) -> bool: ...
def color_map(self) -> PNMImage:
"""Returns a reference to the color map (a PNMImage) contained inside
GeoMipTerrain. You can use the reference to alter the color map.
"""
@overload
def set_color_map(self, image: PNMImage | Texture) -> bool:
"""Loads the specified image as color map. The next time generate() is
called, the terrain is painted with this color map using the vertex color
column. Returns a boolean indicating whether the operation has succeeded.
"""
@overload
def set_color_map(self, path: str) -> bool: ...
@overload
def set_color_map(self, filename: StrOrBytesPath, type: PNMFileType = ...) -> bool: ...
def has_color_map(self) -> bool:
"""Returns whether a color map has been set."""
def clear_color_map(self) -> None:
"""Clears the color map."""
def calc_ambient_occlusion(self, radius: float = ..., contrast: float = ..., brightness: float = ...) -> None:
"""Calculates an approximate for the ambient occlusion and stores it in the
color map, so that it will be written to the vertex colors. Any existing
color map will be discarded. You need to call this before generating the
geometry.
"""
def get_elevation(self, x: float, y: float) -> float:
"""Fetches the elevation at (x, y), where the input coordinate is specified in
pixels. This ignores the current LOD level and instead provides an
accurate number. Linear blending is used for non-integral coordinates.
Terrain scale is NOT taken into account! To get accurate normals, please
multiply this with the terrain Z scale!
trueElev = terr.get_elevation(x,y) * terr.get_sz();
"""
@overload
def get_normal(self, x: int, y: int) -> LVector3:
"""`(self, x: int, y: int)`:
Fetches the terrain normal at (x, y), where the input coordinate is
specified in pixels. This ignores the current LOD level and instead
provides an accurate number. Terrain scale is NOT taken into account! To
get accurate normals, please divide it by the terrain scale and normalize
it again, like this:
LVector3 normal (terr.get_normal(x, y)); normal.set(normal.get_x() /
root.get_sx(), normal.get_y() / root.get_sy(), normal.get_z() /
root.get_sz()); normal.normalize();
`(self, mx: int, my: int, x: int, y: int)`:
Fetches the terrain normal at (x,y), where the input coordinate is
specified in pixels. This ignores the current LOD level and instead
provides an accurate number. Terrain scale is NOT taken into account! To
get accurate normals, please divide it by the terrain scale and normalize
it again!
"""
@overload
def get_normal(self, mx: int, my: int, x: int, y: int) -> LVector3: ...
def set_bruteforce(self, bf: bool) -> None:
"""Sets a boolean specifying whether the terrain will be rendered bruteforce.
If the terrain is rendered bruteforce, there will be no Level of Detail,
and the update() call will only update the terrain if it is marked dirty.
"""
def get_bruteforce(self) -> bool:
"""Returns a boolean whether the terrain is rendered bruteforce or not. See
set_bruteforce for more information.
"""
def set_auto_flatten(self, mode: int) -> None:
"""The terrain can be automatically flattened (using flatten_light,
flatten_medium, or flatten_strong) after each update. This only affects
future updates, it doesn't flatten the current terrain.
"""
@overload
def set_focal_point(self, fp: DoubleVec3Like | LVecBase2d | LVecBase2f | Vec3Like) -> None:
"""`(self, fp: LPoint2d)`:
The focal point is the point at which the terrain will have the highest
quality (lowest level of detail). Parts farther away from the focal point
will have a lower quality (higher level of detail). The focal point is
not taken in respect if bruteforce is set true.
`(self, x: float, y: float)`:
Sets the focal point. GeoMipTerrain generates high-resolution terrain
around the focal point, and progressively lower and lower resolution
terrain as you get farther away. If a point is supplied and not a
NodePath, make sure it's relative to the terrain. Only the x and y
coordinates of the focal point are taken in respect.
"""
@overload
def set_focal_point(self, fnp: NodePath) -> None: ...
@overload
def set_focal_point(self, x: float, y: float) -> None: ...
def get_focal_point(self) -> NodePath:
"""Returns the focal point, as a NodePath. If you have set it to be just a
point, it will return an empty node at the focal position.
"""
def get_root(self) -> NodePath:
"""Returns the root of the terrain. This is a single PandaNode to which all
the rest of the terrain is parented. The generate and update operations
replace the nodes which are parented to this root, but they don't replace
this root itself.
"""
def set_block_size(self, newbs: int) -> None:
"""Sets the block size. If it is not a power of two, the closest power of two
is used.
"""
def get_block_size(self) -> int:
"""Gets the block size."""
def get_max_level(self) -> int:
"""Returns the highest level possible for this block size. When a block is at
this level, it will be the worst quality possible.
"""
def set_min_level(self, minlevel: int) -> None:
"""Sets the minimum level of detail at which blocks may be generated by
generate() or update(). The default value is 0, which is the highest
quality. This value is also taken in respect when generating the terrain
bruteforce.
"""
def get_min_level(self) -> int:
"""Gets the minimum level of detail at which blocks may be generated by
generate() or update(). The default value is 0, which is the highest
quality.
"""
def is_dirty(self) -> bool:
"""Returns a bool indicating whether the terrain is marked 'dirty', that means
the terrain has to be regenerated on the next update() call, because for
instance the heightfield has changed. Once the terrain has been
regenerated, the dirty flag automatically gets reset internally.
"""
def set_factor(self, factor: float) -> None:
"""DEPRECATED method. Use set_near/far instead. Sets the quality factor at
which blocks must be generated. The higher this level, the better quality
the terrain will be, but more expensive to render. A value of 0 makes the
terrain the lowest quality possible, depending on blocksize. The default
value is 100.
"""
def set_near_far(self, input_near: float, input_far: float) -> None:
"""Sets the near and far LOD distances in one call."""
def set_near(self, input_near: float) -> None:
"""Sets the near LOD distance, at which the terrain will be rendered at
highest quality. This distance is in the terrain's coordinate space!
"""
def set_far(self, input_far: float) -> None:
"""Sets the far LOD distance, at which the terrain will be rendered at lowest
quality. This distance is in the terrain's coordinate space!
"""
def get_block_node_path(self, mx: int, my: int) -> NodePath:
"""Returns the NodePath of the specified block. If auto-flatten is enabled
and the node is getting removed during the flattening process, it will
still return a NodePath with the appropriate terrain chunk, but it will be
in a temporary scenegraph. Please note that this returns a const object
and you can not modify the node. Modify the heightfield instead.
"""
def get_block_from_pos(self, x: float, y: float) -> LVecBase2:
"""Gets the coordinates of the block at the specified position. This position
must be relative to the terrain, not to render. Returns an array
containing two values: the block x and the block y coords. If the
positions are out of range, the closest block is taken. Note that the
VecBase returned does not represent a vector, position, or rotation, but it
contains the block index of the block which you can use in
GeoMipTerrain::get_block_node_path.
"""
def set_border_stitching(self, stitching: bool) -> None:
"""If this value is true, the LOD level at the borders of the terrain will be
0. This is useful if you have multiple terrains attached and you want to
stitch them together, to fix seams. This setting also has effect when
bruteforce is enabled, although in that case you are probably better off
with setting the minlevels to the same value.
"""
def get_border_stitching(self) -> bool:
"""Returns the current stitching setting. False by default, unless
set_stitching has been set.
"""
def get_far(self) -> float:
"""Returns the far LOD distance in the terrain coordinate space"""
def get_near(self) -> float:
"""Returns the near LOD distance in the terrain coordinate space"""
def get_flatten_mode(self) -> int:
"""Returns the automatic-flatten mode (e.g., off, flatten_light,
flatten_medium, or flatten_strong)
"""
def make_slope_image(self) -> PNMImage:
"""Returns a new grayscale image containing the slope angles. A white pixel
value means a vertical slope, while a black pixel will mean that the
terrain is entirely flat at that pixel. You can translate it to degrees by
mapping the greyscale values from 0 to 90 degrees. The resulting image
will have the same size as the heightfield image. The scale will be taken
into respect -- meaning, if you change the terrain scale, the slope image
will need to be regenerated in order to be correct.
"""
def generate(self) -> None:
"""(Re)generates the entire terrain, erasing the current. This call un-
flattens the terrain, so make sure you have set auto-flatten if you want to
keep your terrain flattened.
"""
def update(self) -> bool:
"""Loops through all of the terrain blocks, and checks whether they need to be
updated. If that is indeed the case, it regenerates the mipmap. Returns a
true when the terrain has changed. Returns false when the terrain isn't
updated at all. If there is no terrain yet, it generates the entire
terrain. This call un-flattens the terrain, so make sure you have set
auto-flatten if you want to keep your terrain flattened.
"""
setHeightfield = set_heightfield
colorMap = color_map
setColorMap = set_color_map
hasColorMap = has_color_map
clearColorMap = clear_color_map
calcAmbientOcclusion = calc_ambient_occlusion
getElevation = get_elevation
getNormal = get_normal
setBruteforce = set_bruteforce
getBruteforce = get_bruteforce
setAutoFlatten = set_auto_flatten
setFocalPoint = set_focal_point
getFocalPoint = get_focal_point
getRoot = get_root
setBlockSize = set_block_size
getBlockSize = get_block_size
getMaxLevel = get_max_level
setMinLevel = set_min_level
getMinLevel = get_min_level
isDirty = is_dirty
setFactor = set_factor
setNearFar = set_near_far
setNear = set_near
setFar = set_far
getBlockNodePath = get_block_node_path
getBlockFromPos = get_block_from_pos
setBorderStitching = set_border_stitching
getBorderStitching = get_border_stitching
getFar = get_far
getNear = get_near
getFlattenMode = get_flatten_mode
makeSlopeImage = make_slope_image
class HeightfieldTesselator(Namable):
@overload
def __init__(self, __param0: HeightfieldTesselator) -> None: ...
@overload
def __init__(self, name: str) -> None: ...
def heightfield(self) -> PNMImage:
"""Returns a reference to the heightfield (a PNMImage) contained inside the
HeightfieldTesselator. You can use the reference to alter the heightfield.
"""
def set_heightfield(self, filename: StrOrBytesPath, type: PNMFileType = ...) -> bool:
"""Loads the specified greyscale image file into the heightfield."""
def set_poly_count(self, n: int) -> None:
"""Sets the polygon-count target. The tesselator usually manages to come
within about 20% of the target, plus or minus.
"""
def set_visibility_radius(self, r: int) -> None:
"""Sets the visibility radius. Polygons that are completely outside the
radius (relative to the focal point) are cropped away. The cropping is
imperfect (all approximations are conservative), so this should be used in
conjunction with a far clipping plane, fog, or some other visibility
limiting mechanism. The units are in pixels.
"""
def set_focal_point(self, x: int, y: int) -> None:
"""Sets the focal point. The tesselator generates high-resolution terrain
around the focal point, and progressively lower and lower resolution
terrain as you get farther away. The units are in pixels.
"""
def set_horizontal_scale(self, h: float) -> None:
"""Sets the horizontal scale. The default scale is 1.0, meaning that each
pixel in the heightfield is 1x1 panda units wide.
"""
def set_vertical_scale(self, v: float) -> None:
"""Sets the vertical scale. The default scale is 255.0, meaning that each as
the gray value ranges from (0-1), the elevation ranges from (0-255) feet.
"""
def set_max_triangles(self, n: int) -> None:
"""Sets the max triangles per geom."""
def get_elevation(self, x: float, y: float) -> float:
"""Fetches the elevation at (x,y), where the input coordinate is specified in
pixels. This ignores the current tesselation level and instead provides an
accurate number. Linear blending is used for non-integral coordinates.
"""
def generate(self) -> NodePath:
"""Generates a tree of nodes that represents the heightfield. This can be
reparented into the scene.
"""
setHeightfield = set_heightfield
setPolyCount = set_poly_count
setVisibilityRadius = set_visibility_radius
setFocalPoint = set_focal_point
setHorizontalScale = set_horizontal_scale
setVerticalScale = set_vertical_scale
setMaxTriangles = set_max_triangles
getElevation = get_elevation
class LineSegs(Namable):
"""Encapsulates creation of a series of connected or disconnected line
segments or points, for drawing paths or rays. This class doesn't attempt
to be the smartest it could possibly be; it's intended primarily as a
visualization and editing tool.
"""
@overload
def __init__(self, name: str = ...) -> None:
"""Constructs a LineSegs object, which can be used to create any number of
disconnected lines or points of various thicknesses and colors through the
visible scene. After creating the object, call move_to() and draw_to()
repeatedly to describe the path, then call create() to create a GeomNode
which will render the described path.
"""
@overload
def __init__(self, __param0: LineSegs) -> None: ...
def reset(self) -> None:
"""Removes any lines in progress and resets to the initial empty state."""
@overload
def set_color(self, color: Vec4Like) -> None:
"""Establishes the color that will be assigned to all vertices created by
future calls to move_to() and draw_to().
"""
@overload
def set_color(self, r: float, g: float, b: float, a: float = ...) -> None: ...
def set_thickness(self, thick: float) -> None:
"""Establishes the line thickness or point size in pixels that will be
assigned to all lines and points created by future calls to create().
"""
@overload
def move_to(self, v: Vec3Like) -> None:
"""Moves the pen to the given point without drawing a line. When followed by
draw_to(), this marks the first point of a line segment; when followed by
move_to() or create(), this creates a single point.
"""
@overload
def move_to(self, x: float, y: float, z: float) -> None: ...
@overload
def draw_to(self, v: Vec3Like) -> None:
"""Draws a line segment from the pen's last position (the last call to move_to
or draw_to) to the indicated point. move_to() and draw_to() only update
tables; the actual drawing is performed when create() is called.
"""
@overload
def draw_to(self, x: float, y: float, z: float) -> None: ...
def get_current_position(self) -> LVertex:
"""Returns the pen's current position. The next call to draw_to() will draw a
line segment from this point.
"""
def is_empty(self) -> bool:
"""Returns true if move_to() or draw_to() have not been called since the last
reset() or create(), false otherwise.
"""
@overload
def create(self, dynamic: bool = ...) -> GeomNode:
"""`(self, previous: GeomNode, dynamic: bool = ...)`:
Appends to an existing GeomNode a new Geom that will render the series of
line segments and points described via calls to move_to() and draw_to().
The lines and points are created with the color and thickness established
by calls to set_color() and set_thickness().
If dynamic is true, the line segments will be created with the dynamic Geom
setting, optimizing them for runtime vertex animation.
`(self, dynamic: bool = ...)`:
Creates a new GeomNode that will render the series of line segments and
points described via calls to move_to() and draw_to(). The lines and
points are created with the color and thickness established by calls to
set_color() and set_thickness().
If dynamic is true, the line segments will be created with the dynamic Geom
setting, optimizing them for runtime vertex animation.
"""
@overload
def create(self, previous: GeomNode, dynamic: bool = ...) -> GeomNode: ...
def get_num_vertices(self) -> int:
"""Returns the total number of line segment and point vertices generated by
the last call to create(). The positions of these vertices may be read and
adjusted through get_vertex() and set_vertex().
"""
def get_vertex(self, n: int) -> LVertex:
"""Returns the nth point or vertex of the line segment sequence generated by
the last call to create(). The first move_to() generates vertex 0;
subsequent move_to() and draw_to() calls generate consecutively higher
vertex numbers.
"""
@overload
def set_vertex(self, n: int, vert: Vec3Like) -> None:
"""Moves the nth point or vertex of the line segment sequence generated by the
last call to create(). The first move_to() generates vertex 0; subsequent
move_to() and draw_to() calls generate consecutively higher vertex numbers.
"""
@overload
def set_vertex(self, vertex: int, x: float, y: float, z: float) -> None: ...
def get_vertex_color(self, vertex: int) -> LColor:
"""Returns the color of the nth point or vertex."""
@overload
def set_vertex_color(self, vertex: int, c: Vec4Like) -> None:
"""Changes the vertex color of the nth point or vertex. See set_vertex()."""
@overload
def set_vertex_color(self, vertex: int, r: float, g: float, b: float, a: float = ...) -> None: ...
def get_vertices(self) -> tuple[LVertex, ...]: ...
def get_vertex_colors(self) -> tuple[LColor, ...]: ...
setColor = set_color
setThickness = set_thickness
moveTo = move_to
drawTo = draw_to
getCurrentPosition = get_current_position
isEmpty = is_empty
getNumVertices = get_num_vertices
getVertex = get_vertex
setVertex = set_vertex
getVertexColor = get_vertex_color
setVertexColor = set_vertex_color
getVertices = get_vertices
getVertexColors = get_vertex_colors
class MeshDrawer(TypedObject):
"""Mesh drawer creates a single geom object that can be shaped with different
draw commands. This is an efficient way to render bunch of billboards,
particles, fast changing triangles. Its implemented by recycling same geom
over and over again. Max budget specifies how many triangles are allowed.
Some uses of this class can be : particle system, radar icons, health bars,
2d icons, 2d ui, bullets, missile trails. Any that can be drawn with
triangles can be drawn with this class. At the low level this uses the
GeomVertexRewriter's. The internal geom consists of vertex, normal, uv and
color channels.
"""
def __init__(self) -> None:
"""Creates the MeshDrawer low level system."""
def set_budget(self, budget: int) -> None:
"""Sets the total triangle budget of the drawer. This will not be exceeded.
Don't set some thing too large because it will be slow
"""
def get_budget(self) -> int:
"""Gets the total triangle budget of the drawer"""
def get_root(self) -> NodePath:
"""Returns the root NodePath. You should use this node to reparent mesh
drawer onto the scene might also want to disable depth draw or enable
transparency.
"""
def begin(self, camera: NodePath, render: NodePath) -> None:
"""Pass the current camera node and the root node. Passing the camera is
required to generate bill boards that face it.
"""
def tri(
self,
v1: Vec3Like,
c1: Vec4Like,
uv1: LVecBase2f,
v2: Vec3Like,
c2: Vec4Like,
uv2: LVecBase2f,
v3: Vec3Like,
c3: Vec4Like,
uv3: LVecBase2f,
) -> None:
"""Draws a triangle with the given parameters."""
def particle(self, pos: Vec3Like, frame: Vec4Like, size: float, color: Vec4Like, rotation: float) -> None:
"""Draws a particle that is sort of like a bill board but has an extra
rotation component. Frame contains u,v,u-size,v-size quadruple.
"""
def blended_particle(
self, pos: Vec3Like, frame1: Vec4Like, frame2: Vec4Like, blend: float, size: float, color: Vec4Like, rotation: float
) -> None:
"""Works just like particle but accepts 2 frames and a blend (from 0 to 1)
component between them Frame contains u,v,u-size,v-size quadruple.
"""
def billboard(self, pos: Vec3Like, frame: Vec4Like, size: float, color: Vec4Like) -> None:
"""Draws a billboard - particle with no rotation. Billboards always face the
camera. Frame contains u,v,u-size,v-size quadruple.
"""
def segment(self, start: Vec3Like, stop: Vec3Like, frame: Vec4Like, thickness: float, color: Vec4Like) -> None:
"""Draws a segment a line with a thickness. That has billboarding effect.
Frame contains u,v,u-size,v-size quadruple.
"""
def cross_segment(self, start: Vec3Like, stop: Vec3Like, frame: Vec4Like, thickness: float, color: Vec4Like) -> None:
"""Draws a segment a line with a thickness. This segment does not use the
bill boarding behavior and instead draws 2 planes in a cross. Stars at
start and ends at stop. Frame contains u,v,u-size,v-size quadruple.
"""
def uneven_segment(
self,
start: Vec3Like,
stop: Vec3Like,
frame: Vec4Like,
thickness_start: float,
color_start: Vec4Like,
thickness_stop: float,
color_stop: Vec4Like,
) -> None:
"""Draws a segment a line with different thickness and color on both sides.
Stars at start and ends at stop. Frame contains u,v,u-size,v-size
quadruple.
"""
def link_segment(self, pos: Vec3Like, frame: Vec4Like, thickness: float, color: Vec4Like) -> None:
"""Stars or continues linked segment. Control position, frame, thickness and
color with parameters. Frame contains u,v,u-size,v-size quadruple.
"""
def link_segment_end(self, frame: Vec4Like, color: Vec4Like) -> None:
"""Finish drawing linked segments, needs at least two calls to link_segment
before it can end the linked segment. Frame contains u,v,u-size,v-size
quadruple.
"""
def explosion(
self, pos: Vec3Like, frame: Vec4Like, size: float, color: Vec4Like, seed: int, number: int, distance: float
) -> None:
"""Draws number of particles in a sphere like emitter. Frame contains
u,v,u-size,v-size quadruple.
"""
def stream(
self, start: Vec3Like, stop: Vec3Like, frame: Vec4Like, size: float, color: Vec4Like, number: int, offset: float
) -> None:
"""Draws a number of particles in a big line with a shift dictated by the
offset. Frame contains u,v,u-size,v-size quadruple.
"""
def geometry(self, node: NodePath) -> None:
"""Draws the geometry that is inside this node path into the MeshDrawer
object. This performs a similar functions as RigidBodyCombiner but for
very dynamic situations that share the same texture like physcal chunks of
explosions. It can be a little slow
"""
def end(self) -> None:
"""Finish the drawing and clearing off the remaining vertexes."""
setBudget = set_budget
getBudget = get_budget
getRoot = get_root
blendedParticle = blended_particle
crossSegment = cross_segment
unevenSegment = uneven_segment
linkSegment = link_segment
linkSegmentEnd = link_segment_end
class MeshDrawer2D(TypedObject):
"""This class allows the drawing of 2D objects - mainly based on quads and
rectangles. It allows clipping and several high level UI theme functions.
"""
def __init__(self) -> None:
"""Creates the MeshDrawer2D low level system."""
def set_budget(self, budget: int) -> None:
"""Sets the total triangle budget of the drawer."""
def get_budget(self) -> int:
"""Gets the total triangle budget of the drawer."""
def get_root(self) -> NodePath:
"""Returns the root NodePath."""
def quad_raw(
self,
v1: Vec3Like,
c1: Vec4Like,
uv1: LVecBase2f,
v2: Vec3Like,
c2: Vec4Like,
uv2: LVecBase2f,
v3: Vec3Like,
c3: Vec4Like,
uv3: LVecBase2f,
v4: Vec3Like,
c4: Vec4Like,
uv4: LVecBase2f,
) -> None:
"""Draws a 2D rectangle. Ignores the clipping rectangle."""
def rectangle_raw(
self, x: float, y: float, w: float, h: float, u: float, v: float, us: float, vs: float, color: Vec4Like
) -> None: ...
def set_clip(self, x: float, y: float, w: float, h: float) -> None:
"""Sets the clipping rectangle."""
def rectangle(
self, x: float, y: float, w: float, h: float, u: float, v: float, us: float, vs: float, color: Vec4Like
) -> None:
"""Draws a 2D rectangle which can be clipped."""
def rectangle_border(
self,
x: float,
y: float,
w: float,
h: float,
r: float,
t: float,
l: float,
b: float,
tr: float,
tt: float,
tl: float,
tb: float,
u: float,
v: float,
us: float,
vs: float,
color: Vec4Like,
) -> None:
"""Draws a 2d rectangle, with borders and corders, taken from the surrounding
texture
"""
def rectangle_border_tiled(
self,
x: float,
y: float,
w: float,
h: float,
r: float,
t: float,
l: float,
b: float,
tr: float,
tt: float,
tl: float,
tb: float,
u: float,
v: float,
us: float,
vs: float,
color: Vec4Like,
) -> None:
"""Draws a 2d rectangle, with borders and corders, taken from the surrounding
texture
"""
def rectangle_tiled(
self, x: float, y: float, w: float, h: float, u: float, v: float, us: float, vs: float, color: Vec4Like
) -> None:
"""Draws a tiled rectangle, size of tiles is in us and vs"""
def begin(self) -> None:
"""Opens up the geom for drawing, don't forget to call MeshDrawer2D::end()"""
def end(self) -> None:
"""Finish the drawing and clearing off the remaining vertexes."""
setBudget = set_budget
getBudget = get_budget
getRoot = get_root
quadRaw = quad_raw
rectangleRaw = rectangle_raw
setClip = set_clip
rectangleBorder = rectangle_border
rectangleBorderTiled = rectangle_border_tiled
rectangleTiled = rectangle_tiled
class MovieTexture(Texture):
"""A texture that fetches video frames from an underlying object of class
Movie.
"""
time: float
loop: bool
loop_count: int
play_rate: float
@property
def video_length(self) -> float: ...
@property
def video_width(self) -> int: ...
@property
def video_height(self) -> int: ...
@property
def playing(self) -> bool: ...
@overload
def __init__(self, video: MovieVideo) -> None:
"""`(self, video: MovieVideo)`:
Creates a texture playing the specified movie.
`(self, name: str)`:
Creates a blank movie texture. Movies must be added using do_read_one or
do_load_one.
"""
@overload
def __init__(self, name: str) -> None: ...
def get_video_length(self) -> float:
"""Returns the length of the video."""
def get_video_width(self) -> int:
"""Returns the width in texels of the source video stream. This is not
necessarily the width of the actual texture, since the texture may have
been expanded to raise it to a power of 2.
"""
def get_video_height(self) -> int:
"""Returns the height in texels of the source video stream. This is not
necessarily the height of the actual texture, since the texture may have
been expanded to raise it to a power of 2.
"""
def get_color_cursor(self, page: int) -> MovieVideoCursor:
"""Returns the MovieVideoCursor that is feeding the color channels for the
indicated page, where 0 <= page < get_num_pages().
"""
def get_alpha_cursor(self, page: int) -> MovieVideoCursor:
"""Returns the MovieVideoCursor that is feeding the alpha channel for the
indicated page, where 0 <= page < get_num_pages().
"""
def restart(self) -> None:
"""Start playing the movie from where it was last paused. Has no effect if
the movie is not paused, or if the movie's cursor is already at the end.
"""
def stop(self) -> None:
"""Stops a currently playing or looping movie right where it is. The movie's
cursor remains frozen at the point where it was stopped.
"""
def play(self) -> None:
"""Plays the movie from the beginning."""
def set_time(self, t: float) -> None:
"""Sets the movie's cursor."""
def get_time(self) -> float:
"""Returns the current value of the movie's cursor. If the movie's loop count
is greater than one, then its length is effectively multiplied for the
purposes of this function. In other words, the return value will be in the
range 0.0 to (length * loopcount).
"""
def set_loop(self, enable: bool) -> None:
"""If true, sets the movie's loop count to 1 billion. If false, sets the
movie's loop count to one.
"""
def get_loop(self) -> bool:
"""Returns true if the movie's loop count is not equal to one."""
def set_loop_count(self, count: int) -> None:
"""Sets the movie's loop count to the desired value."""
def get_loop_count(self) -> int:
"""Returns the movie's loop count."""
def set_play_rate(self, play_rate: float) -> None:
"""Sets the movie's play-rate. This is the speed at which the movie's cursor
advances. The default is to advance 1.0 movie-seconds per real-time
second.
"""
def get_play_rate(self) -> float:
"""Gets the movie's play-rate."""
def is_playing(self) -> bool:
"""Returns true if the movie's cursor is advancing."""
def synchronize_to(self, sound: AudioSound) -> None:
"""Synchronize this texture to a sound. Typically, you would load the texture
and the sound from the same AVI file.
"""
def unsynchronize(self) -> None:
"""Stop synchronizing with a sound."""
getVideoLength = get_video_length
getVideoWidth = get_video_width
getVideoHeight = get_video_height
getColorCursor = get_color_cursor
getAlphaCursor = get_alpha_cursor
setTime = set_time
getTime = get_time
setLoop = set_loop
getLoop = get_loop
setLoopCount = set_loop_count
getLoopCount = get_loop_count
setPlayRate = set_play_rate
getPlayRate = get_play_rate
isPlaying = is_playing
synchronizeTo = synchronize_to
class MultitexReducer:
"""This object presents an interface for generating new texture images that
represent the combined images from one or more individual textures,
reproducing certain kinds of multitexture effects without depending on
multitexture support in the hardware.
This also flattens out texture matrices and removes extra texture