diff --git a/doc/classes/AudioStreamPlayer3D.xml b/doc/classes/AudioStreamPlayer3D.xml
deleted file mode 100644
index 5263bd7..0000000
--- a/doc/classes/AudioStreamPlayer3D.xml
+++ /dev/null
@@ -1,149 +0,0 @@
-
-
-
- Plays positional sound in 3D space.
-
-
- Plays a sound effect with directed sound effects, dampens with distance if needed, generates effect of hearable position in space. For greater realism, a low-pass filter is automatically applied to distant sounds. This can be disabled by setting [member attenuation_filter_cutoff_hz] to [code]20500[/code].
- By default, audio is heard from the camera position. This can be changed by adding a [Listener] node to the scene and enabling it by calling [method Listener.make_current] on it.
- See also [AudioStreamPlayer] to play a sound non-positionally.
- [b]Note:[/b] Hiding an [AudioStreamPlayer3D] node does not disable its audio output. To temporarily disable an [AudioStreamPlayer3D]'s audio output, set [member unit_db] to a very low value like [code]-100[/code] (which isn't audible to human hearing).
-
-
- $DOCS_URL/tutorials/audio/audio_streams.md
-
-
-
-
-
- Returns the position in the [AudioStream].
-
-
-
-
-
- Returns the [AudioStreamPlayback] object associated with this [AudioStreamPlayer3D].
-
-
-
-
-
-
- Plays the audio from the given position [code]from_position[/code], in seconds.
-
-
-
-
-
-
- Sets the position from which audio will be played, in seconds.
-
-
-
-
-
- Stops the audio.
-
-
-
-
-
- Determines which [Area] layers affect the sound for reverb and audio bus effects. Areas can be used to redirect [AudioStream]s so that they play in a certain audio bus. An example of how you might use this is making a "water" area so that sounds played in the water are redirected through an audio bus to make them sound like they are being played underwater.
-
-
- Dampens audio using a low-pass filter above this frequency, in Hz. To disable the dampening effect entirely, set this to [code]20500[/code] as this frequency is above the human hearing limit.
-
-
- Amount how much the filter affects the loudness, in decibels.
-
-
- Decides if audio should get quieter with distance linearly, quadratically, logarithmically, or not be affected by distance, effectively disabling attenuation.
-
-
- If [code]true[/code], audio plays when the AudioStreamPlayer3D node is added to scene tree.
-
-
- The bus on which this audio is playing.
- [b]Note:[/b] When setting this property, keep in mind that no validation is performed to see if the given name matches an existing bus. This is because audio bus layouts might be loaded after this property is set. If this given name can't be resolved at runtime, it will fall back to [code]"Master"[/code].
-
-
- Decides in which step the [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] should be calculated.
- [b]Note:[/b] Only effective if the current [Camera]'s [member Camera.doppler_tracking] property is set to a value other than [constant Camera.DOPPLER_TRACKING_DISABLED].
-
-
- The angle in which the audio reaches cameras undampened.
-
-
- If [code]true[/code], the audio should be dampened according to the direction of the sound.
-
-
- Dampens audio if camera is outside of [member emission_angle_degrees] and [member emission_angle_enabled] is set by this factor, in decibels.
-
-
- Sets the absolute maximum of the soundlevel, in decibels.
-
-
- Sets the distance from which the [member out_of_range_mode] takes effect. Has no effect if set to 0.
-
-
- Decides if audio should pause when source is outside of [member max_distance] range.
-
-
- Scales the panning strength for this node by multiplying the base [member ProjectSettings.audio/3d_panning_strength] with this factor. Higher values will pan audio from left to right more dramatically than lower values.
-
-
- The pitch and the tempo of the audio, as a multiplier of the audio sample's sample rate.
-
-
- If [code]true[/code], audio is playing.
-
-
- The [AudioStream] resource to be played.
-
-
- If [code]true[/code], the playback is paused. You can resume it by setting [member stream_paused] to [code]false[/code].
-
-
- The base sound level unaffected by dampening, in decibels.
-
-
- The factor for the attenuation effect. Higher values make the sound audible over a larger distance.
-
-
-
-
-
- Emitted when the audio stops playing.
-
-
-
-
-
- Linear dampening of loudness according to distance.
-
-
- Squared dampening of loudness according to distance.
-
-
- Logarithmic dampening of loudness according to distance.
-
-
- No dampening of loudness according to distance. The sound will still be heard positionally, unlike an [AudioStreamPlayer]. [constant ATTENUATION_DISABLED] can be combined with a [member max_distance] value greater than [code]0.0[/code] to achieve linear attenuation clamped to a sphere of a defined size.
-
-
- Mix this audio in, even when it's out of range. This increases CPU usage, but keeps the sound playing at the correct position if the camera leaves and enters the [AudioStreamPlayer3D]'s [member max_distance] radius.
-
-
- Pause this audio when it gets out of range. This decreases CPU usage, but will cause the sound to restart if the camera leaves and enters the [AudioStreamPlayer3D]'s [member max_distance] radius.
-
-
- Disables doppler tracking.
-
-
- Executes doppler tracking in idle step (every rendered frame).
-
-
- Executes doppler tracking in physics step (every simulated physics frame).
-
-
-
diff --git a/doc/classes/BoxShape.xml b/doc/classes/BoxShape.xml
deleted file mode 100644
index cc0dda1..0000000
--- a/doc/classes/BoxShape.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
- Box shape resource.
-
-
- 3D box shape that can be a child of a [PhysicsBody] or [Area].
-
-
- https://godotengine.org/asset-library/asset/675
- https://godotengine.org/asset-library/asset/126
- https://godotengine.org/asset-library/asset/125
-
-
-
-
-
- The box's half extents. The width, height and depth of this shape is twice the half extents.
-
-
-
-
-
diff --git a/doc/classes/CPUParticles.xml b/doc/classes/CPUParticles.xml
deleted file mode 100644
index 9e19c47..0000000
--- a/doc/classes/CPUParticles.xml
+++ /dev/null
@@ -1,379 +0,0 @@
-
-
-
- CPU-based 3D particle emitter.
-
-
- CPU-based 3D particle node used to create a variety of particle systems and effects.
- See also [Particles], which provides the same functionality with hardware acceleration, but may not run on older devices.
- [b]Note:[/b] Unlike [Particles], the visibility rect is generated on-the-fly and doesn't need to be configured by the user.
-
-
-
-
-
-
-
-
- Returns the base value of the parameter specified by [enum Parameter].
-
-
-
-
-
-
- Returns the [Curve] of the parameter specified by [enum Parameter].
-
-
-
-
-
-
- Returns the randomness factor of the parameter specified by [enum Parameter].
-
-
-
-
-
-
- Returns the enabled state of the given flag (see [enum Flags] for options).
-
-
-
-
-
- Restarts the particle emitter.
-
-
-
-
-
-
-
- Sets the base value of the parameter specified by [enum Parameter].
-
-
-
-
-
-
-
- Sets the [Curve] of the parameter specified by [enum Parameter].
-
-
-
-
-
-
-
- Sets the randomness factor of the parameter specified by [enum Parameter].
-
-
-
-
-
-
-
- Enables or disables the given flag (see [enum Flags] for options).
-
-
-
-
-
- The number of particles emitted in one emission cycle (corresponding to the [member lifetime]).
- [b]Note:[/b] Changing [member amount] will reset the particle emission, therefore removing all particles that were already emitted before changing [member amount].
-
-
- Initial rotation applied to each particle, in degrees.
-
-
- Each particle's rotation will be animated along this [Curve].
-
-
- Rotation randomness ratio.
-
-
- Initial angular velocity applied to each particle in [i]degrees[/i] per second. Sets the speed of rotation of the particle.
-
-
- Each particle's angular velocity will vary along this [Curve].
-
-
- Angular velocity randomness ratio.
-
-
- Particle animation offset.
-
-
- Each particle's animation offset will vary along this [Curve].
-
-
- Animation offset randomness ratio.
-
-
- Particle animation speed.
-
-
- Each particle's animation speed will vary along this [Curve].
-
-
- Animation speed randomness ratio.
-
-
- Each particle's initial color.
- [b]Note:[/b] [member color] multiplies the particle mesh's vertex colors. To have a visible effect on a [SpatialMaterial], [member SpatialMaterial.vertex_color_use_as_albedo] [i]must[/i] be [code]true[/code]. For a [ShaderMaterial], [code]ALBEDO *= COLOR.rgb;[/code] must be inserted in the shader's [code]fragment()[/code] function. Otherwise, [member color] will have no visible effect.
-
-
- Each particle's initial color will vary along this [GradientTexture] (multiplied with [member color]).
- [b]Note:[/b] [member color_initial_ramp] multiplies the particle mesh's vertex colors. To have a visible effect on a [SpatialMaterial], [member SpatialMaterial.vertex_color_use_as_albedo] [i]must[/i] be [code]true[/code]. For a [ShaderMaterial], [code]ALBEDO *= COLOR.rgb;[/code] must be inserted in the shader's [code]fragment()[/code] function. Otherwise, [member color_initial_ramp] will have no visible effect.
-
-
- Each particle's color will vary along this [GradientTexture] over its lifetime (multiplied with [member color]).
- [b]Note:[/b] [member color_ramp] multiplies the particle mesh's vertex colors. To have a visible effect on a [SpatialMaterial], [member SpatialMaterial.vertex_color_use_as_albedo] [i]must[/i] be [code]true[/code]. For a [ShaderMaterial], [code]ALBEDO *= COLOR.rgb;[/code] must be inserted in the shader's [code]fragment()[/code] function. Otherwise, [member color_ramp] will have no visible effect.
-
-
- The rate at which particles lose velocity.
-
-
- Damping will vary along this [Curve].
-
-
- Damping randomness ratio.
-
-
- Unit vector specifying the particles' emission direction.
-
-
- Particle draw order. Uses [enum DrawOrder] values.
-
-
- The rectangle's extents if [member emission_shape] is set to [constant EMISSION_SHAPE_BOX].
-
-
- Sets the [Color]s to modulate particles by when using [constant EMISSION_SHAPE_POINTS] or [constant EMISSION_SHAPE_DIRECTED_POINTS].
- [b]Note:[/b] [member emission_colors] multiplies the particle mesh's vertex colors. To have a visible effect on a [SpatialMaterial], [member SpatialMaterial.vertex_color_use_as_albedo] [i]must[/i] be [code]true[/code]. For a [ShaderMaterial], [code]ALBEDO *= COLOR.rgb;[/code] must be inserted in the shader's [code]fragment()[/code] function. Otherwise, [member emission_colors] will have no visible effect.
-
-
- Sets the direction the particles will be emitted in when using [constant EMISSION_SHAPE_DIRECTED_POINTS].
-
-
- Sets the initial positions to spawn particles when using [constant EMISSION_SHAPE_POINTS] or [constant EMISSION_SHAPE_DIRECTED_POINTS].
-
-
- The axis for the ring shaped emitter when using [constant EMISSION_SHAPE_RING].
-
-
- The height for the ring shaped emitter when using [constant EMISSION_SHAPE_RING].
-
-
- The inner radius for the ring shaped emitter when using [constant EMISSION_SHAPE_RING].
-
-
- The radius for the ring shaped emitter when using [constant EMISSION_SHAPE_RING].
-
-
- Particles will be emitted inside this region. See [enum EmissionShape] for possible values.
-
-
- The sphere's radius if [enum EmissionShape] is set to [constant EMISSION_SHAPE_SPHERE].
-
-
- If [code]true[/code], particles are being emitted.
-
-
- How rapidly particles in an emission cycle are emitted. If greater than [code]0[/code], there will be a gap in emissions before the next cycle begins.
-
-
- The particle system's frame rate is fixed to a value. For instance, changing the value to 2 will make the particles render at 2 frames per second. Note this does not slow down the particle system itself.
-
-
- Align Y axis of particle with the direction of its velocity.
-
-
- If [code]true[/code], particles will not move on the z axis.
-
-
- If [code]true[/code], particles rotate around Y axis by [member angle].
-
-
- Amount of [member spread] in Y/Z plane. A value of [code]1[/code] restricts particles to X/Z plane.
-
-
- If [code]true[/code], results in fractional delta calculation which has a smoother particles display effect.
-
-
- Gravity applied to every particle.
-
-
- Initial hue variation applied to each particle.
-
-
- Each particle's hue will vary along this [Curve].
-
-
- Hue variation randomness ratio.
-
-
- Initial velocity magnitude for each particle. Direction comes from [member spread] and the node's orientation.
-
-
- Initial velocity randomness ratio.
-
-
- The amount of time each particle will exist (in seconds).
-
-
- Particle lifetime randomness ratio.
-
-
- Linear acceleration applied to each particle in the direction of motion.
-
-
- Each particle's linear acceleration will vary along this [Curve].
-
-
- Linear acceleration randomness ratio.
-
-
- If [code]true[/code], particles use the parent node's coordinate space. If [code]false[/code], they use global coordinates.
-
-
- The [Mesh] used for each particle. If [code]null[/code], particles will be spheres.
-
-
- If [code]true[/code], only one emission cycle occurs. If set [code]true[/code] during a cycle, emission will stop at the cycle's end.
-
-
- Orbital velocity applied to each particle. Makes the particles circle around origin in the local XY plane. Specified in number of full rotations around origin per second.
- This property is only available when [member flag_disable_z] is [code]true[/code].
-
-
- Each particle's orbital velocity will vary along this [Curve].
-
-
- Orbital velocity randomness ratio.
-
-
- Particle system starts as if it had already run for this many seconds.
-
-
- Radial acceleration applied to each particle. Makes particle accelerate away from origin.
-
-
- Each particle's radial acceleration will vary along this [Curve].
-
-
- Radial acceleration randomness ratio.
-
-
- Emission lifetime randomness ratio.
-
-
- Initial scale applied to each particle. This can be set to a negative value to flip the particle on all axes.
-
-
- Each particle's scale will vary along this [Curve].
-
-
- Scale randomness ratio.
-
-
- Particle system's running speed scaling ratio. A value of [code]0[/code] can be used to pause the particles.
-
-
- Each particle's initial direction range from [code]+spread[/code] to [code]-spread[/code] degrees. Applied to X/Z plane and Y/Z planes.
-
-
- Tangential acceleration applied to each particle. Tangential acceleration is perpendicular to the particle's velocity giving the particles a swirling motion.
-
-
- Each particle's tangential acceleration will vary along this [Curve].
-
-
- Tangential acceleration randomness ratio.
-
-
-
-
- Particles are drawn in the order emitted.
-
-
- Particles are drawn in order of remaining lifetime.
-
-
- Particles are drawn in order of depth.
-
-
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set initial velocity properties.
-
-
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set angular velocity properties.
-
-
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set orbital velocity properties.
-
-
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set linear acceleration properties.
-
-
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set radial acceleration properties.
-
-
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set tangential acceleration properties.
-
-
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set damping properties.
-
-
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set angle properties.
-
-
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set scale properties.
-
-
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set hue variation properties.
-
-
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set animation speed properties.
-
-
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set animation offset properties.
-
-
- Represents the size of the [enum Parameter] enum.
-
-
- Use with [method set_particle_flag] to set [member flag_align_y].
-
-
- Use with [method set_particle_flag] to set [member flag_rotate_y].
-
-
- Use with [method set_particle_flag] to set [member flag_disable_z].
-
-
- Represents the size of the [enum Flags] enum.
-
-
- All particles will be emitted from a single point.
-
-
- Particles will be emitted in the volume of a sphere.
-
-
- Particles will be emitted in the volume of a box.
-
-
- Particles will be emitted at a position chosen randomly among [member emission_points]. Particle color will be modulated by [member emission_colors].
-
-
- Particles will be emitted at a position chosen randomly among [member emission_points]. Particle velocity and rotation will be set based on [member emission_normals]. Particle color will be modulated by [member emission_colors].
-
-
- Particles will be emitted in a ring or cylinder.
-
-
- Represents the size of the [enum EmissionShape] enum.
-
-
-
diff --git a/doc/classes/Camera.xml b/doc/classes/Camera.xml
deleted file mode 100644
index 8172a14..0000000
--- a/doc/classes/Camera.xml
+++ /dev/null
@@ -1,213 +0,0 @@
-
-
-
- Camera node, displays from a point of view.
-
-
- Camera is a special node that displays what is visible from its current location. Cameras register themselves in the nearest [Viewport] node (when ascending the tree). Only one camera can be active per viewport. If no viewport is available ascending the tree, the camera will register in the global viewport. In other words, a camera just provides 3D display capabilities to a [Viewport], and, without one, a scene registered in that [Viewport] (or higher viewports) can't be displayed.
-
-
- https://godotengine.org/asset-library/asset/678
-
-
-
-
-
-
- If this is the current camera, remove it from being current. If [code]enable_next[/code] is [code]true[/code], request to make the next camera current, if any.
-
-
-
-
-
- Returns the camera's RID from the [RenderingServer].
-
-
-
-
-
- Returns the transform of the camera plus the vertical ([member v_offset]) and horizontal ([member h_offset]) offsets; and any other adjustments made to the position and orientation of the camera by subclassed cameras such as [ClippedCamera], [InterpolatedCamera] and [ARVRCamera].
-
-
-
-
-
-
- Returns [code]true[/code] if the given [code]layer[/code] in the [member cull_mask] is enabled, [code]false[/code] otherwise.
-
-
-
-
-
- Returns the camera's frustum planes in world space units as an array of [Plane]s in the following order: near, far, left, top, right, bottom. Not to be confused with [member frustum_offset].
-
-
-
-
-
-
- Returns [code]true[/code] if the given position is behind the camera.
- [b]Note:[/b] A position which returns [code]false[/code] may still be outside the camera's field of view.
-
-
-
-
-
- Makes this camera the current camera for the [Viewport] (see class description). If the camera node is outside the scene tree, it will attempt to become current once it's added.
-
-
-
-
-
-
- Returns a normal vector from the screen point location directed along the camera. Orthogonal cameras are normalized. Perspective cameras account for perspective, screen width/height, etc.
-
-
-
-
-
-
-
- Returns the 3D point in world space that maps to the given 2D coordinate in the [Viewport] rectangle on a plane that is the given [code]z_depth[/code] distance into the scene away from the camera.
-
-
-
-
-
-
- Returns a normal vector in world space, that is the result of projecting a point on the [Viewport] rectangle by the inverse camera projection. This is useful for casting rays in the form of (origin, normal) for object intersection or picking.
-
-
-
-
-
-
- Returns a 3D position in world space, that is the result of projecting a point on the [Viewport] rectangle by the inverse camera projection. This is useful for casting rays in the form of (origin, normal) for object intersection or picking.
-
-
-
-
-
-
-
- Enables or disables the given [code]layer[/code] in the [member cull_mask].
-
-
-
-
-
-
-
-
-
- Sets the camera projection to frustum mode (see [constant PROJECTION_FRUSTUM]), by specifying a [code]size[/code], an [code]offset[/code], and the [code]z_near[/code] and [code]z_far[/code] clip planes in world space units.
-
-
-
-
-
-
-
-
- Sets the camera projection to orthogonal mode (see [constant PROJECTION_ORTHOGONAL]), by specifying a [code]size[/code], and the [code]z_near[/code] and [code]z_far[/code] clip planes in world space units. (As a hint, 2D games often use this projection, with values specified in pixels.)
-
-
-
-
-
-
-
-
- Sets the camera projection to perspective mode (see [constant PROJECTION_PERSPECTIVE]), by specifying a [code]fov[/code] (field of view) angle in degrees, and the [code]z_near[/code] and [code]z_far[/code] clip planes in world space units.
-
-
-
-
-
-
- Returns the 2D coordinate in the [Viewport] rectangle that maps to the given 3D point in world space.
- [b]Note:[/b] When using this to position GUI elements over a 3D viewport, use [method is_position_behind] to prevent them from appearing if the 3D point is behind the camera:
- [codeblock]
- # This code block is part of a script that inherits from Spatial.
- # `control` is a reference to a node inheriting from Control.
- control.visible = not get_viewport().get_camera().is_position_behind(global_transform.origin)
- control.rect_position = get_viewport().get_camera().unproject_position(global_transform.origin)
- [/codeblock]
-
-
-
-
-
- The culling mask that describes which 3D render layers are rendered by this camera.
-
-
- If [code]true[/code], the ancestor [Viewport] is currently using this camera.
- If multiple cameras are in the scene, one will always be made current. For example, if two [Camera] nodes are present in the scene and only one is current, setting one camera's [member current] to [code]false[/code] will cause the other camera to be made current.
-
-
- If not [constant DOPPLER_TRACKING_DISABLED], this camera will simulate the [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] for objects changed in particular [code]_process[/code] methods. The Doppler effect is only simulated for [AudioStreamPlayer3D] nodes that have [member AudioStreamPlayer3D.doppler_tracking] set to a value other than [constant AudioStreamPlayer3D.DOPPLER_TRACKING_DISABLED].
- [b]Note:[/b] To toggle the Doppler effect preview in the editor, use the Perspective menu in the top-left corner of the 3D viewport and toggle [b]Enable Doppler[/b].
-
-
- The [Environment3D] to use for this camera.
-
-
- The distance to the far culling boundary for this camera relative to its local Z axis.
-
-
- The camera's field of view angle (in degrees). Only applicable in perspective mode. Since [member keep_aspect] locks one axis, [code]fov[/code] sets the other axis' field of view angle.
- For reference, the default vertical field of view value ([code]70.0[/code]) is equivalent to a horizontal FOV of:
- - ~86.07 degrees in a 4:3 viewport
- - ~96.50 degrees in a 16:10 viewport
- - ~102.45 degrees in a 16:9 viewport
- - ~117.06 degrees in a 21:9 viewport
-
-
- The camera's frustum offset. This can be changed from the default to create "tilted frustum" effects such as [url=https://zdoom.org/wiki/Y-shearing]Y-shearing[/url].
-
-
- The horizontal (X) offset of the camera viewport.
-
-
- The axis to lock during [member fov]/[member size] adjustments. Can be either [constant KEEP_WIDTH] or [constant KEEP_HEIGHT].
-
-
- The distance to the near culling boundary for this camera relative to its local Z axis.
-
-
- The camera's projection mode. In [constant PROJECTION_PERSPECTIVE] mode, objects' Z distance from the camera's local space scales their perceived size.
-
-
- The camera's size in meters measured as the diameter of the width or height, depending on [member keep_aspect]. Only applicable in orthogonal and frustum modes.
-
-
- The vertical (Y) offset of the camera viewport.
-
-
-
-
- Perspective projection. Objects on the screen becomes smaller when they are far away.
-
-
- Orthogonal projection, also known as orthographic projection. Objects remain the same size on the screen no matter how far away they are.
-
-
- Frustum projection. This mode allows adjusting [member frustum_offset] to create "tilted frustum" effects.
-
-
- Preserves the horizontal aspect ratio; also known as Vert- scaling. This is usually the best option for projects running in portrait mode, as taller aspect ratios will benefit from a wider vertical FOV.
-
-
- Preserves the vertical aspect ratio; also known as Hor+ scaling. This is usually the best option for projects running in landscape mode, as wider aspect ratios will automatically benefit from a wider horizontal FOV.
-
-
- Disables [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] simulation (default).
-
-
- Simulate [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] by tracking positions of objects that are changed in [code]_process[/code]. Changes in the relative velocity of this camera compared to those objects affect how audio is perceived (changing the audio's [member AudioStreamPlayer3D.pitch_scale]).
-
-
- Simulate [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] by tracking positions of objects that are changed in [code]_physics_process[/code]. Changes in the relative velocity of this camera compared to those objects affect how audio is perceived (changing the audio's [member AudioStreamPlayer3D.pitch_scale]).
-
-
-
diff --git a/doc/classes/EditorExportPlugin.xml b/doc/classes/EditorExportPlugin.xml
deleted file mode 100644
index 36b2415..0000000
--- a/doc/classes/EditorExportPlugin.xml
+++ /dev/null
@@ -1,126 +0,0 @@
-
-
-
- A script that is executed when exporting the project.
-
-
- [EditorExportPlugin]s are automatically invoked whenever the user exports the project. Their most common use is to determine what files are being included in the exported project. For each plugin, [method _export_begin] is called at the beginning of the export process and then [method _export_file] is called for each exported file.
- To use [EditorExportPlugin], register it using the [method EditorPlugin.add_export_plugin] method first.
-
-
-
-
-
-
-
-
-
-
-
- Virtual method to be overridden by the user. It is called when the export starts and provides all information about the export. [code]features[/code] is the list of features for the export, [code]is_debug[/code] is [code]true[/code] for debug builds, [code]path[/code] is the target path for the exported project. [code]flags[/code] is only used when running a runnable profile, e.g. when using native run on Android.
-
-
-
-
-
- Virtual method to be overridden by the user. Called when the export is finished.
-
-
-
-
-
-
-
-
- Virtual method to be overridden by the user. Called for each exported file, providing arguments that can be used to identify the file. [code]path[/code] is the path of the file, [code]type[/code] is the [Resource] represented by the file (e.g. [PackedScene]) and [code]features[/code] is the list of features for the export.
- Calling [method skip] inside this callback will make the file not included in the export.
-
-
-
-
-
-
-
-
- Adds a custom file to be exported. [code]path[/code] is the virtual path that can be used to load the file, [code]file[/code] is the binary data of the file. If [code]remap[/code] is [code]true[/code], file will not be exported, but instead remapped to the given [code]path[/code].
-
-
-
-
-
-
- Adds an iOS bundle file from the given [code]path[/code] to the exported project.
-
-
-
-
-
-
- Adds a C++ code to the iOS export. The final code is created from the code appended by each active export plugin.
-
-
-
-
-
-
- Adds a dynamic library (*.dylib, *.framework) to Linking Phase in iOS's Xcode project and embeds it into resulting binary.
- [b]Note:[/b] For static libraries (*.a) works in same way as [method add_ios_framework].
- This method should not be used for System libraries as they are already present on the device.
-
-
-
-
-
-
- Adds a static library (*.a) or dynamic library (*.dylib, *.framework) to Linking Phase in iOS's Xcode project.
-
-
-
-
-
-
- Adds linker flags for the iOS export.
-
-
-
-
-
-
- Adds content for iOS Property List files.
-
-
-
-
-
-
- Adds a static lib from the given [code]path[/code] to the iOS project.
-
-
-
-
-
-
- Adds file or directory matching [code]path[/code] to [code]PlugIns[/code] directory of macOS app bundle.
- [b]Note:[/b] This is useful only for macOS exports.
-
-
-
-
-
-
-
- Adds a shared object or a directory containing only shared objects with the given [code]tags[/code] and destination [code]path[/code].
- [b]Note:[/b] In case of macOS exports, those shared objects will be added to [code]Frameworks[/code] directory of app bundle.
- In case of a directory code-sign will error if you place non code object in directory.
-
-
-
-
-
- To be called inside [method _export_file]. Skips the current file, so it's not included in the export.
-
-
-
-
-
-
diff --git a/doc/classes/EditorFileDialog.xml b/doc/classes/EditorFileDialog.xml
deleted file mode 100644
index c1e8a90..0000000
--- a/doc/classes/EditorFileDialog.xml
+++ /dev/null
@@ -1,120 +0,0 @@
-
-
-
- A modified version of [FileDialog] used by the editor.
-
-
-
-
-
-
-
-
-
-
- Adds a comma-delimited file extension filter option to the [EditorFileDialog] with an optional semi-colon-delimited label.
- For example, [code]"*.tscn, *.scn; Scenes"[/code] results in filter text "Scenes (*.tscn, *.scn)".
-
-
-
-
-
- Removes all filters except for "All Files (*)".
-
-
-
-
-
- Returns the [code]VBoxContainer[/code] used to display the file system.
- [b]Warning:[/b] This is a required internal node, removing and freeing it may cause a crash. If you wish to hide it or any of its children, use their [member CanvasItem.visible] property.
-
-
-
-
-
- Notify the [EditorFileDialog] that its view of the data is no longer accurate. Updates the view contents on next view update.
-
-
-
-
-
- The location from which the user may select a file, including [code]res://[/code], [code]user://[/code], and the local file system.
-
-
- The currently occupied directory.
-
-
- The currently selected file.
-
-
- The file system path in the address bar.
-
-
-
- If [code]true[/code], the [EditorFileDialog] will not warn the user before overwriting files.
-
-
- The view format in which the [EditorFileDialog] displays resources to the user.
-
-
- The purpose of the [EditorFileDialog], which defines the allowed behaviors.
-
-
-
- If [code]true[/code], hidden files and directories will be visible in the [EditorFileDialog].
-
-
-
-
-
-
-
- Emitted when a directory is selected.
-
-
-
-
-
- Emitted when a file is selected.
-
-
-
-
-
- Emitted when multiple files are selected.
-
-
-
-
-
- The [EditorFileDialog] can select only one file. Accepting the window will open the file.
-
-
- The [EditorFileDialog] can select multiple files. Accepting the window will open all files.
-
-
- The [EditorFileDialog] can select only one directory. Accepting the window will open the directory.
-
-
- The [EditorFileDialog] can select a file or directory. Accepting the window will open it.
-
-
- The [EditorFileDialog] can select only one file. Accepting the window will save the file.
-
-
- The [EditorFileDialog] can only view [code]res://[/code] directory contents.
-
-
- The [EditorFileDialog] can only view [code]user://[/code] directory contents.
-
-
- The [EditorFileDialog] can view the entire local file system.
-
-
- The [EditorFileDialog] displays resources as thumbnails.
-
-
- The [EditorFileDialog] displays resources as a list of filenames.
-
-
-
diff --git a/doc/classes/EditorFileSystem.xml b/doc/classes/EditorFileSystem.xml
deleted file mode 100644
index f8ee606..0000000
--- a/doc/classes/EditorFileSystem.xml
+++ /dev/null
@@ -1,98 +0,0 @@
-
-
-
- Resource filesystem, as the editor sees it.
-
-
- This object holds information of all resources in the filesystem, their types, etc.
- [b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_resource_filesystem].
-
-
-
-
-
-
-
-
- Returns the resource type of the file, given the full path. This returns a string such as [code]"Resource"[/code] or [code]"GDScript"[/code], [i]not[/i] a file extension such as [code]".gd"[/code].
-
-
-
-
-
- Gets the root directory object.
-
-
-
-
-
-
- Returns a view into the filesystem at [code]path[/code].
-
-
-
-
-
- Returns the scan progress for 0 to 1 if the FS is being scanned.
-
-
-
-
-
- Returns [code]true[/code] of the filesystem is being scanned.
-
-
-
-
-
- Scan the filesystem for changes.
-
-
-
-
-
- Check if the source of any imported resource changed.
-
-
-
-
-
-
- Update a file information. Call this if an external program (not Godot) modified the file.
-
-
-
-
-
- Scans the script files and updates the list of custom class names.
-
-
-
-
-
-
- Emitted if the filesystem changed.
-
-
-
-
-
- Emitted if a resource is reimported.
-
-
-
-
-
- Emitted if at least one resource is reloaded when the filesystem is scanned.
-
-
-
-
-
- Emitted if the source of any imported file changed.
-
-
-
-
-
-
diff --git a/doc/classes/EditorFileSystemDirectory.xml b/doc/classes/EditorFileSystemDirectory.xml
deleted file mode 100644
index 8ce0369..0000000
--- a/doc/classes/EditorFileSystemDirectory.xml
+++ /dev/null
@@ -1,108 +0,0 @@
-
-
-
- A directory for the resource filesystem.
-
-
- A more generalized, low-level variation of the directory concept.
-
-
-
-
-
-
-
-
- Returns the index of the directory with name [code]name[/code] or [code]-1[/code] if not found.
-
-
-
-
-
-
- Returns the index of the file with name [code]name[/code] or [code]-1[/code] if not found.
-
-
-
-
-
-
- Returns the name of the file at index [code]idx[/code].
-
-
-
-
-
- Returns the number of files in this directory.
-
-
-
-
-
-
- Returns [code]true[/code] if the file at index [code]idx[/code] imported properly.
-
-
-
-
-
-
- Returns the path to the file at index [code]idx[/code].
-
-
-
-
-
-
- Returns the base class of the script class defined in the file at index [code]idx[/code]. If the file doesn't define a script class using the [code]class_name[/code] syntax, this will return an empty string.
-
-
-
-
-
-
- Returns the name of the script class defined in the file at index [code]idx[/code]. If the file doesn't define a script class using the [code]class_name[/code] syntax, this will return an empty string.
-
-
-
-
-
-
- Returns the resource type of the file at index [code]idx[/code]. This returns a string such as [code]"Resource"[/code] or [code]"GDScript"[/code], [i]not[/i] a file extension such as [code]".gd"[/code].
-
-
-
-
-
- Returns the name of this directory.
-
-
-
-
-
- Returns the parent directory for this directory or [code]null[/code] if called on a directory at [code]res://[/code] or [code]user://[/code].
-
-
-
-
-
- Returns the path to this directory.
-
-
-
-
-
-
- Returns the subdirectory at index [code]idx[/code].
-
-
-
-
-
- Returns the number of subdirectories in this directory.
-
-
-
-
-
-
diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml
deleted file mode 100644
index d9dba12..0000000
--- a/doc/classes/EditorImportPlugin.xml
+++ /dev/null
@@ -1,149 +0,0 @@
-
-
-
- Registers a custom resource importer in the editor. Use the class to parse any file and import it as a new resource type.
-
-
- [EditorImportPlugin]s provide a way to extend the editor's resource import functionality. Use them to import resources from custom files or to provide alternatives to the editor's existing importers.
- EditorImportPlugins work by associating with specific file extensions and a resource type. See [method get_recognized_extensions] and [method get_resource_type]. They may optionally specify some import presets that affect the import process. EditorImportPlugins are responsible for creating the resources and saving them in the [code].import[/code] directory (see [member ProjectSettings.application/config/use_hidden_project_data_directory]).
- Below is an example EditorImportPlugin that imports a [Mesh] from a file with the extension ".special" or ".spec":
- [codeblock]
- tool
- extends EditorImportPlugin
-
- func get_importer_name():
- return "my.special.plugin"
-
- func get_visible_name():
- return "Special Mesh"
-
- func get_recognized_extensions():
- return ["special", "spec"]
-
- func get_save_extension():
- return "mesh"
-
- func get_resource_type():
- return "Mesh"
-
- func get_preset_count():
- return 1
-
- func get_preset_name(i):
- return "Default"
-
- func get_import_options(i):
- return [{"name": "my_option", "default_value": false}]
-
- func import(source_file, save_path, options, platform_variants, gen_files):
- var file = File.new()
- if file.open(source_file, File.READ) != OK:
- return FAILED
-
- var mesh = Mesh.new()
- # Fill the Mesh with data read in "file", left as an exercise to the reader
-
- var filename = save_path + "." + get_save_extension()
- return ResourceSaver.save(filename, mesh)
- [/codeblock]
- To use [EditorImportPlugin], register it using the [method EditorPlugin.add_import_plugin] method first.
-
-
- $DOCS_URL/tutorials/plugins/editor/import_plugins.md
-
-
-
-
-
-
- Gets the options and default values for the preset at this index. Returns an Array of Dictionaries with the following keys: [code]name[/code], [code]default_value[/code], [code]property_hint[/code] (optional), [code]hint_string[/code] (optional), [code]usage[/code] (optional).
-
-
-
-
-
- Gets the order of this importer to be run when importing resources. Importers with [i]lower[/i] import orders will be called first, and higher values will be called later. Use this to ensure the importer runs after the dependencies are already imported. The default import order is [code]0[/code] unless overridden by a specific importer. See [enum ResourceImporter.ImportOrder] for some predefined values.
-
-
-
-
-
- Gets the unique name of the importer.
-
-
-
-
-
-
-
- This method can be overridden to hide specific import options if conditions are met. This is mainly useful for hiding options that depend on others if one of them is disabled. For example:
- [codeblock]
- func get_option_visibility(option, options):
- # Only show the lossy quality setting if the compression mode is set to "Lossy".
- if option == "compress/lossy_quality" and options.has("compress/mode"):
- return int(options["compress/mode"]) == COMPRESS_LOSSY
-
- return true
- [/codeblock]
- Return [code]true[/code] to make all options always visible.
-
-
-
-
-
- Gets the number of initial presets defined by the plugin. Use [method get_import_options] to get the default options for the preset and [method get_preset_name] to get the name of the preset.
-
-
-
-
-
-
- Gets the name of the options preset at this index.
-
-
-
-
-
- Gets the priority of this plugin for the recognized extension. Higher priority plugins will be preferred. The default priority is [code]1.0[/code].
-
-
-
-
-
- Gets the list of file extensions to associate with this loader (case-insensitive). e.g. [code]["obj"][/code].
-
-
-
-
-
- Gets the Godot resource type associated with this loader. e.g. [code]"Mesh"[/code] or [code]"Animation"[/code].
-
-
-
-
-
- Gets the extension used to save this resource in the [code].import[/code] directory (see [member ProjectSettings.application/config/use_hidden_project_data_directory]).
-
-
-
-
-
- Gets the name to display in the import window. You should choose this name as a continuation to "Import as", e.g. "Import as Special Mesh".
-
-
-
-
-
-
-
-
-
-
- Imports [code]source_file[/code] into [code]save_path[/code] with the import [code]options[/code] specified. The [code]platform_variants[/code] and [code]gen_files[/code] arrays will be modified by this function.
- This method must be overridden to do the actual importing work. See this class' description for an example of overriding this method.
-
-
-
-
-
-
diff --git a/doc/classes/EditorInspector.xml b/doc/classes/EditorInspector.xml
deleted file mode 100644
index 843e289..0000000
--- a/doc/classes/EditorInspector.xml
+++ /dev/null
@@ -1,192 +0,0 @@
-
-
-
- A control used to edit properties of an object.
-
-
- This is the control that implements property editing in the editor's Settings dialogs, the Inspector dock, etc. To get the [EditorInspector] used in the editor's Inspector dock, use [method EditorInterface.get_inspector].
- [EditorInspector] will show properties in the same order as the array returned by [method Object.get_property_list].
- If a property's name is path-like (i.e. if it contains forward slashes), [EditorInspector] will create nested sections for "directories" along the path. For example, if a property is named [code]highlighting/gdscript/node_path_color[/code], it will be shown as "Node Path Color" inside the "GDScript" section nested inside the "Highlighting" section.
- If a property has [constant @GlobalScope.PROPERTY_USAGE_GROUP] usage, it will group subsequent properties whose name starts with the property's hint string. The group ends when a property does not start with that hint string or when a new group starts. An empty group name effectively ends the current group. [EditorInspector] will create a top-level section for each group. For example, if a property with group usage is named [code]Collide With[/code] and its hint string is [code]collide_with_[/code], a subsequent [code]collide_with_area[/code] property will be shown as "Area" inside the "Collide With" section.
- [b]Note:[/b] Unlike sections created from path-like property names, [EditorInspector] won't capitalize the name for sections created from groups. So properties with group usage usually use capitalized names instead of snake_cased names.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Refreshes the inspector.
- [b]Note:[/b] To save on CPU resources, calling this method will do nothing if the time specified in [code]docks/property_editor/auto_refresh_interval[/code] editor setting hasn't passed yet since this method was last called. (By default, this interval is set to 0.3 seconds.)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Emitted when the Edit button of an [Object] has been pressed in the inspector. This is mainly used in the remote scene tree inspector.
-
-
-
-
-
- Emitted when a property is edited in the inspector.
-
-
-
-
-
- Emitted when a property is keyed in the inspector. Properties can be keyed by clicking the "key" icon next to a property when the Animation panel is toggled.
-
-
-
-
-
- Emitted when a property is selected in the inspector.
-
-
-
-
-
-
- Emitted when a boolean property is toggled in the inspector.
- [b]Note:[/b] This signal is never emitted if the internal [code]autoclear[/code] property enabled. Since this property is always enabled in the editor inspector, this signal is never emitted by the editor itself.
-
-
-
-
-
-
- Emitted when a resource is selected in the inspector.
-
-
-
-
- Emitted when a property that requires a restart to be applied is edited in the inspector. This is only used in the Project Settings and Editor Settings.
-
-
-
-
-
-
diff --git a/doc/classes/EditorInspectorPlugin.xml b/doc/classes/EditorInspectorPlugin.xml
deleted file mode 100644
index 23f77ef..0000000
--- a/doc/classes/EditorInspectorPlugin.xml
+++ /dev/null
@@ -1,86 +0,0 @@
-
-
-
- Plugin for adding custom property editors on inspector.
-
-
- [EditorInspectorPlugin] allows adding custom property editors to [EditorInspector].
- When an object is edited, the [method can_handle] function is called and must return [code]true[/code] if the object type is supported.
- If supported, the function [method parse_begin] will be called, allowing to place custom controls at the beginning of the class.
- Subsequently, the [method parse_category] and [method parse_property] are called for every category and property. They offer the ability to add custom controls to the inspector too.
- Finally, [method parse_end] will be called.
- On each of these calls, the "add" functions can be called.
- To use [EditorInspectorPlugin], register it using the [method EditorPlugin.add_inspector_plugin] method first.
-
-
- $DOCS_URL/tutorials/plugins/editor/inspector_plugins.md
-
-
-
-
-
-
- Adds a custom control, which is not necessarily a property editor.
-
-
-
-
-
-
-
- Adds a property editor for an individual property. The [code]editor[/code] control must extend [EditorProperty].
-
-
-
-
-
-
-
-
- Adds an editor that allows modifying multiple properties. The [code]editor[/code] control must extend [EditorProperty].
-
-
-
-
-
-
- Returns [code]true[/code] if this object can be handled by this plugin.
-
-
-
-
-
-
- Called to allow adding controls at the beginning of the list.
-
-
-
-
-
-
-
- Called to allow adding controls at the beginning of the category.
-
-
-
-
-
- Called to allow adding controls at the end of the list.
-
-
-
-
-
-
-
-
-
-
-
- Called to allow adding property specific editors to the inspector. Usually these inherit [EditorProperty]. Returning [code]true[/code] removes the built-in editor for this property, otherwise allows to insert a custom editor before the built-in one.
-
-
-
-
-
-
diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml
deleted file mode 100644
index 6a9adf7..0000000
--- a/doc/classes/EditorInterface.xml
+++ /dev/null
@@ -1,273 +0,0 @@
-
-
-
- Godot editor's interface.
-
-
- EditorInterface gives you control over Godot editor's window. It allows customizing the window, saving and (re-)loading scenes, rendering mesh previews, inspecting and editing resources and objects, and provides access to [EditorSettings], [EditorFileSystem], [EditorResourcePreview], [EditorScriptEditor], the editor viewport, and information about scenes.
- [b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorPlugin.get_editor_interface].
-
-
-
-
-
-
-
-
- Edits the given [Node]. The node will be also selected if it's inside the scene tree.
-
-
-
-
-
-
- Edits the given [Resource]. If the resource is a [Script] you can also edit it with [method edit_script] to specify the line and column position.
-
-
-
-
-
-
-
-
-
- Edits the given [Script]. The line and column on which to open the script can also be specified. The script will be open with the user-configured editor for the script's language which may be an external editor.
-
-
-
-
-
- Returns the main container of Godot editor's window. For example, you can use it to retrieve the size of the container and place your controls accordingly.
- [b]Warning:[/b] Removing and freeing this node will render the editor useless and may cause a crash.
-
-
-
-
-
-
-
- Returns the editor icon bound to a class name or the [code]fallback[/code] class's icon if not found. The [code]fallback[/code] defaults to "Object". If still not found, returns [code]null[/code].
- [b]Node:[/b] This includes icons from custom types (see [method EditorPlugin.add_custom_type]) and global script classes from [ScriptServer].
-
-
-
-
-
- Returns the current path being viewed in the [FileSystemDock].
-
-
-
-
-
- Returns the edited (current) scene's root [Node].
-
-
-
-
-
- Returns the actual scale of the editor UI ([code]1.0[/code] being 100% scale). This can be used to adjust position and dimensions of the UI added by plugins.
- [b]Note:[/b] This value is set via the [code]interface/editor/display_scale[/code] and [code]interface/editor/custom_display_scale[/code] editor settings. Editor must be restarted for changes to be properly applied.
-
-
-
-
-
- Returns the editor's [EditorSettings] instance.
-
-
-
-
-
- Returns the main editor control. Use this as a parent for main screens.
- [b]Note:[/b] This returns the main editor control containing the whole editor, not the 2D or 3D viewports specifically.
- [b]Warning:[/b] Removing and freeing this node will render a part of the editor useless and may cause a crash.
-
-
-
-
-
- Returns the editor's [FileSystemDock] instance.
- [b]Warning:[/b] Removing and freeing this node will render a part of the editor useless and may cause a crash.
-
-
-
-
-
- Returns the editor's [EditorInspector] instance.
- [b]Warning:[/b] Removing and freeing this node will render a part of the editor useless and may cause a crash.
-
-
-
-
-
-
-
- Returns the editor icon bound to [Object] [code]object[/code] or the class [code]fallback[/code] if a type cannot be determined. If [code]object[/code] extends [Script], then return the editor icon bound to the scripted class, not the actual script. If still not found, return [code]null[/code].
- [b]Note:[/b] if you need the editor icon for a script such as [GDScript], use [method get_class_icon].
-
-
-
-
-
- Returns an [Array] with the file paths of the currently opened scenes.
-
-
-
-
-
- Returns the name of the scene that is being played. If no scene is currently being played, returns an empty string.
-
-
-
-
-
- Returns the editor's [EditorFileSystem] instance.
-
-
-
-
-
- Returns the editor's [EditorResourcePreview] instance.
-
-
-
-
-
- Returns the editor's [EditorScriptEditor] instance.
- [b]Warning:[/b] Removing and freeing this node will render a part of the editor useless and may cause a crash.
-
-
-
-
-
- Returns the path of the directory currently selected in the [FileSystemDock]. If a file is selected, its base directory will be returned using [method String.get_base_dir] instead.
-
-
-
-
-
- Returns the editor's [EditorSelection] instance.
-
-
-
-
-
-
-
-
- Shows the given property on the given [code]object[/code] in the editor's Inspector dock. If [code]inspector_only[/code] is [code]true[/code], plugins will not attempt to edit [code]object[/code].
-
-
-
-
-
- Returns [code]true[/code] if a scene is currently being played, [code]false[/code] otherwise. Paused scenes are considered as being played.
-
-
-
-
-
-
- Returns [code]true[/code] if the specified [code]plugin[/code] is enabled. The plugin name is the same as its directory name.
-
-
-
-
-
-
-
- Returns mesh previews rendered at the given size as an [Array] of [Texture]s.
-
-
-
-
-
-
- Opens the scene at the given path.
-
-
-
-
-
- Plays the currently active scene.
-
-
-
-
-
-
- Plays the scene specified by its filepath.
-
-
-
-
-
- Plays the main scene.
-
-
-
-
-
-
- Reloads the scene at the given path.
-
-
-
-
-
- Saves the scene. Returns either [code]OK[/code] or [code]ERR_CANT_CREATE[/code] (see [@GlobalScope] constants).
-
-
-
-
-
-
-
- Saves the scene as a file at [code]path[/code].
-
-
-
-
-
-
- Selects the file, with the path provided by [code]file[/code], in the FileSystem dock.
-
-
-
-
-
-
- Sets the editor's current main screen to the one specified in [code]name[/code]. It will also make the editor's tab button at the top to be visible if it weren't. [code]name[/code] must match the text of the tab in question exactly like: [code]2D[/code], [code]3D[/code], [code]Script[/code].
-
-
-
-
-
-
-
- Sets whether the specified main screen's button is visible or not. Will not change the main screen. [code]name[/code] must match the text of the tab in question exactly like: [code]2D[/code], [code]3D[/code], [code]Script[/code], [code]AssetLib[/code].
-
-
-
-
-
-
-
- Sets the enabled status of a plugin. The plugin name is the same as its directory name.
-
-
-
-
-
- Stops the scene that is currently playing.
-
-
-
-
-
- If [code]true[/code], enables distraction-free mode which hides side docks to increase the space available for the main view.
-
-
-
-
-
diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml
deleted file mode 100644
index 6fbba71..0000000
--- a/doc/classes/EditorPlugin.xml
+++ /dev/null
@@ -1,608 +0,0 @@
-
-
-
- Used by the editor to extend its functionality.
-
-
- Plugins are used by the editor to extend functionality. The most common types of plugins are those which edit a given node or resource type, import plugins and export plugins. See also [EditorScript] to add functions to the editor.
-
-
- $DOCS_URL/tutorials/plugins/editor/index.md
-
-
-
-
-
-
-
- Adds a script at [code]path[/code] to the Autoload list as [code]name[/code].
-
-
-
-
-
-
-
- Adds a control to the bottom panel (together with Output, Debug, Animation, etc). Returns a reference to the button added. It's up to you to hide/show the button when needed. When your plugin is deactivated, make sure to remove your custom control with [method remove_control_from_bottom_panel] and free it with [method Node.queue_free].
-
-
-
-
-
-
-
- Adds a custom control to a container (see [enum CustomControlContainer]). There are many locations where custom controls can be added in the editor UI.
- Please remember that you have to manage the visibility of your custom controls yourself (and likely hide it after adding it).
- When your plugin is deactivated, make sure to remove your custom control with [method remove_control_from_container] and free it with [method Node.queue_free].
-
-
-
-
-
-
-
- Adds the control to a specific dock slot (see [enum DockSlot] for options).
- If the dock is repositioned and as long as the plugin is active, the editor will save the dock position on further sessions.
- When your plugin is deactivated, make sure to remove your custom control with [method remove_control_from_docks] and free it with [method Node.queue_free].
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Adds a custom type, which will appear in the list of nodes or resources. An icon can be optionally passed.
- When given node or resource is selected, the base type will be instanced (ie, "Spatial", "Control", "Resource"), then the script will be loaded and set to this object.
- You can use the virtual method [method handles] to check if your custom object is being edited by checking the script or using the [code]is[/code] keyword.
- During run-time, this will be a simple object with a script so this function does not need to be called then.
-
-
-
-
-
-
- Registers a new [EditorExportPlugin]. Export plugins are used to perform tasks when the project is being exported.
- See [method add_inspector_plugin] for an example of how to register a plugin.
-
-
-
-
-
-
- Registers a new [EditorImportPlugin]. Import plugins are used to import custom and unsupported assets as a custom [Resource] type.
- [b]Note:[/b] If you want to import custom 3D asset formats use [method add_scene_import_plugin] instead.
- See [method add_inspector_plugin] for an example of how to register a plugin.
-
-
-
-
-
-
- Registers a new [EditorInspectorPlugin]. Inspector plugins are used to extend [EditorInspector] and provide custom configuration tools for your object's properties.
- [b]Note:[/b] Always use [method remove_inspector_plugin] to remove the registered [EditorInspectorPlugin] when your [EditorPlugin] is disabled to prevent leaks and an unexpected behavior.
- [codeblock]
- const MyInspectorPlugin = preload("res://addons/your_addon/path/to/your/script.gd")
- var inspector_plugin = MyInspectorPlugin.new()
-
- func _enter_tree():
- add_inspector_plugin(inspector_plugin)
-
- func _exit_tree():
- remove_inspector_plugin(inspector_plugin)
- [/codeblock]
-
-
-
-
-
-
- Registers a new [EditorSceneImporter]. Scene importers are used to import custom 3D asset formats as scenes.
-
-
-
-
-
-
- Registers a new [EditorSpatialGizmoPlugin]. Gizmo plugins are used to add custom gizmos to the 3D preview viewport for a [Spatial].
- See [method add_inspector_plugin] for an example of how to register a plugin.
-
-
-
-
-
-
-
-
-
- Adds a custom menu item to [b]Project > Tools[/b] as [code]name[/code] that calls [code]callback[/code] on an instance of [code]handler[/code] with a parameter [code]ud[/code] when user activates it.
-
-
-
-
-
-
-
- Adds a custom submenu under [b]Project > Tools >[/b] [code]name[/code]. [code]submenu[/code] should be an object of class [PopupMenu]. This submenu should be cleaned up using [code]remove_tool_menu_item(name)[/code].
-
-
-
-
-
- This method is called when the editor is about to save the project, switch to another tab, etc. It asks the plugin to apply any pending state changes to ensure consistency.
- This is used, for example, in shader editors to let the plugin know that it must apply the shader code being written by the user to the object.
-
-
-
-
-
- This method is called when the editor is about to run the project. The plugin can then perform required operations before the project runs.
- This method must return a boolean. If this method returns [code]false[/code], the project will not run. The run is aborted immediately, so this also prevents all other plugins' [method build] methods from running.
-
-
-
-
-
- Clear all the state and reset the object being edited to zero. This ensures your plugin does not keep editing a currently existing node, or a node from the wrong scene.
-
-
-
-
-
- Called by the engine when the user disables the [EditorPlugin] in the Plugin tab of the project settings window.
-
-
-
-
-
-
- This function is used for plugins that edit specific object types (nodes or resources). It requests the editor to edit the given object.
-
-
-
-
-
- Called by the engine when the user enables the [EditorPlugin] in the Plugin tab of the project settings window.
-
-
-
-
-
-
- Called by the engine when the 2D editor's viewport is updated. Use the [code]overlay[/code] [Control] for drawing. You can update the viewport manually by calling [method update_overlays].
- [codeblock]
- func forward_canvas_draw_over_viewport(overlay):
- # Draw a circle at cursor position.
- overlay.draw_circle(overlay.get_local_mouse_position(), 64, Color.white)
-
- func forward_canvas_gui_input(event):
- if event is InputEventMouseMotion:
- # Redraw viewport when cursor is moved.
- update_overlays()
- return true
- return false
- [/codeblock]
-
-
-
-
-
-
- This method is the same as [method forward_canvas_draw_over_viewport], except it draws on top of everything. Useful when you need an extra layer that shows over anything else.
- You need to enable calling of this method by using [method set_force_draw_over_forwarding_enabled].
-
-
-
-
-
-
- Called when there is a root node in the current edited scene, [method handles] is implemented and an [InputEvent] happens in the 2D viewport. Intercepts the [InputEvent], if [code]return true[/code] [EditorPlugin] consumes the [code]event[/code], otherwise forwards [code]event[/code] to other Editor classes. Example:
- [codeblock]
- # Prevents the InputEvent to reach other Editor classes
- func forward_canvas_gui_input(event):
- var forward = true
- return forward
- [/codeblock]
- Must [code]return false[/code] in order to forward the [InputEvent] to other Editor classes. Example:
- [codeblock]
- # Consumes InputEventMouseMotion and forwards other InputEvent types
- func forward_canvas_gui_input(event):
- var forward = false
- if event is InputEventMouseMotion:
- forward = true
- return forward
- [/codeblock]
-
-
-
-
-
-
- Called by the engine when the 3D editor's viewport is updated. Use the [code]overlay[/code] [Control] for drawing. You can update the viewport manually by calling [method update_overlays].
- [codeblock]
- func forward_spatial_draw_over_viewport(overlay):
- # Draw a circle at cursor position.
- overlay.draw_circle(overlay.get_local_mouse_position(), 64)
-
- func forward_spatial_gui_input(camera, event):
- if event is InputEventMouseMotion:
- # Redraw viewport when cursor is moved.
- update_overlays()
- return true
- return false
- [/codeblock]
-
-
-
-
-
-
- This method is the same as [method forward_spatial_draw_over_viewport], except it draws on top of everything. Useful when you need an extra layer that shows over anything else.
- You need to enable calling of this method by using [method set_force_draw_over_forwarding_enabled].
-
-
-
-
-
-
-
- Called when there is a root node in the current edited scene, [method handles] is implemented and an [InputEvent] happens in the 3D viewport. Intercepts the [InputEvent], if [code]return true[/code] [EditorPlugin] consumes the [code]event[/code], otherwise forwards [code]event[/code] to other Editor classes. Example:
- [codeblock]
- # Prevents the InputEvent to reach other Editor classes
- func forward_spatial_gui_input(camera, event):
- return EditorPlugin.AFTER_GUI_INPUT_STOP
- [/codeblock]
- Must [code]return false[/code] in order to forward the [InputEvent] to other Editor classes. Example:
- [codeblock]
- # Consumes InputEventMouseMotion and forwards other InputEvent types
- func forward_spatial_gui_input(camera, event):
- var forward = EditorPlugin.AFTER_GUI_INPUT_STOP
- if event is InputEventMouseMotion:
- forward = EditorPlugin.AFTER_GUI_INPUT_PASS
- return forward
- [/codeblock]
-
-
-
-
-
- This is for editors that edit script-based objects. You can return a list of breakpoints in the format ([code]script:line[/code]), for example: [code]res://path_to_script.gd:25[/code].
-
-
-
-
-
- Returns the [EditorInterface] object that gives you control over Godot editor's window and its functionalities.
-
-
-
-
-
- Override this method in your plugin to return a [Texture] in order to give it an icon.
- For main screen plugins, this appears at the top of the screen, to the right of the "2D", "3D", "Script", and "AssetLib" buttons.
- Ideally, the plugin icon should be white with a transparent background and 16x16 pixels in size.
- [codeblock]
- func get_plugin_icon():
- # You can use a custom icon:
- return preload("res://addons/my_plugin/my_plugin_icon.svg")
- # Or use a built-in icon:
- return get_editor_interface().get_base_control().get_icon("Node", "EditorIcons")
- [/codeblock]
-
-
-
-
-
- Override this method in your plugin to provide the name of the plugin when displayed in the Godot editor.
- For main screen plugins, this appears at the top of the screen, to the right of the "2D", "3D", "Script", and "AssetLib" buttons.
-
-
-
-
-
- Gets the Editor's dialogue used for making scripts.
- [b]Note:[/b] Users can configure it before use.
- [b]Warning:[/b] Removing and freeing this node will render a part of the editor useless and may cause a crash.
-
-
-
-
-
- Override this method to provide a state data you want to be saved, like view position, grid settings, folding, etc. This is used when saving the scene (so state is kept when opening it again) and for switching tabs (so state can be restored when the tab returns). This data is automatically saved for each scene in an [code]editstate[/code] file in the editor metadata folder. If you want to store global (scene-independent) editor data for your plugin, you can use [method get_window_layout] instead.
- Use [method set_state] to restore your saved state.
- [b]Note:[/b] This method should not be used to save important settings that should persist with the project.
- [b]Note:[/b] You must implement [method get_plugin_name] for the state to be stored and restored correctly.
- [codeblock]
- func get_state():
- var state = {"zoom": zoom, "preferred_color": my_color}
- return state
- [/codeblock]
-
-
-
-
-
- Gets the undo/redo object. Most actions in the editor can be undoable, so use this object to make sure this happens when it's worth it.
-
-
-
-
-
-
- Override this method to provide the GUI layout of the plugin or any other data you want to be stored. This is used to save the project's editor layout when [method queue_save_layout] is called or the editor layout was changed (for example changing the position of a dock). The data is stored in the [code]editor_layout.cfg[/code] file in the editor metadata directory.
- Use [method set_window_layout] to restore your saved layout.
- [codeblock]
- func get_window_layout(configuration):
- configuration.set_value("MyPlugin", "window_position", $Window.position)
- configuration.set_value("MyPlugin", "icon_color", $Icon.modulate)
- [/codeblock]
-
-
-
-
-
-
- Implement this function if your plugin edits a specific type of object (Resource or Node). If you return [code]true[/code], then you will get the functions [method edit] and [method make_visible] called when the editor requests them. If you have declared the methods [method forward_canvas_gui_input] and [method forward_spatial_gui_input] these will be called too.
-
-
-
-
-
- Returns [code]true[/code] if this is a main screen editor plugin (it goes in the workspace selector together with [b]2D[/b], [b]3D[/b], [b]Script[/b] and [b]AssetLib[/b]).
-
-
-
-
-
- Minimizes the bottom panel.
-
-
-
-
-
-
- Makes a specific item in the bottom panel visible.
-
-
-
-
-
-
- This function will be called when the editor is requested to become visible. It is used for plugins that edit a specific object type.
- Remember that you have to manage the visibility of all your editor controls manually.
-
-
-
-
-
- Queue save the project's editor layout.
-
-
-
-
-
-
- Removes an Autoload [code]name[/code] from the list.
-
-
-
-
-
-
- Removes the control from the bottom panel. You have to manually [method Node.queue_free] the control.
-
-
-
-
-
-
-
- Removes the control from the specified container. You have to manually [method Node.queue_free] the control.
-
-
-
-
-
-
- Removes the control from the dock. You have to manually [method Node.queue_free] the control.
-
-
-
-
-
-
-
-
-
-
-
-
- Removes a custom type added by [method add_custom_type].
-
-
-
-
-
-
- Removes an export plugin registered by [method add_export_plugin].
-
-
-
-
-
-
- Removes an import plugin registered by [method add_import_plugin].
-
-
-
-
-
-
- Removes an inspector plugin registered by [method add_import_plugin]
-
-
-
-
-
-
- Removes a scene importer registered by [method add_scene_import_plugin].
-
-
-
-
-
-
- Removes a gizmo plugin registered by [method add_spatial_gizmo_plugin].
-
-
-
-
-
-
- Removes a menu [code]name[/code] from [b]Project > Tools[/b].
-
-
-
-
-
- This method is called after the editor saves the project or when it's closed. It asks the plugin to save edited external scenes/resources.
-
-
-
-
-
- Enables calling of [method forward_canvas_force_draw_over_viewport] for the 2D editor and [method forward_spatial_force_draw_over_viewport] for the 3D editor when their viewports are updated. You need to call this method only once and it will work permanently for this plugin.
-
-
-
-
-
- Use this method if you always want to receive inputs from 3D view screen inside [method forward_spatial_gui_input]. It might be especially usable if your plugin will want to use raycast in the scene.
-
-
-
-
-
-
- Restore the state saved by [method get_state]. This method is called when the current scene tab is changed in the editor.
- [b]Note:[/b] Your plugin must implement [method get_plugin_name], otherwise it will not be recognized and this method will not be called.
- [codeblock]
- func set_state(data):
- zoom = data.get("zoom", 1.0)
- preferred_color = data.get("my_color", Color.white)
- [/codeblock]
-
-
-
-
-
-
- Restore the plugin GUI layout and data saved by [method get_window_layout]. This method is called for every plugin on editor startup. Use the provided [code]configuration[/code] file to read your saved data.
- [codeblock]
- func set_window_layout(configuration):
- $Window.position = configuration.get_value("MyPlugin", "window_position", Vector2())
- $Icon.modulate = configuration.get_value("MyPlugin", "icon_color", Color.white)
- [/codeblock]
-
-
-
-
-
- Updates the overlays of the 2D and 3D editor viewport. Causes methods [method forward_canvas_draw_over_viewport], [method forward_canvas_force_draw_over_viewport], [method forward_spatial_draw_over_viewport] and [method forward_spatial_force_draw_over_viewport] to be called.
-
-
-
-
-
-
-
- Emitted when user changes the workspace ([b]2D[/b], [b]3D[/b], [b]Script[/b], [b]AssetLib[/b]). Also works with custom screens defined by plugins.
-
-
-
-
-
-
-
-
-
-
- Emitted when the scene is changed in the editor. The argument will return the root node of the scene that has just become active. If this scene is new and empty, the argument will be [code]null[/code].
-
-
-
-
-
- Emitted when user closes a scene. The argument is file path to a closed scene.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Represents the size of the [enum DockSlot] enum.
-
-
-
-
-
-
-
-
-
diff --git a/doc/classes/EditorProperty.xml b/doc/classes/EditorProperty.xml
deleted file mode 100644
index b6a72b0..0000000
--- a/doc/classes/EditorProperty.xml
+++ /dev/null
@@ -1,143 +0,0 @@
-
-
-
- Custom control to edit properties for adding into the inspector.
-
-
- This control allows property editing for one or multiple properties into [EditorInspector]. It is added via [EditorInspectorPlugin].
-
-
-
-
-
-
-
-
- If any of the controls added can gain keyboard focus, add it here. This ensures that focus will be restored if the inspector is refreshed.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Gets the edited object.
-
-
-
-
-
- Gets the edited property. If your editor is for a single property (added via [method EditorInspectorPlugin.parse_property]), then this will return the property.
-
-
-
-
-
-
- Puts the [code]editor[/code] control below the property label. The control must be previously added using [method Node.add_child].
-
-
-
-
-
- When this virtual function is called, you must update your editor.
-
-
-
-
-
- Used by the inspector, set to [code]true[/code] when the property is checkable.
-
-
- Used by the inspector, set to [code]true[/code] when the property is checked.
-
-
- Used by the inspector, set to [code]true[/code] when the property is drawn with the editor theme's warning color. This is used for editable children's properties.
-
-
- Used by the inspector, set to [code]true[/code] when the property can add keys for animation.
-
-
- Set this property to change the label (if you want to show one).
-
-
- Used by the inspector, set to [code]true[/code] when the property is read-only.
-
-
-
-
-
-
-
- Emit it if you want multiple properties modified at the same time. Do not use if added via [method EditorInspectorPlugin.parse_property].
-
-
-
-
-
-
- Used by sub-inspectors. Emit it if what was selected was an Object ID.
-
-
-
-
-
-
-
-
- Do not emit this manually, use the [method emit_changed] method instead.
-
-
-
-
-
-
- Emitted when a property was checked. Used internally.
-
-
-
-
-
- Emit it if you want to add this value as an animation key (check for keying being enabled first).
-
-
-
-
-
-
- Emit it if you want to key a property with a single value.
-
-
-
-
-
-
- Emit it if you want to mark (or unmark) the value of a property for being saved regardless of being equal to the default value.
- The default value is the one the property will get when the node is just instantiated and can come from an ancestor scene in the inheritance/instancing chain, a script or a builtin class.
-
-
-
-
-
-
- If you want a sub-resource to be edited, emit this signal with the resource.
-
-
-
-
-
-
- Emitted when selected. Used internally.
-
-
-
-
-
-
diff --git a/doc/classes/EditorResourceConversionPlugin.xml b/doc/classes/EditorResourceConversionPlugin.xml
deleted file mode 100644
index 2db40dc..0000000
--- a/doc/classes/EditorResourceConversionPlugin.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/classes/EditorResourcePicker.xml b/doc/classes/EditorResourcePicker.xml
deleted file mode 100644
index c95d854..0000000
--- a/doc/classes/EditorResourcePicker.xml
+++ /dev/null
@@ -1,96 +0,0 @@
-
-
-
- Godot editor's control for selecting [Resource] type properties.
-
-
- This [Control] node is used in the editor's Inspector dock to allow editing of [Resource] type properties. It provides options for creating, loading, saving and converting resources. Can be used with [EditorInspectorPlugin] to recreate the same behavior.
- [b]Note:[/b] This [Control] does not include any editor for the resource, as editing is controlled by the Inspector dock itself or sub-Inspectors.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns a list of all allowed types and subtypes corresponding to the [member base_type]. If the [member base_type] is empty, an empty list is returned.
-
-
-
-
-
-
-
-
-
-
-
-
-
- This virtual method can be implemented to handle context menu items not handled by default. See [method set_create_options].
-
-
-
-
-
-
- This virtual method is called when updating the context menu of [EditorResourcePicker]. Implement this method to override the "New ..." items with your own options. [code]menu_node[/code] is a reference to the [PopupMenu] node.
- [b]Note:[/b] Implement [method handle_menu_selected] to handle these custom items.
-
-
-
-
-
-
- Sets the toggle mode state for the main button. Works only if [member toggle_mode] is set to [code]true[/code].
-
-
-
-
-
- The base type of allowed resource types. Can be a comma-separated list of several options.
-
-
- If [code]true[/code], the value can be selected and edited.
-
-
- The edited resource value.
-
-
- If [code]true[/code], the main button with the resource preview works in the toggle mode. Use [method set_toggle_pressed] to manually set the state.
-
-
-
-
-
-
- Emitted when the value of the edited resource was changed.
-
-
-
-
-
-
- Emitted when the resource value was set and user clicked to edit it. When [code]edit[/code] is [code]true[/code], the signal was caused by the context menu "Edit" option.
-
-
-
-
-
-
diff --git a/doc/classes/EditorResourcePreview.xml b/doc/classes/EditorResourcePreview.xml
deleted file mode 100644
index ba5f714..0000000
--- a/doc/classes/EditorResourcePreview.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-
-
-
- Helper to generate previews of resources or files.
-
-
- This object is used to generate previews for resources of files.
- [b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_resource_previewer].
-
-
-
-
-
-
-
-
- Create an own, custom preview generator.
-
-
-
-
-
-
- Check if the resource changed, if so, it will be invalidated and the corresponding signal emitted.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Removes a custom preview generator.
-
-
-
-
-
-
-
- Emitted if a preview was invalidated (changed). [code]path[/code] corresponds to the path of the preview.
-
-
-
-
-
-
diff --git a/doc/classes/EditorResourcePreviewGenerator.xml b/doc/classes/EditorResourcePreviewGenerator.xml
deleted file mode 100644
index e995e9f..0000000
--- a/doc/classes/EditorResourcePreviewGenerator.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
-
- Custom generator of previews.
-
-
- Custom code to generate previews. Please check [code]file_dialog/thumbnail_size[/code] in [EditorSettings] to find out the right size to do previews at.
-
-
-
-
-
-
-
- If this function returns [code]true[/code], the generator will call [method generate] or [method generate_from_path] for small previews as well.
- By default, it returns [code]false[/code].
-
-
-
-
-
-
-
- Generate a preview from a given resource with the specified size. This must always be implemented.
- Returning an empty texture is an OK way to fail and let another generator take care.
- Care must be taken because this function is always called from a thread (not the main thread).
-
-
-
-
-
-
-
- Generate a preview directly from a path with the specified size. Implementing this is optional, as default code will load and call [method generate].
- Returning an empty texture is an OK way to fail and let another generator take care.
- Care must be taken because this function is always called from a thread (not the main thread).
-
-
-
-
-
- If this function returns [code]true[/code], the generator will automatically generate the small previews from the normal preview texture generated by the methods [method generate] or [method generate_from_path].
- By default, it returns [code]false[/code].
-
-
-
-
-
-
- Returns [code]true[/code] if your generator supports the resource of type [code]type[/code].
-
-
-
-
-
-
diff --git a/doc/classes/EditorSceneImporter.xml b/doc/classes/EditorSceneImporter.xml
deleted file mode 100644
index 5af5017..0000000
--- a/doc/classes/EditorSceneImporter.xml
+++ /dev/null
@@ -1,77 +0,0 @@
-
-
-
- Imports scenes from third-parties' 3D files.
-
-
- [EditorSceneImporter] allows to define an importer script for a third-party 3D format.
- To use [EditorSceneImporter], register it using the [method EditorPlugin.add_scene_import_plugin] method first.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/classes/EditorScenePostImport.xml b/doc/classes/EditorScenePostImport.xml
deleted file mode 100644
index b7cbb2f..0000000
--- a/doc/classes/EditorScenePostImport.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
- Post-processes scenes after import.
-
-
- Imported scenes can be automatically modified right after import by setting their [b]Custom Script[/b] Import property to a [code]tool[/code] script that inherits from this class.
- The [method post_import] callback receives the imported scene's root node and returns the modified version of the scene. Usage example:
- [codeblock]
- tool # Needed so it runs in editor
- extends EditorScenePostImport
-
- # This sample changes all node names
-
- # Called right after the scene is imported and gets the root node
- func post_import(scene):
- # Change all node names to "modified_[oldnodename]"
- iterate(scene)
- return scene # Remember to return the imported scene
-
- func iterate(node):
- if node != null:
- node.name = "modified_" + node.name
- for child in node.get_children():
- iterate(child)
- [/codeblock]
-
-
- $DOCS_URL/tutorials/assets_pipeline/importing_scenes.html#custom-script
-
-
-
-
-
- Returns the source file path which got imported (e.g. [code]res://scene.dae[/code]).
-
-
-
-
-
- Returns the resource folder the imported scene file is located in.
-
-
-
-
-
-
- Called after the scene was imported. This method must return the modified version of the scene.
-
-
-
-
-
-
diff --git a/doc/classes/EditorScript.xml b/doc/classes/EditorScript.xml
deleted file mode 100644
index 0197355..0000000
--- a/doc/classes/EditorScript.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
-
- Base script that can be used to add extension functions to the editor.
-
-
- Scripts extending this class and implementing its [method _run] method can be executed from the Script Editor's [b]File > Run[/b] menu option (or by pressing [kbd]Ctrl + Shift + X[/kbd]) while the editor is running. This is useful for adding custom in-editor functionality to Godot. For more complex additions, consider using [EditorPlugin]s instead.
- [b]Note:[/b] Extending scripts need to have [code]tool[/code] mode enabled.
- [b]Example script:[/b]
- [codeblock]
- tool
- extends EditorScript
-
- func _run():
- print("Hello from the Godot Editor!")
- [/codeblock]
- [b]Note:[/b] The script is run in the Editor context, which means the output is visible in the console window started with the Editor (stdout) instead of the usual Godot [b]Output[/b] dock.
-
-
-
-
-
-
-
- This method is executed by the Editor when [b]File > Run[/b] is used.
-
-
-
-
-
-
- Adds [code]node[/code] as a child of the root node in the editor context.
- [b]Warning:[/b] The implementation of this method is currently disabled.
-
-
-
-
-
- Returns the [EditorInterface] singleton instance.
-
-
-
-
-
- Returns the Editor's currently active scene.
-
-
-
-
-
-
diff --git a/doc/classes/EditorScriptPicker.xml b/doc/classes/EditorScriptPicker.xml
deleted file mode 100644
index c2b9b1f..0000000
--- a/doc/classes/EditorScriptPicker.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
- Godot editor's control for selecting the [code]script[/code] property of a [Node].
-
-
- Similar to [EditorResourcePicker] this [Control] node is used in the editor's Inspector dock, but only to edit the [code]script[/code] property of a [Node]. Default options for creating new resources of all possible subtypes are replaced with dedicated buttons that open the "Attach Node Script" dialog. Can be used with [EditorInspectorPlugin] to recreate the same behavior.
- [b]Note:[/b] You must set the [member script_owner] for the custom context menu items to work.
-
-
-
-
-
-
-
- The owner [Node] of the script property that holds the edited resource.
-
-
-
-
-
diff --git a/doc/classes/EditorSelection.xml b/doc/classes/EditorSelection.xml
deleted file mode 100644
index 5ce8e39..0000000
--- a/doc/classes/EditorSelection.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
-
- Manages the SceneTree selection in the editor.
-
-
- This object manages the SceneTree selection in the editor.
- [b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_selection].
-
-
-
-
-
-
-
-
- Adds a node to the selection.
- [b]Note:[/b] The newly selected node will not be automatically edited in the inspector. If you want to edit a node, use [method EditorInterface.edit_node].
-
-
-
-
-
- Clear the selection.
-
-
-
-
-
- Gets the list of selected nodes.
-
-
-
-
-
- Gets the list of selected nodes, optimized for transform operations (i.e. moving them, rotating, etc). This list avoids situations where a node is selected and also child/grandchild.
-
-
-
-
-
-
- Removes a node from the selection.
-
-
-
-
-
-
- Emitted when the selection changes.
-
-
-
-
-
-
diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml
deleted file mode 100644
index 891a0bf..0000000
--- a/doc/classes/EditorSettings.xml
+++ /dev/null
@@ -1,851 +0,0 @@
-
-
-
- Object that holds the project-independent editor settings.
-
-
- Object that holds the project-independent editor settings. These settings are generally visible in the [b]Editor > Editor Settings[/b] menu.
- Property names use slash delimiters to distinguish sections. Setting values can be of any [Variant] type. It's recommended to use [code]snake_case[/code] for editor settings to be consistent with the Godot editor itself.
- Accessing the settings can be done using the following methods, such as:
- [codeblock]
- # `settings.set("some/property", value)` also works as this class overrides `_set()` internally.
- settings.set_setting("some/property",value)
-
- # `settings.get("some/property", value)` also works as this class overrides `_get()` internally.
- settings.get_setting("some/property")
-
- var list_of_settings = settings.get_property_list()
- [/codeblock]
- [b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_editor_settings].
-
-
-
-
-
-
-
-
- Adds a custom property info to a property. The dictionary must contain:
- - [code]name[/code]: [String] (the name of the property)
- - [code]type[/code]: [int] (see [enum Variant.Type])
- - optionally [code]hint[/code]: [int] (see [enum PropertyHint]) and [code]hint_string[/code]: [String]
- [b]Example:[/b]
- [codeblock]
- editor_settings.set("category/property_name", 0)
-
- var property_info = {
- "name": "category/property_name",
- "type": TYPE_INT,
- "hint": PROPERTY_HINT_ENUM,
- "hint_string": "one,two,three"
- }
-
- editor_settings.add_property_info(property_info)
- [/codeblock]
-
-
-
-
-
-
- Erases the setting whose name is specified by [code]property[/code].
-
-
-
-
-
- Returns the list of favorite files and directories for this project.
-
-
-
-
-
-
-
-
- Returns project-specific metadata for the [code]section[/code] and [code]key[/code] specified. If the metadata doesn't exist, [code]default[/code] will be returned instead. See also [method set_project_metadata].
-
-
-
-
-
- Returns the project-specific settings path. Projects all have a unique subdirectory inside the settings path where project-specific settings are saved.
-
-
-
-
-
- Returns the list of recently visited folders in the file dialog for this project.
-
-
-
-
-
-
- Returns the value of the setting specified by [code]name[/code]. This is equivalent to using [method Object.get] on the EditorSettings instance.
-
-
-
-
-
- Gets the global settings path for the engine. Inside this path, you can find some standard paths such as:
- [code]settings/tmp[/code] - Used for temporary storage of files
- [code]settings/templates[/code] - Where export templates are located
-
-
-
-
-
-
- Returns [code]true[/code] if the setting specified by [code]name[/code] exists, [code]false[/code] otherwise.
-
-
-
-
-
-
- Returns [code]true[/code] if the setting specified by [code]name[/code] can have its value reverted to the default value, [code]false[/code] otherwise. When this method returns [code]true[/code], a Revert button will display next to the setting in the Editor Settings.
-
-
-
-
-
-
- Returns the default value of the setting specified by [code]name[/code]. This is the value that would be applied when clicking the Revert button in the Editor Settings.
-
-
-
-
-
-
- Sets the list of favorite files and directories for this project.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Sets project-specific metadata with the [code]section[/code], [code]key[/code] and [code]data[/code] specified. This metadata is stored outside the project folder and therefore won't be checked into version control. See also [method get_project_metadata].
-
-
-
-
-
-
- Sets the list of recently visited folders in the file dialog for this project.
-
-
-
-
-
-
-
- Sets the [code]value[/code] of the setting specified by [code]name[/code]. This is equivalent to using [method Object.set] on the EditorSettings instance.
-
-
-
-
-
- If [code]true[/code], displays folders in the FileSystem dock's bottom pane when split mode is enabled. If [code]false[/code], only files will be displayed in the bottom pane. Split mode can be toggled by pressing the icon next to the [code]res://[/code] folder path.
- [b]Note:[/b] This setting has no effect when split mode is disabled (which is the default).
-
-
- Controls where the editor will display the FileSystem panel.
-
-
- Controls whether the FileSystem panel can be split horizontally or vertically.
-
-
- The thumbnail size to use in the FileSystem dock (in pixels). See also [member filesystem/file_dialog/thumbnail_size].
-
-
- The refresh interval to use for the inspector dock's properties. The effect of this setting is mainly noticeable when adjusting gizmos in the 2D/3D editor and looking at the inspector at the same time. Lower values make the inspector more often, but take up more CPU time.
-
-
- The tint intensity to use for the subresources background in the inspector dock. The tint is used to distinguish between different subresources in the inspector. Higher values result in a more noticeable background color difference.
-
-
- If [code]true[/code], the Create dialog (Create New Node/Create New Resource) will start with all its sections expanded. Otherwise, sections will be collapsed until the user starts searching (which will automatically expand sections as needed).
-
-
- The "start" stop of the color gradient to use for bones in the 2D skeleton editor.
-
-
- The "end" stop of the color gradient to use for bones in the 2D skeleton editor.
-
-
- The color to use for inverse kinematics-enabled bones in the 2D skeleton editor.
-
-
- The outline color to use for non-selected bones in the 2D skeleton editor. See also [member editors/2d/bone_selected_color].
-
-
- The outline size in the 2D skeleton editor (in pixels). See also [member editors/2d/bone_width].
-
-
- The color to use for selected bones in the 2D skeleton editor. See also [member editors/2d/bone_outline_color].
-
-
- The bone width in the 2D skeleton editor (in pixels). See also [member editors/2d/bone_outline_size].
-
-
- If [code]true[/code], prevents the 2D editor viewport from leaving the scene. Limits are calculated dynamically based on nodes present in the current scene. If [code]false[/code], the 2D editor viewport will be able to move freely, but you risk getting lost when zooming out too far. You can refocus on the scene by selecting a node then pressing [kbd]F[/kbd].
-
-
- The grid color to use in the 2D editor.
-
-
- The guides color to use in the 2D editor. Guides can be created by dragging the mouse cursor from the rulers.
-
-
- The pan speed factor when scrolling the mouse wheel on the 2D editor viewport. Only effective if [member editors/2d/scroll_to_pan] is [code]true[/code].
-
-
- If [code]true[/code], scrolling the mouse wheel will pan vertically instead of zoom in the 2D editor. Holding [kbd]Shift[/kbd] at the same time will pan horizontally instead of vertically. See [member editors/2d/pan_speed] to adjust the scrolling speed.
- [b]Note:[/b] If [code]true[/code], holding [kbd]Ctrl[/kbd] will temporarily override this behavior and will zoom instead of pan.
-
-
- If [code]true[/code], allows panning in the 2D editor viewport by holding [kbd]Space[/kbd], without having to hold any mouse buttons at the same time. This can be useful to improve navigation usability when using a trackpad.
-
-
- The color to use when drawing smart snapping lines in the 2D editor. The smart snapping lines will automatically display when moving 2D nodes if smart snapping is enabled in the Snapping Options menu at the top of the 2D editor viewport.
-
-
- The color of the viewport border in the 2D editor. This border represents the viewport's size at the base resolution defined in the Project Settings. Objects placed outside this border will not be visible unless a [Camera2D] node is used, or unless the window is resized and the stretch mode is set to [code]disabled[/code].
-
-
- If [code]true[/code], wraps around the mouse cursor when it reaches one of the 2D editor viewport's edges. This makes panning over large areas easier, as you don't have to stop and reposition the mouse every time it's about to hit the screen's borders.
-
-
- The default camera field of view to use in the 3D editor (in degrees). The camera field of view can be adjusted on a per-scene basis using the [b]View[/b] menu at the top of the 3D editor. If a scene had its camera field of view adjusted using the [b]View[/b] menu, this setting is ignored in the scene in question. This setting is also ignored while a Camera3D node is being previewed in the editor.
-
-
- The default camera far clip distance to use in the 3D editor (in degrees). Higher values make it possible to view objects placed further away from the camera, at the cost of lower precision in the depth buffer (which can result in visible Z-fighting in the distance). The camera far clip distance can be adjusted on a per-scene basis using the [b]View[/b] menu at the top of the 3D editor. If a scene had its camera far clip distance adjusted using the [b]View[/b] menu, this setting is ignored in the scene in question. This setting is also ignored while a Camera3D node is being previewed in the editor.
-
-
- The default camera near clip distance to use in the 3D editor (in degrees). Lower values make it possible to view objects placed closer to the camera, at the cost of lower precision in the depth buffer (which can result in visible Z-fighting in the distance). The camera near clip distance can be adjusted on a per-scene basis using the [b]View[/b] menu at the top of the 3D editor. If a scene had its camera near clip distance adjusted using the [b]View[/b] menu, this setting is ignored in the scene in question. This setting is also ignored while a Camera3D node is being previewed in the editor.
-
-
- The modifier key to use to enable freelook in the 3D editor (on top of pressing the right mouse button).
- [b]Note:[/b] Regardless of this setting, the freelook toggle keyboard shortcut ([kbd]Shift + F[/kbd] by default) is always available.
- [b]Note:[/b] On certain window managers on Linux, the [kbd]Alt[/kbd] key will be intercepted by the window manager when clicking a mouse button at the same time. This means Godot will not see the modifier key as being pressed.
-
-
- The base 3D freelook speed in units per second. This can be adjusted by using the mouse wheel while in freelook mode, or by holding down the "fast" or "slow" modifier keys ([kbd]Shift[/kbd] and [kbd]Alt[/kbd] by default, respectively).
-
-
- The inertia of the 3D freelook camera. Higher values make the camera start and stop slower, which looks smoother but adds latency.
-
-
- The navigation scheme to use when freelook is enabled in the 3D editor. Some of the navigation schemes below may be more convenient when designing specific levels in the 3D editor.
- - [b]Default:[/b] The "Freelook Forward", "Freelook Backward", "Freelook Up" and "Freelook Down" keys will move relative to the camera, taking its pitch angle into account for the movement.
- - [b]Partially Axis-Locked:[/b] The "Freelook Forward" and "Freelook Backward" keys will move relative to the camera, taking its pitch angle into account for the movement. The "Freelook Up" and "Freelook Down" keys will move in an "absolute" manner, [i]not[/i] taking the camera's pitch angle into account for the movement.
- - [b]Fully Axis-Locked:[/b] The "Freelook Forward", "Freelook Backward", "Freelook Up" and "Freelook Down" keys will move in an "absolute" manner, [i]not[/i] taking the camera's pitch angle into account for the movement.
- See also [member editors/3d/navigation/navigation_scheme].
-
-
- The mouse sensitivity to use while freelook mode is active in the 3D editor. See also [member editors/3d/navigation_feel/orbit_sensitivity].
-
-
- If [code]true[/code], freelook speed is linked to the zoom value used in the camera orbit mode in the 3D editor.
-
-
- The grid division bias to use in the 3D editor. Negative values will cause small grid divisions to appear earlier, whereas positive values will cause small grid divisions to appear later.
-
-
- The smallest grid division to use in the 3D editor, specified as a power of 2. The grid will not be able to get larger than [code]1 ^ grid_division_level_max[/code] units. By default, this means grid divisions cannot get smaller than 100 units each, no matter how far away the camera is from the grid.
-
-
- The smallest grid division to use in the 3D editor, specified as a power of 2. The grid will not be able to get smaller than [code]1 ^ grid_division_level_min[/code] units. By default, this means grid divisions cannot get smaller than 1 unit each, no matter how close the camera is from the grid.
-
-
- The grid size in units. Higher values prevent the grid from appearing "cut off" at certain angles, but make the grid more demanding to render. Depending on the camera's position, the grid may not be fully visible since a shader is used to fade it progressively.
-
-
- If [code]true[/code], render the grid on an XY plane. This can be useful for 3D side-scrolling games.
-
-
- If [code]true[/code], render the grid on an XZ plane.
-
-
- If [code]true[/code], render the grid on an YZ plane. This can be useful for 3D side-scrolling games.
-
-
- If [code]true[/code], enables 3-button mouse emulation mode. This is useful on laptops when using a trackpad.
- When 3-button mouse emulation mode is enabled, the pan, zoom and orbit modifiers can always be used in the 3D editor viewport, even when not holding down any mouse button.
- [b]Note:[/b] No matter the orbit modifier configured in [member editors/3d/navigation/orbit_modifier], [kbd]Alt[/kbd] will always remain usable for orbiting in this mode to improve usability with graphics tablets.
-
-
- If [code]true[/code], allows using the top row [kbd]0[/kbd]-[kbd]9[/kbd] keys to function as their equivalent numpad keys for 3D editor navigation. This should be enabled on keyboards that have no numeric keypad available.
-
-
- If [code]true[/code], invert the horizontal mouse axis when panning or orbiting in the 3D editor. This setting does [i]not[/i] apply to freelook mode.
-
-
- If [code]true[/code], invert the vertical mouse axis when panning, orbiting, or using freelook mode in the 3D editor.
-
-
- The navigation scheme to use in the 3D editor. Changing this setting will affect the mouse buttons that must be held down to perform certain operations in the 3D editor viewport.
- - [b]Godot[/b] Middle mouse button to orbit, [kbd]Shift + Middle mouse button[/kbd] to pan. [kbd]Mouse wheel[/kbd] to zoom.
- - [b]Maya:[/b] [kbd]Alt + Left mouse button[/kbd] to orbit. [kbd]Middle mouse button[/kbd] to pan, [kbd]Shift + Middle mouse button[/kbd] to pan 10 times faster. [kbd]Mouse wheel[/kbd] to zoom.
- - [b]Modo:[/b] [kbd]Alt + Left mouse button[/kbd] to orbit. [kbd]Alt + Shift + Left mouse button[/kbd] to pan. [kbd]Ctrl + Alt + Left mouse button[/kbd] to zoom.
- See also [member editors/3d/freelook/freelook_navigation_scheme].
- [b]Note:[/b] On certain window managers on Linux, the [kbd]Alt[/kbd] key will be intercepted by the window manager when clicking a mouse button at the same time. This means Godot will not see the modifier key as being pressed.
-
-
- The modifier key that must be held to orbit in the 3D editor.
- [b]Note:[/b] If [member editors/3d/navigation/emulate_3_button_mouse] is [code]true[/code], [kbd]Alt[/kbd] will always remain usable for orbiting to improve usability with graphics tablets.
- [b]Note:[/b] On certain window managers on Linux, the [kbd]Alt[/kbd] key will be intercepted by the window manager when clicking a mouse button at the same time. This means Godot will not see the modifier key as being pressed.
-
-
- The modifier key that must be held to pan in the 3D editor.
- [b]Note:[/b] On certain window managers on Linux, the [kbd]Alt[/kbd] key will be intercepted by the window manager when clicking a mouse button at the same time. This means Godot will not see the modifier key as being pressed.
-
-
- If [code]true[/code], warps the mouse around the 3D viewport while panning in the 3D editor. This makes it possible to pan over a large area without having to exit panning then mouse the mouse back constantly.
-
-
- The modifier key that must be held to zoom in the 3D editor.
- [b]Note:[/b] On certain window managers on Linux, the [kbd]Alt[/kbd] key will be intercepted by the window manager when clicking a mouse button at the same time. This means Godot will not see the modifier key as being pressed.
-
-
- The mouse cursor movement direction to use when zooming by moving the mouse. This does not affect zooming with the mouse wheel.
-
-
- The inertia to use when orbiting in the 3D editor. Higher values make the camera start and stop slower, which looks smoother but adds latency.
-
-
- The mouse sensitivity to use when orbiting in the 3D editor. See also [member editors/3d/freelook/freelook_sensitivity].
-
-
- The inertia to use when panning in the 3D editor. Higher values make the camera start and stop slower, which looks smoother but adds latency.
-
-
- The inertia to use when zooming in the 3D editor. Higher values make the camera start and stop slower, which looks smoother but adds latency.
-
-
- The color to use for the primary 3D grid. The color's alpha channel affects the grid's opacity.
-
-
- If set above 0, where a primary grid line should be drawn. By default, primary lines are configured to be more visible than secondary lines. This helps with measurements in the 3D editor. See also [member editors/3d/primary_grid_color] and [member editors/3d/secondary_grid_color].
-
-
- The color to use for the secondary 3D grid. This is generally a less visible color than [member editors/3d/primary_grid_color]. The color's alpha channel affects the grid's opacity.
-
-
- The color to use for the selection box that surrounds selected nodes in the 3D editor viewport. The color's alpha channel influences the selection box's opacity.
-
-
- If [code]true[/code], automatically updates animation tracks' target paths when renaming or reparenting nodes in the Scene tree dock.
-
-
- If [code]true[/code], display a confirmation dialog when adding a new track to an animation by pressing the "key" icon next to a property.
-
-
- If [code]true[/code], create a Bezier track instead of a standard track when pressing the "key" icon next to a property. Bezier tracks provide more control over animation curves, but are more difficult to adjust quickly.
-
-
- If [code]true[/code], create a [code]RESET[/code] track when creating a new animation track. This track can be used to restore the animation to a "default" state.
-
-
- The modulate color to use for "future" frames displayed in the animation editor's onion skinning feature.
-
-
- The modulate color to use for "past" frames displayed in the animation editor's onion skinning feature.
-
-
- The radius of each point's clickable area in 2D and 3D polygon editors (in pixels). Increase this value if you are having trouble selecting points in polygon editors. However, increasing this value may make it more difficult to select points located close to each other.
-
-
- If [code]true[/code], displays a gray outline matching the polygon's previous shape while dragging one of the points.
-
-
- The opacity of the minimap displayed in the bottom-right corner of the visual script and visual shader editors.
-
-
- The folder where projects should be scanned for (recursively), in a way similar to the project manager's [b]Scan[/b]button. This can be set to the same value as [member filesystem/directories/default_project_path] for convenience.
- [b]Note:[/b] Setting this path to a folder with very large amounts of files/folders can slow down the project manager startup significantly. To keep the project manager quick to start up, it is recommended to set this value to a folder as "specific" as possible.
-
-
- The folder where new projects should be created by default when clicking the project manager's [b]New Project[/b] button. This can be set to the same value as [member filesystem/directories/autoscan_project_path] for convenience.
-
-
- The display mode to use in the editor's file dialogs.
- - [b]Thumbnails[/b] takes more space, but displays dynamic resource thumbnails, making resources easier to preview without having to open them.
- - [b]List[/b] is more compact but doesn't display dynamic resource thumbnails. Instead, it displays static icons based on the file extension.
-
-
- If [code]true[/code], display hidden files in the editor's file dialogs. Files that have names starting with [code].[/code] are considered hidden (e.g. [code].hidden_file[/code]).
-
-
- The thumbnail size to use in the editor's file dialogs (in pixels). See also [member docks/filesystem/thumbnail_size].
-
-
- If [code]true[/code], uses lossless compression for binary resources.
-
-
- If [code]true[/code], when saving a file, the editor will rename the old file to a different name, save a new file, then only remove the old file once the new file has been saved. This makes loss of data less likely to happen if the editor or operating system exits unexpectedly while saving (e.g. due to a crash or power outage).
- [b]Note:[/b] On Windows, this feature can interact negatively with certain antivirus programs. In this case, you may have to set this to [code]false[/code] to prevent file locking issues.
-
-
- How to position the Cancel and OK buttons in the editor's [AcceptDialog]s. Different platforms have different standard behaviors for this, which can be overridden using this setting. This is useful if you use Godot both on Windows and macOS/Linux and your Godot muscle memory is stronger than your OS specific one.
- - [b]Auto[/b] follows the platform convention: Cancel first on macOS and Linux, OK first on Windows.
- - [b]Cancel First[/b] forces the ordering Cancel/OK.
- - [b]OK First[/b] forces the ordering OK/Cancel.
-
-
- If [code]true[/code], automatically opens screenshots with the default program associated to [code].png[/code] files after a screenshot is taken using the [b]Editor > Take Screenshot[/b] action.
-
-
- The font to use for the script editor. Must be a resource of a [Font] type such as a [code].ttf[/code] or [code].otf[/code] font file.
-
-
- The size of the font in the script editor. This setting does not impact the font size of the Output panel (see [member run/output/font_size]).
-
-
- The custom editor scale factor to use. This can be used for displays with very high DPI where a scale factor of 200% is not sufficient.
- [b]Note:[/b] Only effective if [member interface/editor/display_scale] is set to [b]Custom[/b].
-
-
- If [code]true[/code], darkens the rest of the editor when a modal dialog is open. If you need to pick colors on the rest of the editor while in modal dialog, disable this option.
-
-
- The display scale factor to use for the editor interface. Higher values are more suited to hiDPI/Retina displays.
- If set to [b]Auto[/b], the editor scale is automatically determined based on the screen resolution and reported display DPI. This heuristic is not always ideal, which means you can get better results by setting the editor scale manually.
- If set to [b]Custom[/b], the scaling value in [member interface/editor/custom_display_scale] will be used.
-
-
- The language to use for the editor interface.
- Translations are provided by the community. If you spot a mistake, [url=https://docs.godotengine.org/en/latest/community/contributing/editor_and_docs_localization.html]contribute to editor translations on Weblate![/url]
-
-
- If [code]true[/code], enables FreeType's font antialiasing on the editor fonts. Most fonts are not designed to look good with antialiasing disabled, so it's recommended to leave this enabled unless you're using a pixel art font.
-
-
- The font hinting mode to use for the editor fonts. FreeType supports the following font hinting modes:
- - [b]None:[/b] Don't use font hinting when rasterizing the font. This results in a smooth font, but it can look blurry.
- - [b]Light:[/b] Use hinting on the X axis only. This is a compromise between font sharpness and smoothness.
- - [b]Normal:[/b] Use hinting on both X and Y axes. This results in a sharp font, but it doesn't look very smooth.
- If set to [b]Auto[/b], the font hinting mode will be set to match the current operating system in use. This means the [b]Light[/b] hinting mode will be used on Windows and Linux, and the [b]None[/b] hinting mode will be used on macOS.
-
-
- If [code]true[/code] the names of the main screen plugins will be hidden (when they have an icon).
-
-
- The amount of sleeping between frames when the low-processor usage mode is enabled (in microseconds). Higher values will result in lower CPU/GPU usage, which can improve battery life on laptops. However, higher values will result in a less responsive editor. The default value is set to allow for maximum smoothness on monitors up to 144 Hz. See also [member interface/editor/unfocused_low_processor_mode_sleep_usec].
-
-
- The font to use for the editor interface. Must be a resource of a [Font] type such as a [code].ttf[/code] or [code].otf[/code] font file.
-
-
- The font to use for bold text in the editor interface. Must be a resource of a [Font] type such as a [code].ttf[/code] or [code].otf[/code] font file.
-
-
- The size of the font in the editor interface.
-
-
- If [code]true[/code], displays a confirmation dialog when exiting the editor when there are no unsaved changes.
- [b]Note:[/b] Regardless of this setting, the editor will [i]always[/i] display a quit confirmation dialog when there are unsaved changes.
-
-
- If [code]true[/code], the editor will save all scenes when confirming the [b]Save[/b] action when quitting the editor or quitting to the project list. If [code]false[/code], the editor will ask to save each scene individually.
-
-
- If [code]true[/code], the editor's Script tab will have a separate distraction mode setting from the 2D/3D/AssetLib tabs. If [code]false[/code], the distraction-free mode toggle is shared between all tabs.
-
-
- When the editor window is unfocused, the amount of sleeping between frames when the low-processor usage mode is enabled (in microseconds). Higher values will result in lower CPU/GPU usage, which can improve battery life on laptops (in addition to improving the running project's performance if the editor has to redraw continuously). However, higher values will result in a less responsive editor. The default value is set to limit the editor to 20 FPS when the editor window is unfocused. See also [member interface/editor/low_processor_mode_sleep_usec].
-
-
- The number of [Array] or [Dictionary] items to display on each "page" in the inspector. Higher values allow viewing more values per page, but take more time to load. This increased load time is noticeable when selecting nodes that have array or dictionary properties in the editor.
-
-
- The minimum width to use for each scene tab (in pixels). Only effective if [member interface/scene_tabs/resize_if_many_tabs] is [code]true[/code].
-
-
- If [code]true[/code], sets the scene tabs' minimum width to [member interface/scene_tabs/minimum_width].
-
-
- If [code]true[/code], show a button next to each scene tab that opens the scene's "dominant" script when clicked. The "dominant" script is the one that is at the highest level in the scene's hierarchy.
-
-
- If [code]true[/code], display an automatically-generated thumbnail when hovering scene tabs with the mouse. Scene thumbnails are generated when saving the scene.
-
-
- The color to use for "highlighted" user interface elements in the editor (pressed and hovered items).
-
-
- The spacing to add for buttons and list items in the editor (in pixels). Increasing this value is useful to improve usability on touch screens, at the cost of reducing the amount of usable screen real estate.
-
-
- The base color to use for user interface elements in the editor. Secondary colors (such as darker/lighter variants) are derived from this color.
-
-
- The border size to use for interface elements (in pixels).
-
-
- The contrast factor to use when deriving the editor theme's base color (see [member interface/theme/base_color]). When using a positive values, the derived colors will be [i]darker[/i] than the base color. This contrast factor can be set to a negative value, which will make the derived colors [i]brighter[/i] than the base color. Negative contrast rates often look better for light themes.
-
-
- The custom theme resource to use for the editor. Must be a Godot theme resource in [code].tres[/code] or [code].res[/code] format.
-
-
- If [code]true[/code], makes the background of selected tabs more contrasted in the editor theme (brighter on dark themes, darker on light themes).
-
-
- The icon and font color scheme to use in the editor.
- - [b]Auto[/b] determines the color scheme to use automatically based on [member interface/theme/base_color].
- - [b]Dark[/b] makes fonts and icons light (suitable for dark themes).
- - [b]Light[/b] makes fonts and icons dark (suitable for light themes). Icon colors are automatically converted by the editor following [url=https://github.com/godotengine/godot/blob/master/editor/editor_themes.cpp#L135]this set of rules[/url].
-
-
- The editor theme preset to use.
-
-
- The opacity to use when drawing relationship lines in the editor's [Tree]-based GUIs (such as the Scene tree dock).
-
-
- If [code]true[/code], use colored header backgrounds for individual [GraphNode]s in the visual script and visual shader editors. This can improve usability when frequently using these editors at low zoom levels.
-
-
- If [code]true[/code], long press on touchscreen is treated as right click.
- [b]Note:[/b] Defaults to [code]true[/code] on touchscreen devices.
-
-
- If [code]true[/code], enable two finger pan and scale gestures on touchscreen devices.
- [b]Note:[/b] Defaults to [code]true[/code] on touchscreen devices.
-
-
- If [code]true[/code], increases the scrollbar touch area to improve usability on touchscreen devices.
- [b]Note:[/b] Defaults to [code]true[/code] on touchscreen devices.
-
-
- Specify the multiplier to apply to the scale for the editor gizmo handles to improve usability on touchscreen devices.
- [b]Note:[/b] Defaults to [code]1[/code] on non-touchscreen devices.
-
-
- The address to listen to when starting the remote debugger. This can be set to [code]0.0.0.0[/code] to allow external clients to connect to the remote debugger (instead of restricting the remote debugger to connections from [code]localhost[/code]).
-
-
- The port to listen to when starting the remote debugger. Godot will try to use port numbers above the configured number if the configured number is already taken by another application.
-
-
- The SSL certificate bundle to use for HTTP requests made within the editor (e.g. from the AssetLib tab). If left empty, the [url=https://github.com/godotengine/godot/blob/master/thirdparty/certs/ca-certificates.crt]included Mozilla certificate bundle[/url] will be used.
-
-
- The sorting order to use in the project manager. When changing the sorting order in the project manager, this setting is set permanently in the editor settings.
-
-
- If [code]true[/code], saves all scenes and scripts automatically before running the project. Setting this to [code]false[/code] prevents the editor from saving if there are no changes which can speed up the project startup slightly, but it makes it possible to run a project that has unsaved changes. (Unsaved changes will not be visible in the running project.)
-
-
- If [code]true[/code], the editor will clear the Output panel when running the project.
-
-
- If [code]true[/code], the editor will collapse the Output panel when stopping the project.
-
-
- If [code]true[/code], the editor will expand the Output panel when running the project.
-
-
- The size of the font in the [b]Output[/b] panel at the bottom of the editor. This setting does not impact the font size of the script editor (see [member interface/editor/code_font_size]).
-
-
- The window mode to use to display the project when starting the project from the editor.
-
-
- The custom position to use when starting the project from the editor (in pixels from the top-left corner). Only effective if [member run/window_placement/rect] is set to [b]Custom Position[/b].
-
-
- The monitor to display the project on when starting the project from the editor.
-
-
- If [code]true[/code], displays the folding arrows next to indented code sections and allows code folding. If [code]false[/code], hides the folding arrows next to indented code sections and disallows code folding.
-
-
- The column at which to display a subtle line as a line length guideline for scripts. This should generally be greater than [member text_editor/appearance/line_length_guideline_soft_column].
-
-
- The column at which to display a [i]very[/i] subtle line as a line length guideline for scripts. This should generally be lower than [member text_editor/appearance/line_length_guideline_hard_column].
-
-
- If [code]true[/code], displays line numbers with zero padding (e.g. [code]007[/code] instead of [code]7[/code]).
-
-
- If [code]true[/code], displays a gutter at the left containing icons for bookmarks.
-
-
- If [code]true[/code], shows breakpoint gutter and its icons. If [code]false[/code], breakpoints will still be active but it won't be possible to add or remove breakpoints.
-
-
- If [code]true[/code], displays a gutter at the left containing icons for methods with signal connections.
-
-
- If [code]true[/code], displays line length guidelines to help you keep line lengths in check. See also [member text_editor/appearance/line_length_guideline_soft_column] and [member text_editor/appearance/line_length_guideline_soft_column].
-
-
- If [code]true[/code], displays line numbers in the gutter at the left.
-
-
- If [code]true[/code], wraps long lines over multiple lines to avoid horizontal scrolling. This is a display-only feature; it does not actually insert line breaks in your scripts.
-
-
- If [code]true[/code], adds static typing hints such as [code]-> void[/code] and [code]: int[/code] when performing method definition autocompletion.
-
-
- If [code]true[/code], automatically completes braces when making use of code completion.
-
-
- The offset to use when displaying [i]callhints[/i] (non-interactive tooltips that appear during function autocompletion) in the script editor (in pixels). Not to be confused with the code completion dialog, which is interactive.
-
-
- The delay in seconds after which autocompletion suggestions should be displayed when the user stops typing.
-
-
- If [code]true[/code], provides autocompletion suggestions for file paths in methods such as [code]load()[/code] and [code]preload()[/code].
-
-
- The delay in seconds after which the script editor should check for errors when the user stops typing.
-
-
- If [code]true[/code], the code completion tooltip will appear below the current line unless there is no space on screen below the current line. If [code]false[/code], the code completion tooltip will appear above the current line.
-
-
- If [code]true[/code], performs string autocompletion with single quotes. If [code]false[/code], performs string autocompletion with double quotes (which matches the [url=https://docs.godotengine.org/en/latest/tutorials/scripting/gdscript/gdscript_styleguide.html]GDScript style guide[/url]).
-
-
- If [code]true[/code], use a block-shaped caret instead of a line-shaped caret in the script editor.
-
-
- If [code]true[/code], makes the caret blink according to [member text_editor/cursor/caret_blink_speed]. Disabling this setting can improve battery life on laptops if you spend long amounts of time in the script editor, since it will reduce the frequency at which the editor needs to be redrawn.
-
-
- The interval at which to blink the caret (in seconds). See also [member text_editor/cursor/caret_blink].
-
-
- If [code]true[/code], the caret will be moved when right-clicking somewhere in the script editor (like when left-clicking or middle-clicking). If [code]false[/code], the caret will only be moved when left-clicking or middle-clicking somewhere.
-
-
- If [code]true[/code], allows scrolling past the end of the file in the script editor.
-
-
- If set to a value greater than [code]0[/code], automatically saves the current script following the specified interval (in seconds). This can be used to prevent data loss if the editor crashes.
-
-
- If [code]true[/code], reopens scripts that were opened in the last session when the editor is reopened on a given project.
-
-
- If [code]true[/code], trims trailing whitespace when saving a script. Trailing whitespace refers to tab and space characters placed at the end of lines. Since these serve no practical purpose, they can and should be removed to make version control diffs less noisy.
-
-
- The font size to use for the editor help (built-in class reference).
-
-
- The font size to use for code samples in the editor help (built-in class reference).
-
-
- The font size to use for headings in the editor help (built-in class reference).
-
-
- If [code]true[/code], displays a table of contents at the left of the editor help (at the location where the members overview would appear when editing a script).
-
-
- The script editor's background color. If set to a translucent color, the editor theme's base color will be visible behind.
-
-
- The script editor's base type color (used for types like [Vector2], [Vector3], ...).
-
-
- The script editor's bookmark icon color (displayed in the gutter).
-
-
- The script editor's brace mismatch color. Used when the caret is currently on a mismatched brace, parenthesis or bracket character.
-
-
- The script editor's breakpoint icon color (displayed in the gutter).
-
-
- The script editor's caret background color.
- [b]Note:[/b] This setting has no effect as it's currently unused.
-
-
- The script editor's caret color.
-
-
- The script editor's color for the code folding icon (displayed in the gutter).
-
-
- The script editor's comment color.
- [b]Note:[/b] In GDScript, unlike Python, multiline strings are not considered to be comments, and will use the string highlighting color instead.
-
-
- The script editor's autocompletion box background color.
-
-
- The script editor's autocompletion box background color to highlight existing characters in the completion results. This should be a translucent color so that [member text_editor/highlighting/completion_selected_color] can be seen behind.
-
-
- The script editor's autocompletion box text color.
-
-
- The script editor's autocompletion box scroll bar color.
-
-
- The script editor's autocompletion box background color for the currently selected line.
-
-
- The script editor's control flow keyword color (used for keywords like [code]if[/code], [code]for[/code], [code]return[/code], ...).
-
-
- The script editor's background color for the line the caret is currently on. This should be set to a translucent color so that it can display on top of other line color modifiers such as [member text_editor/highlighting/mark_color].
-
-
- The script editor's engine type color ([Vector2], [Vector3], [Color], ...).
-
-
- The script editor's color for the debugger's executing line icon (displayed in the gutter).
-
-
- The script editor's function call color.
- [b]Note:[/b] When using the GDScript syntax highlighter, this is replaced by the function definition color configured in the syntax theme for function definitions (e.g. [code]func _ready():[/code]).
-
-
- If [code]true[/code], highlights all occurrences of the currently selected text in the script editor. See also [member text_editor/highlighting/word_highlighted_color].
-
-
- If [code]true[/code], colors the background of the line the caret is currently on with [member text_editor/highlighting/current_line_color].
-
-
- If [code]true[/code], highlights type-safe lines by displaying their line number color with [member text_editor/highlighting/safe_line_number_color] instead of [member text_editor/highlighting/line_number_color]. Type-safe lines are lines of code where the type of all variables is known at compile-time. These type-safe lines will run faster in Godot 4.0 and later thanks to typed instructions.
-
-
- The script editor's non-control flow keyword color (used for keywords like [code]var[/code], [code]func[/code], some built-in methods, ...).
-
-
- The script editor's color for the line length guideline. The "hard" line length guideline will be drawn with this color, whereas the "soft" line length guideline will be drawn with an opacity twice as low.
-
-
- The script editor's color for line numbers. See also [member text_editor/highlighting/safe_line_number_color].
-
-
- The script editor's background color for lines with errors. This should be set to a translucent color so that it can display on top of other line color modifiers such as [member text_editor/highlighting/current_line_color].
-
-
- The script editor's color for member variables on objects (e.g. [code]self.some_property[/code]).
- [b]Note:[/b] This color is not used for local variable declaration and access.
-
-
- The script editor's color for numbers (integer and floating-point).
-
-
- The script editor's color for type-safe line numbers. See also [member text_editor/highlighting/line_number_color].
- [b]Note:[/b] Only displayed if [member text_editor/highlighting/highlight_type_safe_lines] is [code]true[/code].
-
-
- The script editor's color for the border of search results. This border helps bring further attention to the search result. Set this color's opacity to 0 to disable the border.
-
-
- The script editor's background color for search results.
-
-
- The script editor's background color for the currently selected text.
-
-
- The script editor's color for strings (single-line and multi-line).
-
-
- The script editor's color for operators ([code]( ) [ ] { } + - * /[/code], ...).
-
-
- The script editor's color for text not highlighted by any syntax highlighting rule.
-
-
- The script editor's background color for text. This should be set to a translucent color so that it can display on top of other line color modifiers such as [member text_editor/highlighting/current_line_color].
-
-
- The script editor's color for user-defined types (using [code]class_name[/code]).
-
-
- The script editor's color for words highlighted by selecting them. Only visible if [member text_editor/highlighting/highlight_all_occurrences] is [code]true[/code].
-
-
- If [code]true[/code], automatically indents code when pressing the [kbd]Enter[/kbd] key based on blocks above the new line.
-
-
- If [code]true[/code], converts indentation to match the script editor's indentation settings when saving a script. See also [member text_editor/indent/type].
-
-
- If [code]true[/code], draws space characters as centered points.
-
-
- If [code]true[/code], draws tab characters as chevrons.
-
-
- When using tab indentation, determines the length of each tab. When using space indentation, determines how many spaces are inserted when pressing [kbd]Tab[/kbd] and when automatic indentation is performed.
-
-
- The indentation style to use (tabs or spaces).
- [b]Note:[/b] The [url=$DOCS_URL/getting_started/scripting/gdscript/gdscript_styleguide.html]GDScript style guide[/url] recommends using tabs for indentation. It is advised to change this setting only if you need to work on a project that currently uses spaces for indentation.
-
-
- If [code]true[/code], allows drag-and-dropping text in the script editor to move text. Disable this if you find yourself accidentally drag-and-dropping text in the script editor.
-
-
- The width of the minimap in the script editor (in pixels).
-
-
- If [code]true[/code], the mouse's additional side buttons will be usable to navigate in the script editor's file history. Set this to [code]false[/code] if you're using the side buttons for other purposes (such as a push-to-talk button in a VoIP program).
-
-
- If [code]true[/code], draws an overview of the script near the scroll bar. The minimap can be left-clicked to scroll directly to a location in an "absolute" manner.
-
-
- If [code]true[/code], allows scrolling in sub-line intervals and enables a smooth scrolling animation when using the mouse wheel to scroll.
- [b]Note:[/b] [member text_editor/navigation/smooth_scrolling] currently behaves poorly in projects where [member ProjectSettings.physics/common/physics_fps] has been increased significantly from its default value ([code]60[/code]). In this case, it is recommended to disable this setting.
-
-
- If [code]true[/code], prevents automatically switching between the Script and 2D/3D screens when selecting a node in the Scene tree dock.
-
-
- The number of pixels to scroll with every mouse wheel increment. Higher values make the script scroll by faster when using the mouse wheel.
- [b]Note:[/b] You can hold down [kbd]Alt[/kbd] while using the mouse wheel to temporarily scroll 5 times faster.
-
-
- If [code]true[/code], displays an overview of the current script's member variables and functions at the left of the script editor. See also [member text_editor/tools/sort_members_outline_alphabetically].
-
-
- The syntax theme to use in the script editor.
- You can save your own syntax theme from your current settings by using [b]File > Theme > Save As...[/b] at the top of the script editor. The syntax theme will then be available locally in the list of color themes.
- You can find additional syntax themes to install in the [url=https://github.com/godotengine/godot-syntax-themes]godot-syntax-themes[/url] repository.
-
-
- The space to add between lines (in pixels). Greater line spacing can help improve readability at the cost of displaying fewer lines on screen.
-
-
- If [code]true[/code], sorts the members outline (located at the left of the script editor) using alphabetical order. If [code]false[/code], sorts the members outline depending on the order in which members are found in the script.
- [b]Note:[/b] Only effective if [member text_editor/script_list/show_members_overview] is [code]true[/code].
-
-
-
-
-
- Emitted after any editor setting has changed.
-
-
-
-
-
- Emitted after any editor setting has changed. It's used by various editor plugins to update their visuals on theme changes or logic on configuration changes.
-
-
-
diff --git a/doc/classes/EditorSpatialGizmo.xml b/doc/classes/EditorSpatialGizmo.xml
deleted file mode 100644
index 894274d..0000000
--- a/doc/classes/EditorSpatialGizmo.xml
+++ /dev/null
@@ -1,213 +0,0 @@
-
-
-
- Gizmo for editing Spatial objects.
-
-
- Gizmo that is used for providing custom visualization and editing (handles and subgizmos) for Spatial objects. Can be overridden to create custom gizmos, but for simple gizmos creating a [EditorSpatialGizmoPlugin] is usually recommended.
-
-
-
-
-
-
-
-
- Adds the specified [code]segments[/code] to the gizmo's collision shape for picking. Call this method during [method redraw].
-
-
-
-
-
-
- Adds collision triangles to the gizmo for picking. A [TriangleMesh] can be generated from a regular [Mesh] too. Call this method during [method redraw].
-
-
-
-
-
-
-
-
-
-
- Adds a list of handles (points) which can be used to edit the properties of the gizmo's Spatial. The [code]ids[/code] argument can be used to specify a custom identifier for each handle, if an empty [code]Array[/code] is passed, the ids will be assigned automatically from the [code]handles[/code] argument order.
- The [code]secondary[/code] argument marks the added handles as secondary, meaning they will normally have less selection priority than regular handles. When the user is holding the shift key secondary handles will switch to have higher priority than regular handles. This change in priority can be used to place multiple handles at the same point while still giving the user control on their selection.
- There are virtual methods which will be called upon editing of these handles. Call this method during [method _redraw].
-
-
-
-
-
-
-
-
-
- Adds lines to the gizmo (as sets of 2 points), with a given material. The lines are used for visualizing the gizmo. Call this method during [method redraw].
-
-
-
-
-
-
-
-
-
- Adds a mesh to the gizmo with the specified [code]material[/code], local [code]transform[/code] and [code]skeleton[/code]. Call this method during [method _redraw].
-
-
-
-
-
-
-
-
- Adds an unscaled billboard for visualization and selection. Call this method during [method _redraw].
-
-
-
-
-
- Removes everything in the gizmo including meshes, collisions and handles.
-
-
-
-
-
-
-
-
-
- Override this method to commit a handle being edited (handles must have been previously added by [method add_handles]). This usually means creating an [UndoRedo] action for the change, using the current handle value as "do" and the [code]restore[/code] argument as "undo".
- If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] value should be directly set, without any [UndoRedo] action.
- The [code]secondary[/code] argument is [code]true[/code] when the committed handle is secondary (see [method add_handles] for more information).
-
-
-
-
-
-
-
-
- Override this method to commit a group of subgizmos being edited (see [method _subgizmos_intersect_ray] and [method _subgizmos_intersect_frustum]). This usually means creating an [UndoRedo] action for the change, using the current transforms as "do" and the [code]restore[/code] transforms as "undo".
- If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] transforms should be directly set, without any [UndoRedo] action.
-
-
-
-
-
-
-
- Override this method to return the name of an edited handle (handles must have been previously added by [method add_handles]). Handles can be named for reference to the user when editing.
- The [code]secondary[/code] argument is [code]true[/code] when the requested handle is secondary (see [method add_handles] for more information).
-
-
-
-
-
-
-
- Override this method to return the current value of a handle. This value will be requested at the start of an edit and used as the [code]restore[/code] argument in [method _commit_handle].
- The [code]secondary[/code] argument is [code]true[/code] when the requested handle is secondary (see [method add_handles] for more information).
-
-
-
-
-
- Returns the [EditorSpatialGizmoPlugin] that owns this gizmo. It's useful to retrieve materials using [method EditorSpatialGizmoPlugin.get_material].
-
-
-
-
-
- Returns the Spatial node associated with this gizmo.
-
-
-
-
-
- Returns a list of the currently selected subgizmos. Can be used to highlight selected elements during [method _redraw].
-
-
-
-
-
-
- Override this method to return the current transform of a subgizmo. This transform will be requested at the start of an edit and used as the [code]restore[/code] argument in [method _commit_subgizmos].
-
-
-
-
-
-
-
- Override this method to return [code]true[/code] whenever the given handle should be highlighted in the editor.
- The [code]secondary[/code] argument is [code]true[/code] when the requested handle is secondary (see [method add_handles] for more information).
-
-
-
-
-
-
- Returns [code]true[/code] if the given subgizmo is currently selected. Can be used to highlight selected elements during [method _redraw].
-
-
-
-
-
- Override this method to add all the gizmo elements whenever a gizmo update is requested. It's common to call [method clear] at the beginning of this method and then add visual elements depending on the node's properties.
-
-
-
-
-
-
-
-
-
- Override this method to update the node properties when the user drags a gizmo handle (previously added with [method add_handles]). The provided [code]point[/code] is the mouse position in screen coordinates and the [code]camera[/code] can be used to convert it to raycasts.
- The [code]secondary[/code] argument is [code]true[/code] when the edited handle is secondary (see [method add_handles] for more information).
-
-
-
-
-
-
- Sets the gizmo's hidden state. If [code]true[/code], the gizmo will be hidden. If [code]false[/code], it will be shown.
-
-
-
-
-
-
- Sets the reference [Spatial] node for the gizmo. [code]node[/code] must inherit from [Spatial].
-
-
-
-
-
-
-
- Override this method to update the node properties during subgizmo editing (see [method _subgizmos_intersect_ray] and [method _subgizmos_intersect_frustum]). The [code]transform[/code] is given in the Spatial's local coordinate system.
-
-
-
-
-
-
-
- Override this method to allow selecting subgizmos using mouse drag box selection. Given a [code]camera[/code] and a [code]frustum[/code], this method should return which subgizmos are contained within the frustum. The [code]frustum[/code] argument consists of an [code]Array[/code] with all the [code]Plane[/code]s that make up the selection frustum. The returned value should contain a list of unique subgizmo identifiers, which can have any non-negative value and will be used in other virtual methods like [method _get_subgizmo_transform] or [method _commit_subgizmos].
-
-
-
-
-
-
-
- Override this method to allow selecting subgizmos using mouse clicks. Given a [code]camera[/code] and a [code]point[/code] in screen coordinates, this method should return which subgizmo should be selected. The returned value should be a unique subgizmo identifier, which can have any non-negative value and will be used in other virtual methods like [method _get_subgizmo_transform] or [method _commit_subgizmos].
-
-
-
-
-
-
diff --git a/doc/classes/EditorSpatialGizmoPlugin.xml b/doc/classes/EditorSpatialGizmoPlugin.xml
deleted file mode 100644
index 499ed3e..0000000
--- a/doc/classes/EditorSpatialGizmoPlugin.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-
-
-
- Used by the editor to define Spatial gizmo types.
-
-
- [EditorSpatialGizmoPlugin] allows you to define a new type of Gizmo. There are two main ways to do so: extending [EditorSpatialGizmoPlugin] for the simpler gizmos, or creating a new [EditorSpatialGizmo] type. See the tutorial in the documentation for more info.
- To use [EditorSpatialGizmoPlugin], register it using the [method EditorPlugin.add_spatial_gizmo_plugin] method first.
-
-
- $DOCS_URL/tutorials/plugins/editor/spatial_gizmos.md
-
-
-
-
-
-
-
- Adds a new material to the internal material list for the plugin. It can then be accessed with [method get_material]. Should not be overridden.
-
-
-
-
-
- Override this method to define whether the gizmos handled by this plugin can be hidden or not. Returns [code]true[/code] if not overridden.
-
-
-
-
-
-
-
-
-
-
- Override this method to commit a handle being edited (handles must have been previously added by [method EditorSpatialGizmo.add_handles] during [method _redraw]). This usually means creating an [UndoRedo] action for the change, using the current handle value as "do" and the [code]restore[/code] argument as "undo".
- If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] value should be directly set, without any [UndoRedo] action.
- The [code]secondary[/code] argument is [code]true[/code] when the committed handle is secondary (see [method EditorSpatialGizmo.add_handles] for more information).
- Called for this plugin's active gizmos.
-
-
-
-
-
-
-
-
-
- Override this method to commit a group of subgizmos being edited (see [method _subgizmos_intersect_ray] and [method _subgizmos_intersect_frustum]). This usually means creating an [UndoRedo] action for the change, using the current transforms as "do" and the [code]restore[/code] transforms as "undo".
- If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] transforms should be directly set, without any [UndoRedo] action. As with all subgizmo methods, transforms are given in local space respect to the gizmo's Spatial. Called for this plugin's active gizmos.
-
-
-
-
-
-
- Override this method to return a custom [EditorSpatialGizmo] for the spatial nodes of your choice, return [code]null[/code] for the rest of nodes. See also [method has_gizmo].
-
-
-
-
-
-
-
-
- Creates a handle material with its variants (selected and/or editable) and adds them to the internal material list. They can then be accessed with [method get_material] and used in [method EditorSpatialGizmo.add_handles]. Should not be overridden.
- You can optionally provide a texture to use instead of the default icon.
-
-
-
-
-
-
-
-
-
- Creates an icon material with its variants (selected and/or editable) and adds them to the internal material list. They can then be accessed with [method get_material] and used in [method EditorSpatialGizmo.add_unscaled_billboard]. Should not be overridden.
-
-
-
-
-
-
-
-
-
-
- Creates an unshaded material with its variants (selected and/or editable) and adds them to the internal material list. They can then be accessed with [method get_material] and used in [method EditorSpatialGizmo.add_mesh] and [method EditorSpatialGizmo.add_lines]. Should not be overridden.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Override this method to provide gizmo's handle names. The [code]secondary[/code] argument is [code]true[/code] when the requested handle is secondary (see [method EditorSpatialGizmo.add_handles] for more information). Called for this plugin's active gizmos.
-
-
-
-
-
-
-
-
- Override this method to return the current value of a handle. This value will be requested at the start of an edit and used as the [code]restore[/code] argument in [method _commit_handle].
- The [code]secondary[/code] argument is [code]true[/code] when the requested handle is secondary (see [method EditorSpatialGizmo.add_handles] for more information).
- Called for this plugin's active gizmos.
-
-
-
-
-
-
-
- Gets material from the internal list of materials. If an [EditorSpatialGizmo] is provided, it will try to get the corresponding variant (selected and/or editable).
-
-
-
-
-
- Override this method to set the gizmo's priority. Gizmos with higher priority will have precedence when processing inputs like handles or subgizmos selection.
- All built-in editor gizmos return a priority of [code]-1[/code]. If not overridden, this method will return [code]0[/code], which means custom gizmos will automatically get higher priority than built-in gizmos.
-
-
-
-
-
-
-
- Override this method to return the current transform of a subgizmo. As with all subgizmo methods, the transform should be in local space respect to the gizmo's Spatial. This transform will be requested at the start of an edit and used in the [code]restore[/code] argument in [method _commit_subgizmos]. Called for this plugin's active gizmos.
-
-
-
-
-
-
- Override this method to define which Spatial nodes have a gizmo from this plugin. Whenever a [Spatial] node is added to a scene this method is called, if it returns [code]true[/code] the node gets a generic [EditorSpatialGizmo] assigned and is added to this plugin's list of active gizmos.
-
-
-
-
-
-
-
-
- Override this method to return [code]true[/code] whenever to given handle should be highlighted in the editor. The [code]secondary[/code] argument is [code]true[/code] when the requested handle is secondary (see [method EditorSpatialGizmo.add_handles] for more information). Called for this plugin's active gizmos.
-
-
-
-
-
- Override this method to define whether a Spatial with this gizmo should be selectable even when the gizmo is hidden.
-
-
-
-
-
-
- Override this method to add all the gizmo elements whenever a gizmo update is requested. It's common to call [method EditorSpatialGizmo.clear] at the beginning of this method and then add visual elements depending on the node's properties.
-
-
-
-
-
-
-
-
-
-
- Override this method to update the node's properties when the user drags a gizmo handle (previously added with [method EditorSpatialGizmo.add_handles]). The provided [code]point[/code] is the mouse position in screen coordinates and the [code]camera[/code] can be used to convert it to raycasts.
- The [code]secondary[/code] argument is [code]true[/code] when the edited handle is secondary (see [method EditorSpatialGizmo.add_handles] for more information).
- Called for this plugin's active gizmos.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/classes/EditorSpinSlider.xml b/doc/classes/EditorSpinSlider.xml
deleted file mode 100644
index b5d0257..0000000
--- a/doc/classes/EditorSpinSlider.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
- Godot editor's control for editing numeric values.
-
-
- This [Control] node is used in the editor's Inspector dock to allow editing of numeric values. Can be used with [EditorInspectorPlugin] to recreate the same behavior.
-
-
-
-
-
-
-
-
-
-
- If [code]true[/code], the slider is hidden.
-
-
-
-
-
-
-
-
-
-
-
diff --git a/modules/navigation_mesh_generator/pandemonium_navigation_mesh_generator.cpp b/modules/navigation_mesh_generator/pandemonium_navigation_mesh_generator.cpp
index f5bc76c..a2fd513 100644
--- a/modules/navigation_mesh_generator/pandemonium_navigation_mesh_generator.cpp
+++ b/modules/navigation_mesh_generator/pandemonium_navigation_mesh_generator.cpp
@@ -38,10 +38,6 @@
#include "scene/resources/navigation/navigation_mesh.h"
#include "scene/resources/navigation_2d/navigation_mesh_source_geometry_data_2d.h"
-#ifndef _3D_DISABLED
-#include "scene/3d/mesh_instance.h"
-#endif // _3D_DISABLED
-
#ifndef _3D_DISABLED
#include
#endif // _3D_DISABLED
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp
index 76d521b..d9dd0ab 100644
--- a/scene/2d/area_2d.cpp
+++ b/scene/2d/area_2d.cpp
@@ -29,7 +29,6 @@
/*************************************************************************/
#include "area_2d.h"
-#include "scene/resources/world_3d.h"
#include "scene/main/scene_string_names.h"
#include "servers/audio_server.h"
#include "servers/physics_2d_server.h"
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index 0095225..608ebf2 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -43,10 +43,6 @@ void Camera2D::_update_scroll() {
if (Engine::get_singleton()->is_editor_hint()) {
update();
- // Only set viewport transform when not bound to the main viewport.
- if (get_viewport() == get_tree()->get_edited_scene_root()->get_viewport()) {
- return;
- }
}
if (!viewport) {
diff --git a/scene/2d/listener_2d.cpp b/scene/2d/listener_2d.cpp
index 689e467..ed6ab9c 100644
--- a/scene/2d/listener_2d.cpp
+++ b/scene/2d/listener_2d.cpp
@@ -47,7 +47,7 @@ bool Listener2D::_set(const StringName &p_name, const Variant &p_value) {
bool Listener2D::_get(const StringName &p_name, Variant &r_ret) const {
if (p_name == "current") {
- if (is_inside_tree() && get_tree()->is_node_being_edited(this)) {
+ if (is_inside_tree()) {
r_ret = current;
} else {
r_ret = is_current();
@@ -65,18 +65,14 @@ void Listener2D::_get_property_list(List *p_list) const {
void Listener2D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
- if (!get_tree()->is_node_being_edited(this) && current) {
- make_current();
- }
+ make_current();
} break;
case NOTIFICATION_EXIT_TREE: {
- if (!get_tree()->is_node_being_edited(this)) {
- if (is_current()) {
- clear_current();
- current = true; // Keep it true.
- } else {
- current = false;
- }
+ if (is_current()) {
+ clear_current();
+ current = true; // Keep it true.
+ } else {
+ current = false;
}
} break;
}
@@ -99,7 +95,7 @@ void Listener2D::clear_current() {
}
bool Listener2D::is_current() const {
- if (is_inside_tree() && !get_tree()->is_node_being_edited(this)) {
+ if (is_inside_tree()) {
return get_viewport()->get_listener_2d() == this;
} else {
return current;
diff --git a/scene/3d/SCsub b/scene/3d/SCsub
deleted file mode 100644
index a382b0c..0000000
--- a/scene/3d/SCsub
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env python
-
-Import("env")
-
-if env["disable_3d"]:
- env.add_source_files(env.scene_sources, "spatial.cpp")
- env.add_source_files(env.scene_sources, "skeleton.cpp")
- env.add_source_files(env.scene_sources, "particles.cpp")
- env.add_source_files(env.scene_sources, "visual_instance.cpp")
- env.add_source_files(env.scene_sources, "world_environment.cpp")
-else:
- env.add_source_files(env.scene_sources, "*.cpp")
diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp
deleted file mode 100644
index 514d9c9..0000000
--- a/scene/3d/audio_stream_player_3d.cpp
+++ /dev/null
@@ -1,808 +0,0 @@
-/*************************************************************************/
-/* audio_stream_player_3d.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "audio_stream_player_3d.h"
-#include "core/config/engine.h"
-#include "core/config/project_settings.h"
-#include "scene/3d/camera.h"
-#include "scene/3d/listener.h"
-#include "scene/3d/spatial_velocity_tracker.h"
-#include "scene/main/viewport.h"
-#include "servers/audio/audio_stream.h"
-
-// Based on "A Novel Multichannel Panning Method for Standard and Arbitrary Loudspeaker Configurations" by Ramy Sadek and Chris Kyriakakis (2004)
-// Speaker-Placement Correction Amplitude Panning (SPCAP)
-class Spcap {
-private:
- struct Speaker {
- Vector3 direction;
- real_t effective_number_of_speakers; // precalculated
- mutable real_t squared_gain; // temporary
- };
-
- PoolVector speakers;
-
-public:
- Spcap(unsigned int speaker_count, const Vector3 *speaker_directions) {
- this->speakers.resize(speaker_count);
- PoolVector::Write w = this->speakers.write();
- for (unsigned int speaker_num = 0; speaker_num < speaker_count; speaker_num++) {
- w[speaker_num].direction = speaker_directions[speaker_num];
- w[speaker_num].squared_gain = 0.0;
- w[speaker_num].effective_number_of_speakers = 0.0;
- for (unsigned int other_speaker_num = 0; other_speaker_num < speaker_count; other_speaker_num++) {
- w[speaker_num].effective_number_of_speakers += 0.5 * (1.0 + w[speaker_num].direction.dot(w[other_speaker_num].direction));
- }
- }
- }
-
- unsigned int get_speaker_count() const {
- return (unsigned int)this->speakers.size();
- }
-
- Vector3 get_speaker_direction(unsigned int index) const {
- return this->speakers.read()[index].direction;
- }
-
- void calculate(const Vector3 &source_direction, real_t tightness, unsigned int volume_count, real_t *volumes) const {
- PoolVector::Read r = this->speakers.read();
- real_t sum_squared_gains = 0.0;
- for (unsigned int speaker_num = 0; speaker_num < (unsigned int)this->speakers.size(); speaker_num++) {
- real_t initial_gain = 0.5 * powf(1.0 + r[speaker_num].direction.dot(source_direction), tightness) / r[speaker_num].effective_number_of_speakers;
- r[speaker_num].squared_gain = initial_gain * initial_gain;
- sum_squared_gains += r[speaker_num].squared_gain;
- }
-
- for (unsigned int speaker_num = 0; speaker_num < MIN(volume_count, (unsigned int)this->speakers.size()); speaker_num++) {
- volumes[speaker_num] = sqrtf(r[speaker_num].squared_gain / sum_squared_gains);
- }
- }
-};
-
-//TODO: hardcoded main speaker directions for 2, 3.1, 5.1 and 7.1 setups - these are simplified and could also be made configurable
-static const Vector3 speaker_directions[7] = {
- Vector3(-1.0, 0.0, -1.0).normalized(), // front-left
- Vector3(1.0, 0.0, -1.0).normalized(), // front-right
- Vector3(0.0, 0.0, -1.0).normalized(), // center
- Vector3(-1.0, 0.0, 1.0).normalized(), // rear-left
- Vector3(1.0, 0.0, 1.0).normalized(), // rear-right
- Vector3(-1.0, 0.0, 0.0).normalized(), // side-left
- Vector3(1.0, 0.0, 0.0).normalized(), // side-right
-};
-
-void AudioStreamPlayer3D::_calc_output_vol(const Vector3 &source_dir, real_t tightness, AudioStreamPlayer3D::Output &output) {
- unsigned int speaker_count; // only main speakers (no LFE)
- switch (AudioServer::get_singleton()->get_speaker_mode()) {
- default: //fallthrough
- case AudioServer::SPEAKER_MODE_STEREO:
- speaker_count = 2;
- break;
- case AudioServer::SPEAKER_SURROUND_31:
- speaker_count = 3;
- break;
- case AudioServer::SPEAKER_SURROUND_51:
- speaker_count = 5;
- break;
- case AudioServer::SPEAKER_SURROUND_71:
- speaker_count = 7;
- break;
- }
-
- Spcap spcap(speaker_count, speaker_directions); //TODO: should only be created/recreated once the speaker mode / speaker positions changes
- real_t volumes[7];
- spcap.calculate(source_dir, tightness, speaker_count, volumes);
-
- switch (AudioServer::get_singleton()->get_speaker_mode()) {
- case AudioServer::SPEAKER_SURROUND_71:
- output.vol[3].l = volumes[5]; // side-left
- output.vol[3].r = volumes[6]; // side-right
- //fallthrough
- case AudioServer::SPEAKER_SURROUND_51:
- output.vol[2].l = volumes[3]; // rear-left
- output.vol[2].r = volumes[4]; // rear-right
- //fallthrough
- case AudioServer::SPEAKER_SURROUND_31:
- output.vol[1].r = 1.0; // LFE - always full power
- output.vol[1].l = volumes[2]; // center
- //fallthrough
- case AudioServer::SPEAKER_MODE_STEREO:
- output.vol[0].r = volumes[1]; // front-right
- output.vol[0].l = volumes[0]; // front-left
- }
-}
-
-void AudioStreamPlayer3D::_mix_audio() {
- if (!stream_playback.is_valid() || !active.is_set() ||
- (stream_paused && !stream_paused_fade_out)) {
- return;
- }
-
- bool started = false;
- if (setseek.get() >= 0.0) {
- stream_playback->start(setseek.get());
- setseek.set(-1.0); //reset seek
- started = true;
- }
-
- //get data
- AudioFrame *buffer = mix_buffer.ptrw();
- int buffer_size = mix_buffer.size();
-
- if (stream_paused_fade_out) {
- // Short fadeout ramp
- buffer_size = MIN(buffer_size, 128);
- }
-
- // Mix if we're not paused or we're fading out
- if ((output_count.get() > 0 || out_of_range_mode == OUT_OF_RANGE_MIX)) {
- float output_pitch_scale = 0.0;
- if (output_count.get()) {
- //used for doppler, not realistic but good enough
- for (int i = 0; i < output_count.get(); i++) {
- output_pitch_scale += outputs[i].pitch_scale;
- }
- output_pitch_scale /= float(output_count.get());
- } else {
- output_pitch_scale = 1.0;
- }
-
- stream_playback->mix(buffer, pitch_scale * output_pitch_scale, buffer_size);
- }
-
- //write all outputs
- for (int i = 0; i < output_count.get(); i++) {
- Output current = outputs[i];
-
- //see if current output exists, to keep volume ramp
- bool found = false;
- for (int j = i; j < prev_output_count; j++) {
- if (prev_outputs[j].viewport == current.viewport) {
- if (j != i) {
- SWAP(prev_outputs[j], prev_outputs[i]);
- }
- found = true;
- break;
- }
- }
-
- bool interpolate_filter = !started;
-
- if (!found) {
- //create new if was not used before
- if (prev_output_count < MAX_OUTPUTS) {
- prev_outputs[prev_output_count] = prev_outputs[i]; //may be owned by another viewport
- prev_output_count++;
- }
- prev_outputs[i] = current;
- interpolate_filter = false;
- }
-
- //mix!
-
- int buffers = AudioServer::get_singleton()->get_channel_count();
-
- for (int k = 0; k < buffers; k++) {
- AudioFrame target_volume = stream_paused_fade_out ? AudioFrame(0.f, 0.f) : current.vol[k];
- AudioFrame vol_prev = stream_paused_fade_in ? AudioFrame(0.f, 0.f) : prev_outputs[i].vol[k];
- AudioFrame vol_inc = (target_volume - vol_prev) / float(buffer_size);
- AudioFrame vol = vol_prev;
-
- if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.bus_index, k)) {
- continue; //may have been deleted, will be updated on process
- }
-
- AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, k);
- current.filter.set_mode(AudioFilterSW::HIGHSHELF);
- current.filter.set_sampling_rate(AudioServer::get_singleton()->get_mix_rate());
- current.filter.set_cutoff(attenuation_filter_cutoff_hz);
- current.filter.set_resonance(1);
- current.filter.set_stages(1);
- current.filter.set_gain(current.filter_gain);
-
- if (interpolate_filter) {
- current.filter_process[k * 2 + 0] = prev_outputs[i].filter_process[k * 2 + 0];
- current.filter_process[k * 2 + 1] = prev_outputs[i].filter_process[k * 2 + 1];
-
- current.filter_process[k * 2 + 0].set_filter(¤t.filter, false);
- current.filter_process[k * 2 + 1].set_filter(¤t.filter, false);
-
- current.filter_process[k * 2 + 0].update_coeffs(buffer_size);
- current.filter_process[k * 2 + 1].update_coeffs(buffer_size);
- for (int j = 0; j < buffer_size; j++) {
- AudioFrame f = buffer[j] * vol;
- current.filter_process[k * 2 + 0].process_one_interp(f.l);
- current.filter_process[k * 2 + 1].process_one_interp(f.r);
-
- target[j] += f;
- vol += vol_inc;
- }
- } else {
- current.filter_process[k * 2 + 0].set_filter(¤t.filter);
- current.filter_process[k * 2 + 1].set_filter(¤t.filter);
-
- current.filter_process[k * 2 + 0].update_coeffs();
- current.filter_process[k * 2 + 1].update_coeffs();
- for (int j = 0; j < buffer_size; j++) {
- AudioFrame f = buffer[j] * vol;
- current.filter_process[k * 2 + 0].process_one(f.l);
- current.filter_process[k * 2 + 1].process_one(f.r);
-
- target[j] += f;
- vol += vol_inc;
- }
- }
-
- if (current.reverb_bus_index >= 0) {
- if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.reverb_bus_index, k)) {
- continue; //may have been deleted, will be updated on process
- }
-
- AudioFrame *rtarget = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.reverb_bus_index, k);
-
- if (current.reverb_bus_index == prev_outputs[i].reverb_bus_index) {
- AudioFrame rvol_inc = (current.reverb_vol[k] - prev_outputs[i].reverb_vol[k]) / float(buffer_size);
- AudioFrame rvol = prev_outputs[i].reverb_vol[k];
-
- for (int j = 0; j < buffer_size; j++) {
- rtarget[j] += buffer[j] * rvol;
- rvol += rvol_inc;
- }
- } else {
- AudioFrame rvol = current.reverb_vol[k];
- for (int j = 0; j < buffer_size; j++) {
- rtarget[j] += buffer[j] * rvol;
- }
- }
- }
- }
-
- prev_outputs[i] = current;
- }
-
- prev_output_count = output_count.get();
-
- //stream is no longer active, disable this.
- if (!stream_playback->is_playing()) {
- active.clear();
- }
-
- output_ready.clear();
- stream_paused_fade_in = false;
- stream_paused_fade_out = false;
-}
-
-float AudioStreamPlayer3D::_get_attenuation_db(float p_distance) const {
- float att = 0;
- switch (attenuation_model) {
- case ATTENUATION_INVERSE_DISTANCE: {
- att = Math::linear2db(1.0 / ((p_distance / unit_size) + CMP_EPSILON));
- } break;
- case ATTENUATION_INVERSE_SQUARE_DISTANCE: {
- float d = (p_distance / unit_size);
- d *= d;
- att = Math::linear2db(1.0 / (d + CMP_EPSILON));
- } break;
- case ATTENUATION_LOGARITHMIC: {
- att = -20 * Math::log(p_distance / unit_size + CMP_EPSILON);
- } break;
- case ATTENUATION_DISABLED:
- break;
- default: {
- ERR_PRINT("Unknown attenuation type");
- break;
- }
- }
-
- att += unit_db;
- if (att > max_db) {
- att = max_db;
- }
-
- return att;
-}
-
-void _update_sound() {
-}
-
-void AudioStreamPlayer3D::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE) {
- velocity_tracker->reset(get_global_transform().origin);
- AudioServer::get_singleton()->add_callback(_mix_audios, this);
- if (autoplay && !Engine::get_singleton()->is_editor_hint()) {
- play();
- }
- }
-
- if (p_what == NOTIFICATION_EXIT_TREE) {
- AudioServer::get_singleton()->remove_callback(_mix_audios, this);
- }
-
- if (p_what == NOTIFICATION_PAUSED) {
- if (!can_process()) {
- // Node can't process so we start fading out to silence
- set_stream_paused(true);
- }
- }
-
- if (p_what == NOTIFICATION_UNPAUSED) {
- set_stream_paused(false);
- }
-
- if (p_what == NOTIFICATION_TRANSFORM_CHANGED) {
- if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
- velocity_tracker->update_position(get_global_transform().origin);
- }
- }
-
- //start playing if requested
- if (setplay.get() >= 0.0) {
- setseek.set(setplay.get());
- active.set();
- setplay.set(-1);
- //do not update, this makes it easier to animate (will shut off otherwise)
- ///_change_notify("playing"); //update property in editor
- }
-
- //stop playing if no longer active
- if (!active.is_set()) {
- set_physics_process_internal(false);
- //do not update, this makes it easier to animate (will shut off otherwise)
- //_change_notify("playing"); //update property in editor
- emit_signal("finished");
- }
-}
-
-void AudioStreamPlayer3D::set_stream(Ref p_stream) {
- // Instancing audio streams can cause large memory allocations, do it prior to AudioServer::lock.
- Ref pre_instanced_playback;
- if (p_stream.is_valid()) {
- pre_instanced_playback = p_stream->instance_playback();
- }
-
- AudioServer::get_singleton()->lock();
-
- mix_buffer.resize(AudioServer::get_singleton()->thread_get_mix_buffer_size());
-
- if (stream_playback.is_valid()) {
- stream_playback.unref();
- stream.unref();
- active.clear();
- setseek.set(-1);
- }
-
- if (p_stream.is_valid()) {
- stream = p_stream;
- stream_playback = pre_instanced_playback;
- }
-
- AudioServer::get_singleton()->unlock();
-
- if (p_stream.is_valid() && stream_playback.is_null()) {
- stream.unref();
- }
-}
-
-Ref AudioStreamPlayer3D::get_stream() const {
- return stream;
-}
-
-void AudioStreamPlayer3D::set_unit_db(float p_volume) {
- unit_db = p_volume;
-}
-float AudioStreamPlayer3D::get_unit_db() const {
- return unit_db;
-}
-
-void AudioStreamPlayer3D::set_unit_size(float p_volume) {
- unit_size = p_volume;
-}
-float AudioStreamPlayer3D::get_unit_size() const {
- return unit_size;
-}
-
-void AudioStreamPlayer3D::set_max_db(float p_boost) {
- max_db = p_boost;
-}
-float AudioStreamPlayer3D::get_max_db() const {
- return max_db;
-}
-
-void AudioStreamPlayer3D::set_pitch_scale(float p_pitch_scale) {
- ERR_FAIL_COND(!(p_pitch_scale > 0.0));
- pitch_scale = p_pitch_scale;
-}
-float AudioStreamPlayer3D::get_pitch_scale() const {
- return pitch_scale;
-}
-
-void AudioStreamPlayer3D::play(float p_from_pos) {
- if (!is_playing()) {
- // Reset the prev_output_count if the stream is stopped
- prev_output_count = 0;
- }
-
- if (stream_playback.is_valid()) {
- setplay.set(p_from_pos);
- output_ready.clear();
- set_physics_process_internal(true);
- }
-}
-
-void AudioStreamPlayer3D::seek(float p_seconds) {
- if (stream_playback.is_valid()) {
- setseek.set(p_seconds);
- }
-}
-
-void AudioStreamPlayer3D::stop() {
- if (stream_playback.is_valid()) {
- active.clear();
- set_physics_process_internal(false);
- setplay.set(-1);
- }
-}
-
-bool AudioStreamPlayer3D::is_playing() const {
- if (stream_playback.is_valid()) {
- return active.is_set() || setplay.get() >= 0;
- }
-
- return false;
-}
-
-float AudioStreamPlayer3D::get_playback_position() {
- if (stream_playback.is_valid()) {
- float ss = setseek.get();
- if (ss >= 0.0) {
- return ss;
- }
- return stream_playback->get_playback_position();
- }
-
- return 0;
-}
-
-void AudioStreamPlayer3D::set_bus(const StringName &p_bus) {
- //if audio is active, must lock this
- AudioServer::get_singleton()->lock();
- bus = p_bus;
- AudioServer::get_singleton()->unlock();
-}
-StringName AudioStreamPlayer3D::get_bus() const {
- for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
- if (AudioServer::get_singleton()->get_bus_name(i) == bus) {
- return bus;
- }
- }
- return "Master";
-}
-
-void AudioStreamPlayer3D::set_autoplay(bool p_enable) {
- autoplay = p_enable;
-}
-bool AudioStreamPlayer3D::is_autoplay_enabled() {
- return autoplay;
-}
-
-void AudioStreamPlayer3D::_set_playing(bool p_enable) {
- if (p_enable) {
- play();
- } else {
- stop();
- }
-}
-bool AudioStreamPlayer3D::_is_active() const {
- return active.is_set();
-}
-
-void AudioStreamPlayer3D::_validate_property(PropertyInfo &property) const {
- if (property.name == "bus") {
- String options;
- for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
- if (i > 0) {
- options += ",";
- }
- String name = AudioServer::get_singleton()->get_bus_name(i);
- options += name;
- }
-
- property.hint_string = options;
- }
-}
-
-void AudioStreamPlayer3D::_bus_layout_changed() {
- _change_notify();
-}
-
-void AudioStreamPlayer3D::set_max_distance(float p_metres) {
- ERR_FAIL_COND(p_metres < 0.0);
- max_distance = p_metres;
-}
-
-float AudioStreamPlayer3D::get_max_distance() const {
- return max_distance;
-}
-
-void AudioStreamPlayer3D::set_area_mask(uint32_t p_mask) {
- area_mask = p_mask;
-}
-
-uint32_t AudioStreamPlayer3D::get_area_mask() const {
- return area_mask;
-}
-
-void AudioStreamPlayer3D::set_emission_angle_enabled(bool p_enable) {
- emission_angle_enabled = p_enable;
- update_gizmos();
-}
-
-bool AudioStreamPlayer3D::is_emission_angle_enabled() const {
- return emission_angle_enabled;
-}
-
-void AudioStreamPlayer3D::set_emission_angle(float p_angle) {
- ERR_FAIL_COND(p_angle < 0 || p_angle > 90);
- emission_angle = p_angle;
- update_gizmos();
- _change_notify("emission_angle");
-}
-
-float AudioStreamPlayer3D::get_emission_angle() const {
- return emission_angle;
-}
-
-void AudioStreamPlayer3D::set_emission_angle_filter_attenuation_db(float p_angle_attenuation_db) {
- emission_angle_filter_attenuation_db = p_angle_attenuation_db;
-}
-
-float AudioStreamPlayer3D::get_emission_angle_filter_attenuation_db() const {
- return emission_angle_filter_attenuation_db;
-}
-
-void AudioStreamPlayer3D::set_attenuation_filter_cutoff_hz(float p_hz) {
- attenuation_filter_cutoff_hz = p_hz;
-}
-float AudioStreamPlayer3D::get_attenuation_filter_cutoff_hz() const {
- return attenuation_filter_cutoff_hz;
-}
-
-void AudioStreamPlayer3D::set_attenuation_filter_db(float p_db) {
- attenuation_filter_db = p_db;
-}
-float AudioStreamPlayer3D::get_attenuation_filter_db() const {
- return attenuation_filter_db;
-}
-
-void AudioStreamPlayer3D::set_attenuation_model(AttenuationModel p_model) {
- ERR_FAIL_INDEX((int)p_model, 4);
- attenuation_model = p_model;
-}
-
-AudioStreamPlayer3D::AttenuationModel AudioStreamPlayer3D::get_attenuation_model() const {
- return attenuation_model;
-}
-
-void AudioStreamPlayer3D::set_out_of_range_mode(OutOfRangeMode p_mode) {
- ERR_FAIL_INDEX((int)p_mode, 2);
- out_of_range_mode = p_mode;
-}
-
-AudioStreamPlayer3D::OutOfRangeMode AudioStreamPlayer3D::get_out_of_range_mode() const {
- return out_of_range_mode;
-}
-
-void AudioStreamPlayer3D::set_doppler_tracking(DopplerTracking p_tracking) {
- if (doppler_tracking == p_tracking) {
- return;
- }
-
- doppler_tracking = p_tracking;
-
- if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
- set_notify_transform(true);
- velocity_tracker->set_track_physics_step(doppler_tracking == DOPPLER_TRACKING_PHYSICS_STEP);
- if (is_inside_tree()) {
- velocity_tracker->reset(get_global_transform().origin);
- }
- } else {
- set_notify_transform(false);
- }
-}
-
-AudioStreamPlayer3D::DopplerTracking AudioStreamPlayer3D::get_doppler_tracking() const {
- return doppler_tracking;
-}
-
-void AudioStreamPlayer3D::set_stream_paused(bool p_pause) {
- if (p_pause != stream_paused) {
- stream_paused = p_pause;
- stream_paused_fade_in = !stream_paused;
- stream_paused_fade_out = stream_paused;
- }
-}
-
-bool AudioStreamPlayer3D::get_stream_paused() const {
- return stream_paused;
-}
-
-Ref AudioStreamPlayer3D::get_stream_playback() {
- return stream_playback;
-}
-
-void AudioStreamPlayer3D::set_panning_strength(float p_panning_strength) {
- ERR_FAIL_COND_MSG(p_panning_strength < 0, "Panning strength must be a positive number.");
- panning_strength = p_panning_strength;
-}
-
-float AudioStreamPlayer3D::get_panning_strength() const {
- return panning_strength;
-}
-
-void AudioStreamPlayer3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_stream", "stream"), &AudioStreamPlayer3D::set_stream);
- ClassDB::bind_method(D_METHOD("get_stream"), &AudioStreamPlayer3D::get_stream);
-
- ClassDB::bind_method(D_METHOD("set_unit_db", "unit_db"), &AudioStreamPlayer3D::set_unit_db);
- ClassDB::bind_method(D_METHOD("get_unit_db"), &AudioStreamPlayer3D::get_unit_db);
-
- ClassDB::bind_method(D_METHOD("set_unit_size", "unit_size"), &AudioStreamPlayer3D::set_unit_size);
- ClassDB::bind_method(D_METHOD("get_unit_size"), &AudioStreamPlayer3D::get_unit_size);
-
- ClassDB::bind_method(D_METHOD("set_max_db", "max_db"), &AudioStreamPlayer3D::set_max_db);
- ClassDB::bind_method(D_METHOD("get_max_db"), &AudioStreamPlayer3D::get_max_db);
-
- ClassDB::bind_method(D_METHOD("set_pitch_scale", "pitch_scale"), &AudioStreamPlayer3D::set_pitch_scale);
- ClassDB::bind_method(D_METHOD("get_pitch_scale"), &AudioStreamPlayer3D::get_pitch_scale);
-
- ClassDB::bind_method(D_METHOD("play", "from_position"), &AudioStreamPlayer3D::play, DEFVAL(0.0));
- ClassDB::bind_method(D_METHOD("seek", "to_position"), &AudioStreamPlayer3D::seek);
- ClassDB::bind_method(D_METHOD("stop"), &AudioStreamPlayer3D::stop);
-
- ClassDB::bind_method(D_METHOD("is_playing"), &AudioStreamPlayer3D::is_playing);
- ClassDB::bind_method(D_METHOD("get_playback_position"), &AudioStreamPlayer3D::get_playback_position);
-
- ClassDB::bind_method(D_METHOD("set_bus", "bus"), &AudioStreamPlayer3D::set_bus);
- ClassDB::bind_method(D_METHOD("get_bus"), &AudioStreamPlayer3D::get_bus);
-
- ClassDB::bind_method(D_METHOD("set_autoplay", "enable"), &AudioStreamPlayer3D::set_autoplay);
- ClassDB::bind_method(D_METHOD("is_autoplay_enabled"), &AudioStreamPlayer3D::is_autoplay_enabled);
-
- ClassDB::bind_method(D_METHOD("_set_playing", "enable"), &AudioStreamPlayer3D::_set_playing);
- ClassDB::bind_method(D_METHOD("_is_active"), &AudioStreamPlayer3D::_is_active);
-
- ClassDB::bind_method(D_METHOD("set_max_distance", "metres"), &AudioStreamPlayer3D::set_max_distance);
- ClassDB::bind_method(D_METHOD("get_max_distance"), &AudioStreamPlayer3D::get_max_distance);
-
- ClassDB::bind_method(D_METHOD("set_area_mask", "mask"), &AudioStreamPlayer3D::set_area_mask);
- ClassDB::bind_method(D_METHOD("get_area_mask"), &AudioStreamPlayer3D::get_area_mask);
-
- ClassDB::bind_method(D_METHOD("set_emission_angle", "degrees"), &AudioStreamPlayer3D::set_emission_angle);
- ClassDB::bind_method(D_METHOD("get_emission_angle"), &AudioStreamPlayer3D::get_emission_angle);
-
- ClassDB::bind_method(D_METHOD("set_emission_angle_enabled", "enabled"), &AudioStreamPlayer3D::set_emission_angle_enabled);
- ClassDB::bind_method(D_METHOD("is_emission_angle_enabled"), &AudioStreamPlayer3D::is_emission_angle_enabled);
-
- ClassDB::bind_method(D_METHOD("set_emission_angle_filter_attenuation_db", "db"), &AudioStreamPlayer3D::set_emission_angle_filter_attenuation_db);
- ClassDB::bind_method(D_METHOD("get_emission_angle_filter_attenuation_db"), &AudioStreamPlayer3D::get_emission_angle_filter_attenuation_db);
-
- ClassDB::bind_method(D_METHOD("set_attenuation_filter_cutoff_hz", "degrees"), &AudioStreamPlayer3D::set_attenuation_filter_cutoff_hz);
- ClassDB::bind_method(D_METHOD("get_attenuation_filter_cutoff_hz"), &AudioStreamPlayer3D::get_attenuation_filter_cutoff_hz);
-
- ClassDB::bind_method(D_METHOD("set_attenuation_filter_db", "db"), &AudioStreamPlayer3D::set_attenuation_filter_db);
- ClassDB::bind_method(D_METHOD("get_attenuation_filter_db"), &AudioStreamPlayer3D::get_attenuation_filter_db);
-
- ClassDB::bind_method(D_METHOD("set_attenuation_model", "model"), &AudioStreamPlayer3D::set_attenuation_model);
- ClassDB::bind_method(D_METHOD("get_attenuation_model"), &AudioStreamPlayer3D::get_attenuation_model);
-
- ClassDB::bind_method(D_METHOD("set_out_of_range_mode", "mode"), &AudioStreamPlayer3D::set_out_of_range_mode);
- ClassDB::bind_method(D_METHOD("get_out_of_range_mode"), &AudioStreamPlayer3D::get_out_of_range_mode);
-
- ClassDB::bind_method(D_METHOD("set_doppler_tracking", "mode"), &AudioStreamPlayer3D::set_doppler_tracking);
- ClassDB::bind_method(D_METHOD("get_doppler_tracking"), &AudioStreamPlayer3D::get_doppler_tracking);
-
- ClassDB::bind_method(D_METHOD("set_stream_paused", "pause"), &AudioStreamPlayer3D::set_stream_paused);
- ClassDB::bind_method(D_METHOD("get_stream_paused"), &AudioStreamPlayer3D::get_stream_paused);
-
- ClassDB::bind_method(D_METHOD("set_panning_strength", "panning_strength"), &AudioStreamPlayer3D::set_panning_strength);
- ClassDB::bind_method(D_METHOD("get_panning_strength"), &AudioStreamPlayer3D::get_panning_strength);
-
- ClassDB::bind_method(D_METHOD("get_stream_playback"), &AudioStreamPlayer3D::get_stream_playback);
-
- ClassDB::bind_method(D_METHOD("_bus_layout_changed"), &AudioStreamPlayer3D::_bus_layout_changed);
-
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "attenuation_model", PROPERTY_HINT_ENUM, "Inverse,InverseSquare,Logarithmic,Disabled"), "set_attenuation_model", "get_attenuation_model");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_db", PROPERTY_HINT_RANGE, "-80,80"), "set_unit_db", "get_unit_db");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_size", PROPERTY_HINT_RANGE, "0.1,100,0.1"), "set_unit_size", "get_unit_size");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_db", PROPERTY_HINT_RANGE, "-24,6"), "set_max_db", "get_max_db");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "pitch_scale", PROPERTY_HINT_RANGE, "0.01,4,0.01,or_greater"), "set_pitch_scale", "get_pitch_scale");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "is_playing");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stream_paused", PROPERTY_HINT_NONE, ""), "set_stream_paused", "get_stream_paused");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_distance", PROPERTY_HINT_RANGE, "0,4096,0.01,or_greater"), "set_max_distance", "get_max_distance");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "out_of_range_mode", PROPERTY_HINT_ENUM, "Mix,Pause"), "set_out_of_range_mode", "get_out_of_range_mode");
- ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "panning_strength", PROPERTY_HINT_RANGE, "0,3,0.01,or_greater"), "set_panning_strength", "get_panning_strength");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "area_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_area_mask", "get_area_mask");
- ADD_GROUP("Emission Angle", "emission_angle");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emission_angle_enabled"), "set_emission_angle_enabled", "is_emission_angle_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_angle_degrees", PROPERTY_HINT_RANGE, "0.1,90,0.1"), "set_emission_angle", "get_emission_angle");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_angle_filter_attenuation_db", PROPERTY_HINT_RANGE, "-80,0,0.1"), "set_emission_angle_filter_attenuation_db", "get_emission_angle_filter_attenuation_db");
- ADD_GROUP("Attenuation Filter", "attenuation_filter_");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation_filter_cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1"), "set_attenuation_filter_cutoff_hz", "get_attenuation_filter_cutoff_hz");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation_filter_db", PROPERTY_HINT_RANGE, "-80,0,0.1"), "set_attenuation_filter_db", "get_attenuation_filter_db");
- ADD_GROUP("Doppler", "doppler_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "doppler_tracking", PROPERTY_HINT_ENUM, "Disabled,Idle,Physics"), "set_doppler_tracking", "get_doppler_tracking");
-
- BIND_ENUM_CONSTANT(ATTENUATION_INVERSE_DISTANCE);
- BIND_ENUM_CONSTANT(ATTENUATION_INVERSE_SQUARE_DISTANCE);
- BIND_ENUM_CONSTANT(ATTENUATION_LOGARITHMIC);
- BIND_ENUM_CONSTANT(ATTENUATION_DISABLED);
-
- BIND_ENUM_CONSTANT(OUT_OF_RANGE_MIX);
- BIND_ENUM_CONSTANT(OUT_OF_RANGE_PAUSE);
-
- BIND_ENUM_CONSTANT(DOPPLER_TRACKING_DISABLED);
- BIND_ENUM_CONSTANT(DOPPLER_TRACKING_IDLE_STEP);
- BIND_ENUM_CONSTANT(DOPPLER_TRACKING_PHYSICS_STEP);
-
- ADD_SIGNAL(MethodInfo("finished"));
-}
-
-AudioStreamPlayer3D::AudioStreamPlayer3D() {
- unit_db = 0;
- unit_size = 1;
- attenuation_model = ATTENUATION_INVERSE_DISTANCE;
- max_db = 3;
- pitch_scale = 1.0;
- autoplay = false;
- setseek.set(-1);
- prev_output_count = 0;
- max_distance = 0;
- setplay.set(-1);
- area_mask = 1;
- emission_angle = 45;
- emission_angle_enabled = false;
- emission_angle_filter_attenuation_db = -12;
- attenuation_filter_cutoff_hz = 5000;
- attenuation_filter_db = -24;
- out_of_range_mode = OUT_OF_RANGE_MIX;
- doppler_tracking = DOPPLER_TRACKING_DISABLED;
- stream_paused = false;
- stream_paused_fade_in = false;
- stream_paused_fade_out = false;
-
- velocity_tracker.instance();
- AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed");
- set_disable_scale(true);
- cached_global_panning_strength = ProjectSettings::get_singleton()->get("audio/3d_panning_strength");
-}
-AudioStreamPlayer3D::~AudioStreamPlayer3D() {
-}
diff --git a/scene/3d/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h
deleted file mode 100644
index 27fbab3..0000000
--- a/scene/3d/audio_stream_player_3d.h
+++ /dev/null
@@ -1,225 +0,0 @@
-#ifndef AUDIO_STREAM_PLAYER_3D_H
-#define AUDIO_STREAM_PLAYER_3D_H
-/*************************************************************************/
-/* audio_stream_player_3d.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "core/os/safe_refcount.h"
-#include "scene/main/spatial.h"
-#include "servers/audio/audio_filter_sw.h"
-#include "servers/audio_server.h"
-
-class Camera;
-class AudioStreamPlayback;
-class SpatialVelocityTracker;
-
-class AudioStreamPlayer3D : public Spatial {
- GDCLASS(AudioStreamPlayer3D, Spatial);
-
-public:
- enum AttenuationModel {
- ATTENUATION_INVERSE_DISTANCE,
- ATTENUATION_INVERSE_SQUARE_DISTANCE,
- ATTENUATION_LOGARITHMIC,
- ATTENUATION_DISABLED,
- };
-
- enum OutOfRangeMode {
- OUT_OF_RANGE_MIX,
- OUT_OF_RANGE_PAUSE,
- };
-
- enum DopplerTracking {
- DOPPLER_TRACKING_DISABLED,
- DOPPLER_TRACKING_IDLE_STEP,
- DOPPLER_TRACKING_PHYSICS_STEP
- };
-
-private:
- enum {
- MAX_OUTPUTS = 8,
- MAX_INTERSECT_AREAS = 32
-
- };
-
- struct Output {
- AudioFilterSW filter;
- AudioFilterSW::Processor filter_process[8];
- AudioFrame vol[4];
- float filter_gain;
- float pitch_scale;
- int bus_index;
- int reverb_bus_index;
- AudioFrame reverb_vol[4];
- Viewport *viewport; //pointer only used for reference to previous mix
-
- Output() {
- filter_gain = 0;
- viewport = nullptr;
- reverb_bus_index = -1;
- bus_index = -1;
- }
- };
-
- Output outputs[MAX_OUTPUTS];
- SafeNumeric output_count;
- SafeFlag output_ready;
-
- //these are used by audio thread to have a reference of previous volumes (for ramping volume and avoiding clicks)
- Output prev_outputs[MAX_OUTPUTS];
- int prev_output_count;
-
- Ref stream_playback;
- Ref stream;
- Vector mix_buffer;
-
- SafeNumeric setseek;
- SafeFlag active;
- SafeNumeric setplay;
-
- AttenuationModel attenuation_model;
- float unit_db;
- float unit_size;
- float max_db;
- float pitch_scale;
- bool autoplay;
- bool stream_paused;
- bool stream_paused_fade_in;
- bool stream_paused_fade_out;
- StringName bus;
-
- static void _calc_output_vol(const Vector3 &source_dir, real_t tightness, Output &output);
- void _mix_audio();
- static void _mix_audios(void *self) { reinterpret_cast(self)->_mix_audio(); }
-
- void _set_playing(bool p_enable);
- bool _is_active() const;
-
- void _bus_layout_changed();
-
- uint32_t area_mask;
-
- bool emission_angle_enabled;
- float emission_angle;
- float emission_angle_filter_attenuation_db;
- float attenuation_filter_cutoff_hz;
- float attenuation_filter_db;
-
- float max_distance;
-
- Ref velocity_tracker;
-
- DopplerTracking doppler_tracking;
-
- OutOfRangeMode out_of_range_mode;
-
- float _get_attenuation_db(float p_distance) const;
-
- float panning_strength = 1.0f;
- float cached_global_panning_strength = 1.0f;
-
-protected:
- void _validate_property(PropertyInfo &property) const;
- void _notification(int p_what);
- static void _bind_methods();
-
-public:
- void set_stream(Ref p_stream);
- Ref get_stream() const;
-
- void set_unit_db(float p_volume);
- float get_unit_db() const;
-
- void set_unit_size(float p_volume);
- float get_unit_size() const;
-
- void set_max_db(float p_boost);
- float get_max_db() const;
-
- void set_pitch_scale(float p_pitch_scale);
- float get_pitch_scale() const;
-
- void play(float p_from_pos = 0.0);
- void seek(float p_seconds);
- void stop();
- bool is_playing() const;
- float get_playback_position();
-
- void set_bus(const StringName &p_bus);
- StringName get_bus() const;
-
- void set_autoplay(bool p_enable);
- bool is_autoplay_enabled();
-
- void set_max_distance(float p_metres);
- float get_max_distance() const;
-
- void set_area_mask(uint32_t p_mask);
- uint32_t get_area_mask() const;
-
- void set_emission_angle_enabled(bool p_enable);
- bool is_emission_angle_enabled() const;
-
- void set_emission_angle(float p_angle);
- float get_emission_angle() const;
-
- void set_emission_angle_filter_attenuation_db(float p_angle_attenuation_db);
- float get_emission_angle_filter_attenuation_db() const;
-
- void set_attenuation_filter_cutoff_hz(float p_hz);
- float get_attenuation_filter_cutoff_hz() const;
-
- void set_attenuation_filter_db(float p_db);
- float get_attenuation_filter_db() const;
-
- void set_attenuation_model(AttenuationModel p_model);
- AttenuationModel get_attenuation_model() const;
-
- void set_out_of_range_mode(OutOfRangeMode p_mode);
- OutOfRangeMode get_out_of_range_mode() const;
-
- void set_doppler_tracking(DopplerTracking p_tracking);
- DopplerTracking get_doppler_tracking() const;
-
- void set_stream_paused(bool p_pause);
- bool get_stream_paused() const;
-
- void set_panning_strength(float p_panning_strength);
- float get_panning_strength() const;
-
- Ref get_stream_playback();
-
- AudioStreamPlayer3D();
- ~AudioStreamPlayer3D();
-};
-
-VARIANT_ENUM_CAST(AudioStreamPlayer3D::AttenuationModel)
-VARIANT_ENUM_CAST(AudioStreamPlayer3D::OutOfRangeMode)
-VARIANT_ENUM_CAST(AudioStreamPlayer3D::DopplerTracking)
-#endif // AUDIO_STREAM_PLAYER_3D_H
diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp
deleted file mode 100644
index 9e03398..0000000
--- a/scene/3d/camera.cpp
+++ /dev/null
@@ -1,685 +0,0 @@
-/*************************************************************************/
-/* camera.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "camera.h"
-
-#include "core/config/engine.h"
-#include "core/math/projection.h"
-#include "scene/3d/spatial_velocity_tracker.h"
-#include "scene/main/viewport.h"
-#include "scene/resources/environment_3d.h"
-#include "scene/resources/material/material.h"
-#include "scene/resources/mesh/surface_tool.h"
-#include "scene/resources/world_3d.h"
-
-void Camera::_update_audio_listener_state() {
-}
-
-void Camera::_request_camera_update() {
- _update_camera();
-}
-
-void Camera::_update_camera_mode() {
- force_change = true;
- switch (mode) {
- case PROJECTION_PERSPECTIVE: {
- set_perspective(fov, near, far);
-
- } break;
- case PROJECTION_ORTHOGONAL: {
- set_orthogonal(size, near, far);
- } break;
- case PROJECTION_FRUSTUM: {
- set_frustum(size, frustum_offset, near, far);
- } break;
- }
-}
-
-void Camera::_validate_property(PropertyInfo &p_property) const {
- if (p_property.name == "fov") {
- if (mode != PROJECTION_PERSPECTIVE) {
- p_property.usage = PROPERTY_USAGE_NOEDITOR;
- }
- } else if (p_property.name == "size") {
- if (mode != PROJECTION_ORTHOGONAL && mode != PROJECTION_FRUSTUM) {
- p_property.usage = PROPERTY_USAGE_NOEDITOR;
- }
- } else if (p_property.name == "frustum_offset") {
- if (mode != PROJECTION_FRUSTUM) {
- p_property.usage = PROPERTY_USAGE_NOEDITOR;
- }
- }
-}
-
-void Camera::_update_camera() {
- if (!is_inside_tree()) {
- return;
- }
-
- RenderingServer::get_singleton()->camera_set_transform(camera, get_camera_transform());
-
- // here goes listener stuff
- /*
- if (viewport_ptr && is_inside_scene() && is_current())
- get_world()->_camera_transform_changed_notify();
- */
-
- if (get_tree()->is_node_being_edited(this) || !is_current()) {
- return;
- }
-
- get_world()->_camera_transform_changed_notify();
-
- if (get_world_3d().is_valid()) {
- get_world_3d()->_update_camera(this);
- }
-}
-
-void Camera::_physics_interpolated_changed() {
- RenderingServer::get_singleton()->camera_set_interpolated(camera, is_physics_interpolated());
-}
-
-void Camera::_notification(int p_what) {
- switch (p_what) {
- case NOTIFICATION_ENTER_WORLD: {
- // Needs to track the Viewport because it's needed on NOTIFICATION_EXIT_WORLD
- // and Spatial will handle it first, including clearing its reference to the Viewport,
- // therefore making it impossible to subclasses to access it
- world = get_world();
- ERR_FAIL_COND(!world);
-
- bool first_camera = world->_camera_add(this);
- if (current || first_camera) {
- world->_camera_set(this);
- }
- } break;
- case NOTIFICATION_TRANSFORM_CHANGED: {
- _request_camera_update();
- if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
- velocity_tracker->update_position(get_global_transform().origin);
- }
- } break;
- case NOTIFICATION_RESET_PHYSICS_INTERPOLATION: {
- if (is_physics_interpolated()) {
- RenderingServer::get_singleton()->camera_reset_physics_interpolation(camera);
- }
- } break;
- case NOTIFICATION_EXIT_WORLD: {
- if (!get_tree()->is_node_being_edited(this)) {
- if (is_current()) {
- clear_current();
- current = true; //keep it true
-
- } else {
- current = false;
- }
- }
-
- if (world) {
- world->_camera_remove(this);
- world = nullptr;
- }
-
- } break;
- case NOTIFICATION_BECAME_CURRENT: {
- if (world) {
- world->_world_3d_register_camera(this);
- }
- } break;
- case NOTIFICATION_LOST_CURRENT: {
- if (world) {
- world->_world_3d_remove_camera(this);
- }
- } break;
- }
-}
-
-Transform Camera::get_camera_transform() const {
- Transform tr = get_global_transform().orthonormalized();
- tr.origin += tr.basis.get_axis(1) * v_offset;
- tr.origin += tr.basis.get_axis(0) * h_offset;
- return tr;
-}
-
-void Camera::set_perspective(float p_fovy_degrees, float p_z_near, float p_z_far) {
- if (!force_change && fov == p_fovy_degrees && p_z_near == near && p_z_far == far && mode == PROJECTION_PERSPECTIVE) {
- return;
- }
-
- fov = p_fovy_degrees;
- near = p_z_near;
- far = p_z_far;
- mode = PROJECTION_PERSPECTIVE;
-
- RenderingServer::get_singleton()->camera_set_perspective(camera, fov, near, far);
- update_gizmos();
- force_change = false;
-}
-void Camera::set_orthogonal(float p_size, float p_z_near, float p_z_far) {
- if (!force_change && size == p_size && p_z_near == near && p_z_far == far && mode == PROJECTION_ORTHOGONAL) {
- return;
- }
-
- size = p_size;
-
- near = p_z_near;
- far = p_z_far;
- mode = PROJECTION_ORTHOGONAL;
- force_change = false;
-
- RenderingServer::get_singleton()->camera_set_orthogonal(camera, size, near, far);
- update_gizmos();
-}
-
-void Camera::set_frustum(float p_size, Vector2 p_offset, float p_z_near, float p_z_far) {
- if (!force_change && size == p_size && frustum_offset == p_offset && p_z_near == near && p_z_far == far && mode == PROJECTION_FRUSTUM) {
- return;
- }
-
- size = p_size;
- frustum_offset = p_offset;
-
- near = p_z_near;
- far = p_z_far;
- mode = PROJECTION_FRUSTUM;
- force_change = false;
-
- RenderingServer::get_singleton()->camera_set_frustum(camera, size, frustum_offset, near, far);
- update_gizmos();
-}
-
-void Camera::set_projection(Camera::ProjectionMode p_mode) {
- if (p_mode == PROJECTION_PERSPECTIVE || p_mode == PROJECTION_ORTHOGONAL || p_mode == PROJECTION_FRUSTUM) {
- mode = p_mode;
- _update_camera_mode();
- _change_notify();
- }
-}
-
-RID Camera::get_camera() const {
- return camera;
-};
-
-void Camera::make_current() {
- current = true;
-
- if (!is_inside_tree()) {
- return;
- }
-
- get_world()->_camera_set(this);
-
- //get_scene()->call_group(SceneMainLoop::GROUP_CALL_REALTIME,camera_group,"_camera_make_current",this);
-}
-
-void Camera::clear_current(bool p_enable_next) {
- current = false;
- if (!is_inside_tree()) {
- return;
- }
-
- if (get_world()->get_camera() == this) {
- get_world()->_camera_set(nullptr);
-
- if (p_enable_next) {
- get_world()->_camera_make_next_current(this);
- }
- }
-}
-
-void Camera::set_current(bool p_current) {
- if (p_current) {
- make_current();
- } else {
- clear_current();
- }
-}
-
-bool Camera::is_current() const {
- if (is_inside_tree() && !get_tree()->is_node_being_edited(this)) {
- return get_world()->get_camera() == this;
- } else {
- return current;
- }
-}
-
-Vector3 Camera::project_ray_normal(const Point2 &p_pos) const {
- Vector3 ray = project_local_ray_normal(p_pos);
- return get_camera_transform().basis.xform(ray).normalized();
-};
-
-Vector3 Camera::project_local_ray_normal(const Point2 &p_pos) const {
- ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector3(), "Camera is not inside scene.");
-
- Size2 viewport_size = get_world()->get_camera_rect_size();
- Vector2 cpos = get_world()->get_camera_coords(p_pos);
- Vector3 ray;
-
- if (mode == PROJECTION_ORTHOGONAL) {
- ray = Vector3(0, 0, -1);
- } else {
- Projection cm;
- cm.set_perspective(fov, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH);
- Vector2 screen_he = cm.get_viewport_half_extents();
- ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_he.y, -near).normalized();
- }
-
- return ray;
-};
-
-Vector3 Camera::project_ray_origin(const Point2 &p_pos) const {
- ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector3(), "Camera is not inside scene.");
-
- Size2 viewport_size = get_world()->get_camera_rect_size();
- Vector2 cpos = get_world()->get_camera_coords(p_pos);
- ERR_FAIL_COND_V(viewport_size.y == 0, Vector3());
-
- if (mode == PROJECTION_PERSPECTIVE) {
- return get_camera_transform().origin;
- } else {
- Vector2 pos = cpos / viewport_size;
- float vsize, hsize;
- if (keep_aspect == KEEP_WIDTH) {
- vsize = size / viewport_size.aspect();
- hsize = size;
- } else {
- hsize = size * viewport_size.aspect();
- vsize = size;
- }
-
- Vector3 ray;
- ray.x = pos.x * (hsize)-hsize / 2;
- ray.y = (1.0 - pos.y) * (vsize)-vsize / 2;
- ray.z = -near;
- ray = get_camera_transform().xform(ray);
- return ray;
- };
-};
-
-bool Camera::is_position_behind(const Vector3 &p_pos) const {
- Transform t = get_global_transform();
- Vector3 eyedir = -t.basis.get_axis(2).normalized();
- return eyedir.dot(p_pos - t.origin) < near;
-}
-
-Vector Camera::get_near_plane_points() const {
- ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector(), "Camera is not inside scene.");
-
- Size2 viewport_size = get_world()->get_visible_rect().size;
-
- Projection cm;
-
- if (mode == PROJECTION_ORTHOGONAL) {
- cm.set_orthogonal(size, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH);
- } else {
- cm.set_perspective(fov, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH);
- }
-
- Vector3 endpoints[8];
- cm.get_endpoints(Transform(), endpoints);
-
- Vector points;
- points.push_back(Vector3());
- for (int i = 0; i < 4; i++) {
- points.push_back(endpoints[i + 4]);
- }
- return points;
-}
-
-Point2 Camera::unproject_position(const Vector3 &p_pos) const {
- ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector2(), "Camera is not inside scene.");
-
- Size2 viewport_size = get_world()->get_visible_rect().size;
-
- Projection cm;
-
- if (mode == PROJECTION_ORTHOGONAL) {
- cm.set_orthogonal(size, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH);
- } else {
- cm.set_perspective(fov, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH);
- }
-
- Plane p(get_camera_transform().xform_inv(p_pos), 1.0);
-
- p = cm.xform(p);
- p.normal /= p.d;
-
- Point2 res;
- res.x = (p.normal.x * 0.5 + 0.5) * viewport_size.x;
- res.y = (-p.normal.y * 0.5 + 0.5) * viewport_size.y;
-
- return res;
-}
-
-Vector3 Camera::project_position(const Point2 &p_point, float p_z_depth) const {
- ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector3(), "Camera is not inside scene.");
-
- if (p_z_depth == 0 && mode != PROJECTION_ORTHOGONAL) {
- return get_global_transform().origin;
- }
- Size2 viewport_size = get_world()->get_visible_rect().size;
-
- Projection cm;
-
- if (mode == PROJECTION_ORTHOGONAL) {
- cm.set_orthogonal(size, viewport_size.aspect(), p_z_depth, far, keep_aspect == KEEP_WIDTH);
- } else {
- cm.set_perspective(fov, viewport_size.aspect(), p_z_depth, far, keep_aspect == KEEP_WIDTH);
- }
-
- Vector2 vp_he = cm.get_viewport_half_extents();
-
- Vector2 point;
- point.x = (p_point.x / viewport_size.x) * 2.0 - 1.0;
- point.y = (1.0 - (p_point.y / viewport_size.y)) * 2.0 - 1.0;
- point *= vp_he;
-
- Vector3 p(point.x, point.y, -p_z_depth);
-
- return get_camera_transform().xform(p);
-}
-
-/*
-void Camera::_camera_make_current(Node *p_camera) {
-
-
- if (p_camera==this) {
- RenderingServer::get_singleton()->viewport_attach_camera(viewport_id,camera);
- active=true;
- } else {
- if (active && p_camera==NULL) {
- //detech camera because no one else will claim it
- RenderingServer::get_singleton()->viewport_attach_camera(viewport_id,RID());
- }
- active=false;
- }
-}
-*/
-
-void Camera::set_environment(const Ref &p_environment) {
- environment = p_environment;
- if (environment.is_valid()) {
- RS::get_singleton()->camera_set_environment(camera, environment->get_rid());
- } else {
- RS::get_singleton()->camera_set_environment(camera, RID());
- }
- _update_camera_mode();
-}
-
-Ref Camera::get_environment() const {
- return environment;
-}
-
-void Camera::set_keep_aspect_mode(KeepAspect p_aspect) {
- keep_aspect = p_aspect;
- RenderingServer::get_singleton()->camera_set_use_vertical_aspect(camera, p_aspect == KEEP_WIDTH);
- _update_camera_mode();
- _change_notify();
-}
-
-Camera::KeepAspect Camera::get_keep_aspect_mode() const {
- return keep_aspect;
-}
-
-void Camera::set_doppler_tracking(DopplerTracking p_tracking) {
- if (doppler_tracking == p_tracking) {
- return;
- }
-
- doppler_tracking = p_tracking;
- if (p_tracking != DOPPLER_TRACKING_DISABLED) {
- velocity_tracker->set_track_physics_step(doppler_tracking == DOPPLER_TRACKING_PHYSICS_STEP);
- if (is_inside_tree()) {
- velocity_tracker->reset(get_global_transform().origin);
- }
- }
- _update_camera_mode();
-}
-
-Camera::DopplerTracking Camera::get_doppler_tracking() const {
- return doppler_tracking;
-}
-
-void Camera::_bind_methods() {
- ClassDB::bind_method(D_METHOD("project_ray_normal", "screen_point"), &Camera::project_ray_normal);
- ClassDB::bind_method(D_METHOD("project_local_ray_normal", "screen_point"), &Camera::project_local_ray_normal);
- ClassDB::bind_method(D_METHOD("project_ray_origin", "screen_point"), &Camera::project_ray_origin);
- ClassDB::bind_method(D_METHOD("unproject_position", "world_point"), &Camera::unproject_position);
- ClassDB::bind_method(D_METHOD("is_position_behind", "world_point"), &Camera::is_position_behind);
- ClassDB::bind_method(D_METHOD("project_position", "screen_point", "z_depth"), &Camera::project_position);
- ClassDB::bind_method(D_METHOD("set_perspective", "fov", "z_near", "z_far"), &Camera::set_perspective);
- ClassDB::bind_method(D_METHOD("set_orthogonal", "size", "z_near", "z_far"), &Camera::set_orthogonal);
- ClassDB::bind_method(D_METHOD("set_frustum", "size", "offset", "z_near", "z_far"), &Camera::set_frustum);
- ClassDB::bind_method(D_METHOD("make_current"), &Camera::make_current);
- ClassDB::bind_method(D_METHOD("clear_current", "enable_next"), &Camera::clear_current, DEFVAL(true));
- ClassDB::bind_method(D_METHOD("set_current", "enable"), &Camera::set_current);
- ClassDB::bind_method(D_METHOD("is_current"), &Camera::is_current);
- ClassDB::bind_method(D_METHOD("get_camera_transform"), &Camera::get_camera_transform);
- ClassDB::bind_method(D_METHOD("get_fov"), &Camera::get_fov);
- ClassDB::bind_method(D_METHOD("get_frustum_offset"), &Camera::get_frustum_offset);
- ClassDB::bind_method(D_METHOD("get_size"), &Camera::get_size);
- ClassDB::bind_method(D_METHOD("get_zfar"), &Camera::get_zfar);
- ClassDB::bind_method(D_METHOD("get_znear"), &Camera::get_znear);
- ClassDB::bind_method(D_METHOD("set_fov", "fov"), &Camera::set_fov);
- ClassDB::bind_method(D_METHOD("set_frustum_offset", "frustum_offset"), &Camera::set_frustum_offset);
- ClassDB::bind_method(D_METHOD("set_size", "size"), &Camera::set_size);
- ClassDB::bind_method(D_METHOD("set_zfar", "zfar"), &Camera::set_zfar);
- ClassDB::bind_method(D_METHOD("set_znear", "znear"), &Camera::set_znear);
- ClassDB::bind_method(D_METHOD("get_projection"), &Camera::get_projection);
- ClassDB::bind_method(D_METHOD("set_projection", "projection"), &Camera::set_projection);
- ClassDB::bind_method(D_METHOD("set_h_offset", "ofs"), &Camera::set_h_offset);
- ClassDB::bind_method(D_METHOD("get_h_offset"), &Camera::get_h_offset);
- ClassDB::bind_method(D_METHOD("set_v_offset", "ofs"), &Camera::set_v_offset);
- ClassDB::bind_method(D_METHOD("get_v_offset"), &Camera::get_v_offset);
- ClassDB::bind_method(D_METHOD("set_cull_mask", "mask"), &Camera::set_cull_mask);
- ClassDB::bind_method(D_METHOD("get_cull_mask"), &Camera::get_cull_mask);
- ClassDB::bind_method(D_METHOD("set_environment", "env"), &Camera::set_environment);
- ClassDB::bind_method(D_METHOD("get_environment"), &Camera::get_environment);
- ClassDB::bind_method(D_METHOD("set_keep_aspect_mode", "mode"), &Camera::set_keep_aspect_mode);
- ClassDB::bind_method(D_METHOD("get_keep_aspect_mode"), &Camera::get_keep_aspect_mode);
- ClassDB::bind_method(D_METHOD("set_doppler_tracking", "mode"), &Camera::set_doppler_tracking);
- ClassDB::bind_method(D_METHOD("get_doppler_tracking"), &Camera::get_doppler_tracking);
- ClassDB::bind_method(D_METHOD("get_frustum"), &Camera::get_frustum);
- ClassDB::bind_method(D_METHOD("get_camera_rid"), &Camera::get_camera);
-
- ClassDB::bind_method(D_METHOD("set_cull_mask_bit", "layer", "enable"), &Camera::set_cull_mask_bit);
- ClassDB::bind_method(D_METHOD("get_cull_mask_bit", "layer"), &Camera::get_cull_mask_bit);
-
- //ClassDB::bind_method(D_METHOD("_camera_make_current"),&Camera::_camera_make_current );
-
- ADD_PROPERTY(PropertyInfo(Variant::INT, "keep_aspect", PROPERTY_HINT_ENUM, "Keep Width,Keep Height"), "set_keep_aspect_mode", "get_keep_aspect_mode");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment3D"), "set_environment", "get_environment");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "h_offset"), "set_h_offset", "get_h_offset");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_offset"), "set_v_offset", "get_v_offset");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "doppler_tracking", PROPERTY_HINT_ENUM, "Disabled,Idle,Physics"), "set_doppler_tracking", "get_doppler_tracking");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "projection", PROPERTY_HINT_ENUM, "Perspective,Orthogonal,Frustum"), "set_projection", "get_projection");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "set_current", "is_current");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "fov", PROPERTY_HINT_RANGE, "1,179,0.1"), "set_fov", "get_fov");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "size", PROPERTY_HINT_RANGE, "0.001,16384,0.001"), "set_size", "get_size");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frustum_offset"), "set_frustum_offset", "get_frustum_offset");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "near", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01,or_greater"), "set_znear", "get_znear");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "far", PROPERTY_HINT_EXP_RANGE, "0.1,8192,0.1,or_greater"), "set_zfar", "get_zfar");
-
- BIND_ENUM_CONSTANT(PROJECTION_PERSPECTIVE);
- BIND_ENUM_CONSTANT(PROJECTION_ORTHOGONAL);
- BIND_ENUM_CONSTANT(PROJECTION_FRUSTUM);
-
- BIND_ENUM_CONSTANT(KEEP_WIDTH);
- BIND_ENUM_CONSTANT(KEEP_HEIGHT);
-
- BIND_ENUM_CONSTANT(DOPPLER_TRACKING_DISABLED);
- BIND_ENUM_CONSTANT(DOPPLER_TRACKING_IDLE_STEP);
- BIND_ENUM_CONSTANT(DOPPLER_TRACKING_PHYSICS_STEP);
-}
-
-float Camera::get_fov() const {
- return fov;
-}
-
-float Camera::get_size() const {
- return size;
-}
-
-float Camera::get_znear() const {
- return near;
-}
-
-Vector2 Camera::get_frustum_offset() const {
- return frustum_offset;
-}
-
-float Camera::get_zfar() const {
- return far;
-}
-
-Camera::ProjectionMode Camera::get_projection() const {
- return mode;
-}
-
-void Camera::set_fov(float p_fov) {
- ERR_FAIL_COND(p_fov < 1 || p_fov > 179);
- fov = p_fov;
- _update_camera_mode();
- _change_notify("fov");
-}
-
-void Camera::set_size(float p_size) {
- ERR_FAIL_COND(p_size < 0.001 || p_size > 16384);
- size = p_size;
- _update_camera_mode();
- _change_notify("size");
-}
-
-void Camera::set_znear(float p_znear) {
- near = p_znear;
- _update_camera_mode();
-}
-
-void Camera::set_frustum_offset(Vector2 p_offset) {
- frustum_offset = p_offset;
- _update_camera_mode();
-}
-
-void Camera::set_zfar(float p_zfar) {
- far = p_zfar;
- _update_camera_mode();
-}
-
-void Camera::set_cull_mask(uint32_t p_layers) {
- layers = p_layers;
- RenderingServer::get_singleton()->camera_set_cull_mask(camera, layers);
- _update_camera_mode();
-}
-
-uint32_t Camera::get_cull_mask() const {
- return layers;
-}
-
-void Camera::set_cull_mask_bit(int p_layer, bool p_enable) {
- ERR_FAIL_INDEX(p_layer, 32);
- if (p_enable) {
- set_cull_mask(layers | (1 << p_layer));
- } else {
- set_cull_mask(layers & (~(1 << p_layer)));
- }
-}
-
-bool Camera::get_cull_mask_bit(int p_layer) const {
- ERR_FAIL_INDEX_V(p_layer, 32, false);
- return (layers & (1 << p_layer));
-}
-
-Vector Camera::get_frustum() const {
- ERR_FAIL_COND_V(!is_inside_world(), Vector());
-
- Size2 viewport_size = get_world()->get_visible_rect().size;
- Projection cm;
- if (mode == PROJECTION_PERSPECTIVE) {
- cm.set_perspective(fov, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH);
- } else {
- cm.set_orthogonal(size, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH);
- }
-
- return cm.get_projection_planes(get_camera_transform());
-}
-
-void Camera::set_v_offset(float p_offset) {
- v_offset = p_offset;
- _update_camera();
-}
-
-float Camera::get_v_offset() const {
- return v_offset;
-}
-
-void Camera::set_h_offset(float p_offset) {
- h_offset = p_offset;
- _update_camera();
-}
-
-float Camera::get_h_offset() const {
- return h_offset;
-}
-
-Vector3 Camera::get_doppler_tracked_velocity() const {
- if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
- return velocity_tracker->get_tracked_linear_velocity();
- } else {
- return Vector3();
- }
-}
-Camera::Camera() {
- camera = RID_PRIME(RenderingServer::get_singleton()->camera_create());
- size = 1;
- fov = 0;
- frustum_offset = Vector2();
- near = 0;
- far = 0;
- current = false;
- world = nullptr;
- force_change = false;
- mode = PROJECTION_PERSPECTIVE;
- set_perspective(70.0, 0.05, 100.0);
- keep_aspect = KEEP_HEIGHT;
- layers = 0xfffff;
- v_offset = 0;
- h_offset = 0;
- RenderingServer::get_singleton()->camera_set_cull_mask(camera, layers);
- //active=false;
- velocity_tracker.instance();
- doppler_tracking = DOPPLER_TRACKING_DISABLED;
- set_notify_transform(true);
- set_disable_scale(true);
-}
-
-Camera::~Camera() {
- RenderingServer::get_singleton()->free(camera);
-}
diff --git a/scene/3d/camera.h b/scene/3d/camera.h
deleted file mode 100644
index 0f42fb8..0000000
--- a/scene/3d/camera.h
+++ /dev/null
@@ -1,184 +0,0 @@
-#ifndef CAMERA_H
-#define CAMERA_H
-/*************************************************************************/
-/* camera.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "core/object/reference.h"
-#include "scene/main/spatial.h"
-
-class SpatialVelocityTracker;
-class Viewport;
-class Environment3D;
-class World;
-
-class Camera : public Spatial {
- GDCLASS(Camera, Spatial);
-
-public:
- enum ProjectionMode {
-
- PROJECTION_PERSPECTIVE,
- PROJECTION_ORTHOGONAL,
- PROJECTION_FRUSTUM
- };
-
- enum KeepAspect {
- KEEP_WIDTH,
- KEEP_HEIGHT
- };
-
- enum DopplerTracking {
- DOPPLER_TRACKING_DISABLED,
- DOPPLER_TRACKING_IDLE_STEP,
- DOPPLER_TRACKING_PHYSICS_STEP
- };
-
-private:
- bool force_change;
- bool current;
- World *world;
-
- ProjectionMode mode;
-
- float fov;
- float size;
- Vector2 frustum_offset;
- float near, far;
- float v_offset;
- float h_offset;
- KeepAspect keep_aspect;
-
- RID camera;
- RID scenario_id;
-
- //String camera_group;
-
- uint32_t layers;
-
- Ref environment;
-
- //void _camera_make_current(Node *p_camera);
- friend class Viewport;
- void _update_audio_listener_state();
-
- DopplerTracking doppler_tracking;
- Ref velocity_tracker;
-
-protected:
- void _update_camera();
- virtual void _request_camera_update();
- void _update_camera_mode();
-
- virtual void _physics_interpolated_changed();
-
- void _notification(int p_what);
- virtual void _validate_property(PropertyInfo &p_property) const;
-
- static void _bind_methods();
-
-public:
- enum {
-
- NOTIFICATION_BECAME_CURRENT = 50,
- NOTIFICATION_LOST_CURRENT = 51
- };
-
- void set_perspective(float p_fovy_degrees, float p_z_near, float p_z_far);
- void set_orthogonal(float p_size, float p_z_near, float p_z_far);
- void set_frustum(float p_size, Vector2 p_offset, float p_z_near, float p_z_far);
- void set_projection(Camera::ProjectionMode p_mode);
-
- void make_current();
- void clear_current(bool p_enable_next = true);
- void set_current(bool p_current);
- bool is_current() const;
-
- RID get_camera() const;
-
- float get_fov() const;
- float get_size() const;
- float get_zfar() const;
- float get_znear() const;
- Vector2 get_frustum_offset() const;
-
- ProjectionMode get_projection() const;
-
- void set_fov(float p_fov);
- void set_size(float p_size);
- void set_zfar(float p_zfar);
- void set_znear(float p_znear);
- void set_frustum_offset(Vector2 p_offset);
-
- virtual Transform get_camera_transform() const;
-
- virtual Vector3 project_ray_normal(const Point2 &p_pos) const;
- virtual Vector3 project_ray_origin(const Point2 &p_pos) const;
- virtual Vector3 project_local_ray_normal(const Point2 &p_pos) const;
- virtual Point2 unproject_position(const Vector3 &p_pos) const;
- bool is_position_behind(const Vector3 &p_pos) const;
- virtual Vector3 project_position(const Point2 &p_point, float p_z_depth) const;
-
- Vector get_near_plane_points() const;
-
- void set_cull_mask(uint32_t p_layers);
- uint32_t get_cull_mask() const;
-
- void set_cull_mask_bit(int p_layer, bool p_enable);
- bool get_cull_mask_bit(int p_layer) const;
-
- virtual Vector get_frustum() const;
-
- void set_environment(const Ref &p_environment);
- Ref get_environment() const;
-
- void set_keep_aspect_mode(KeepAspect p_aspect);
- KeepAspect get_keep_aspect_mode() const;
-
- void set_v_offset(float p_offset);
- float get_v_offset() const;
-
- void set_h_offset(float p_offset);
- float get_h_offset() const;
-
- void set_doppler_tracking(DopplerTracking p_tracking);
- DopplerTracking get_doppler_tracking() const;
-
- Vector3 get_doppler_tracked_velocity() const;
-
- Camera();
- ~Camera();
-};
-
-VARIANT_ENUM_CAST(Camera::ProjectionMode);
-VARIANT_ENUM_CAST(Camera::KeepAspect);
-VARIANT_ENUM_CAST(Camera::DopplerTracking);
-
-
-#endif
diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp
deleted file mode 100644
index 8ab8939..0000000
--- a/scene/3d/cpu_particles.cpp
+++ /dev/null
@@ -1,1609 +0,0 @@
-/*************************************************************************/
-/* cpu_particles.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "cpu_particles.h"
-
-#include "core/os/os.h"
-#include "scene/3d/camera.h"
-#include "scene/main/viewport.h"
-#include "scene/resources/curve.h"
-#include "scene/resources/gradient.h"
-#include "scene/resources/mesh/mesh.h"
-#include "scene/resources/material/particles_material.h"
-#include "scene/resources/material/spatial_material.h"
-#include "scene/resources/material/shader_material.h"
-#include "servers/rendering_server.h"
-
-AABB CPUParticles::get_aabb() const {
- return AABB();
-}
-PoolVector CPUParticles::get_faces(uint32_t p_usage_flags) const {
- return PoolVector();
-}
-
-void CPUParticles::_set_particles_processing(bool p_enable) {
- if (_interpolated) {
- set_physics_process_internal(p_enable);
- } else {
- set_process_internal(p_enable);
- }
-}
-
-void CPUParticles::set_emitting(bool p_emitting) {
- if (emitting == p_emitting) {
- return;
- }
-
- emitting = p_emitting;
- if (emitting) {
- _set_particles_processing(true);
-
- // first update before rendering to avoid one frame delay after emitting starts
- if ((time == 0) && !_interpolated) {
- _update_internal(false);
- }
- }
-}
-
-void CPUParticles::set_amount(int p_amount) {
- ERR_FAIL_COND_MSG(p_amount < 1, "Amount of particles must be greater than 0.");
-
- particles.resize(p_amount);
- particles_prev.resize(p_amount);
- {
- PoolVector::Write w = particles.write();
-
- for (int i = 0; i < p_amount; i++) {
- w[i].active = false;
- w[i].custom[3] = 0.0; // Make sure w component isn't garbage data
-
- particles_prev[i].blank();
- }
- }
-
- particle_data.resize((12 + 4 + 1) * p_amount);
- particle_data_prev.resize(particle_data.size());
-
- // We must fill immediately to prevent garbage data and Nans
- // being sent to the visual server with set_as_bulk_array,
- // if this is sent before being regularly updated.
- particle_data.fill(0);
- particle_data_prev.fill(0);
-
- RS::get_singleton()->multimesh_allocate(multimesh, p_amount, RS::MULTIMESH_TRANSFORM_3D, RS::MULTIMESH_COLOR_8BIT, RS::MULTIMESH_CUSTOM_DATA_FLOAT);
-
- particle_order.resize(p_amount);
-}
-void CPUParticles::set_lifetime(float p_lifetime) {
- ERR_FAIL_COND_MSG(p_lifetime <= 0, "Particles lifetime must be greater than 0.");
- lifetime = p_lifetime;
-}
-
-void CPUParticles::set_one_shot(bool p_one_shot) {
- one_shot = p_one_shot;
-}
-
-void CPUParticles::set_pre_process_time(float p_time) {
- pre_process_time = p_time;
-}
-void CPUParticles::set_explosiveness_ratio(float p_ratio) {
- explosiveness_ratio = p_ratio;
-}
-void CPUParticles::set_randomness_ratio(float p_ratio) {
- randomness_ratio = p_ratio;
-}
-void CPUParticles::set_lifetime_randomness(float p_random) {
- lifetime_randomness = p_random;
-}
-void CPUParticles::set_use_local_coordinates(bool p_enable) {
- local_coords = p_enable;
-
- // prevent sending instance transforms when using global coords
- set_instance_use_identity_transform(!p_enable);
-}
-void CPUParticles::set_speed_scale(float p_scale) {
- speed_scale = p_scale;
-}
-
-bool CPUParticles::is_emitting() const {
- return emitting;
-}
-int CPUParticles::get_amount() const {
- return particles.size();
-}
-float CPUParticles::get_lifetime() const {
- return lifetime;
-}
-bool CPUParticles::get_one_shot() const {
- return one_shot;
-}
-
-float CPUParticles::get_pre_process_time() const {
- return pre_process_time;
-}
-float CPUParticles::get_explosiveness_ratio() const {
- return explosiveness_ratio;
-}
-float CPUParticles::get_randomness_ratio() const {
- return randomness_ratio;
-}
-float CPUParticles::get_lifetime_randomness() const {
- return lifetime_randomness;
-}
-
-bool CPUParticles::get_use_local_coordinates() const {
- return local_coords;
-}
-
-float CPUParticles::get_speed_scale() const {
- return speed_scale;
-}
-
-void CPUParticles::set_draw_order(DrawOrder p_order) {
- ERR_FAIL_INDEX(p_order, DRAW_ORDER_MAX);
- draw_order = p_order;
-}
-
-CPUParticles::DrawOrder CPUParticles::get_draw_order() const {
- return draw_order;
-}
-
-void CPUParticles::set_mesh(const Ref &p_mesh) {
- mesh = p_mesh;
- if (mesh.is_valid()) {
- RS::get_singleton()->multimesh_set_mesh(multimesh, mesh->get_rid());
- } else {
- RS::get_singleton()->multimesh_set_mesh(multimesh, RID());
- }
-}
-
-Ref CPUParticles::get_mesh() const {
- return mesh;
-}
-
-void CPUParticles::set_fixed_fps(int p_count) {
- fixed_fps = p_count;
-}
-
-int CPUParticles::get_fixed_fps() const {
- return fixed_fps;
-}
-
-void CPUParticles::set_fractional_delta(bool p_enable) {
- fractional_delta = p_enable;
-}
-
-bool CPUParticles::get_fractional_delta() const {
- return fractional_delta;
-}
-
-String CPUParticles::get_configuration_warning() const {
- String warnings = GeometryInstance::get_configuration_warning();
-
- bool mesh_found = false;
- bool anim_material_found = false;
-
- if (get_mesh().is_valid()) {
- mesh_found = true;
- for (int j = 0; j < get_mesh()->get_surface_count(); j++) {
- anim_material_found = Object::cast_to(get_mesh()->surface_get_material(j).ptr()) != nullptr;
- SpatialMaterial *spat = Object::cast_to(get_mesh()->surface_get_material(j).ptr());
- anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == SpatialMaterial::BILLBOARD_PARTICLES);
- }
- }
-
- anim_material_found = anim_material_found || Object::cast_to(get_material_override().ptr()) != nullptr;
- SpatialMaterial *spat = Object::cast_to(get_material_override().ptr());
- anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == SpatialMaterial::BILLBOARD_PARTICLES);
-
- if (!mesh_found) {
- if (warnings != String()) {
- warnings += "\n";
- }
- warnings += "- " + TTR("Nothing is visible because no mesh has been assigned.");
- }
-
- if (!anim_material_found && (get_param(PARAM_ANIM_SPEED) != 0.0 || get_param(PARAM_ANIM_OFFSET) != 0.0 || get_param_curve(PARAM_ANIM_SPEED).is_valid() || get_param_curve(PARAM_ANIM_OFFSET).is_valid())) {
- if (warnings != String()) {
- warnings += "\n";
- }
- warnings += "- " + TTR("CPUParticles animation requires the usage of a SpatialMaterial whose Billboard Mode is set to \"Particle Billboard\".");
- }
-
- return warnings;
-}
-
-void CPUParticles::restart() {
- time = 0;
- inactive_time = 0;
- frame_remainder = 0;
- cycle = 0;
- emitting = false;
-
- {
- int pc = particles.size();
- PoolVector::Write w = particles.write();
-
- for (int i = 0; i < pc; i++) {
- w[i].active = false;
- }
- }
-
- set_emitting(true);
-}
-
-void CPUParticles::set_direction(Vector3 p_direction) {
- direction = p_direction;
-}
-
-Vector3 CPUParticles::get_direction() const {
- return direction;
-}
-
-void CPUParticles::set_spread(float p_spread) {
- spread = p_spread;
-}
-
-float CPUParticles::get_spread() const {
- return spread;
-}
-
-void CPUParticles::set_flatness(float p_flatness) {
- flatness = p_flatness;
-}
-float CPUParticles::get_flatness() const {
- return flatness;
-}
-
-void CPUParticles::set_param(Parameter p_param, float p_value) {
- ERR_FAIL_INDEX(p_param, PARAM_MAX);
-
- parameters[p_param] = p_value;
-}
-float CPUParticles::get_param(Parameter p_param) const {
- ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
-
- return parameters[p_param];
-}
-
-void CPUParticles::set_param_randomness(Parameter p_param, float p_value) {
- ERR_FAIL_INDEX(p_param, PARAM_MAX);
-
- randomness[p_param] = p_value;
-}
-float CPUParticles::get_param_randomness(Parameter p_param) const {
- ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
-
- return randomness[p_param];
-}
-
-static void _adjust_curve_range(const Ref &p_curve, float p_min, float p_max) {
- Ref curve = p_curve;
- if (!curve.is_valid()) {
- return;
- }
-
- curve->ensure_default_setup(p_min, p_max);
-}
-
-void CPUParticles::set_param_curve(Parameter p_param, const Ref &p_curve) {
- ERR_FAIL_INDEX(p_param, PARAM_MAX);
-
- curve_parameters[p_param] = p_curve;
-
- switch (p_param) {
- case PARAM_INITIAL_LINEAR_VELOCITY: {
- //do none for this one
- } break;
- case PARAM_ANGULAR_VELOCITY: {
- _adjust_curve_range(p_curve, -360, 360);
- } break;
- case PARAM_ORBIT_VELOCITY: {
- _adjust_curve_range(p_curve, -500, 500);
- } break;
- case PARAM_LINEAR_ACCEL: {
- _adjust_curve_range(p_curve, -200, 200);
- } break;
- case PARAM_RADIAL_ACCEL: {
- _adjust_curve_range(p_curve, -200, 200);
- } break;
- case PARAM_TANGENTIAL_ACCEL: {
- _adjust_curve_range(p_curve, -200, 200);
- } break;
- case PARAM_DAMPING: {
- _adjust_curve_range(p_curve, 0, 100);
- } break;
- case PARAM_ANGLE: {
- _adjust_curve_range(p_curve, -360, 360);
- } break;
- case PARAM_SCALE: {
- } break;
- case PARAM_HUE_VARIATION: {
- _adjust_curve_range(p_curve, -1, 1);
- } break;
- case PARAM_ANIM_SPEED: {
- _adjust_curve_range(p_curve, 0, 200);
- } break;
- case PARAM_ANIM_OFFSET: {
- } break;
- default: {
- }
- }
-}
-Ref CPUParticles::get_param_curve(Parameter p_param) const {
- ERR_FAIL_INDEX_V(p_param, PARAM_MAX, Ref());
-
- return curve_parameters[p_param];
-}
-
-void CPUParticles::set_color(const Color &p_color) {
- color = p_color;
-}
-
-Color CPUParticles::get_color() const {
- return color;
-}
-
-void CPUParticles::set_color_ramp(const Ref &p_ramp) {
- color_ramp = p_ramp;
-}
-
-Ref CPUParticles::get_color_ramp() const {
- return color_ramp;
-}
-
-void CPUParticles::set_color_initial_ramp(const Ref &p_ramp) {
- color_initial_ramp = p_ramp;
-}
-
-Ref CPUParticles::get_color_initial_ramp() const {
- return color_initial_ramp;
-}
-
-void CPUParticles::set_particle_flag(Flags p_flag, bool p_enable) {
- ERR_FAIL_INDEX(p_flag, FLAG_MAX);
- flags[p_flag] = p_enable;
- if (p_flag == FLAG_DISABLE_Z) {
- _change_notify();
- }
-}
-
-bool CPUParticles::get_particle_flag(Flags p_flag) const {
- ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
- return flags[p_flag];
-}
-
-void CPUParticles::set_emission_shape(EmissionShape p_shape) {
- ERR_FAIL_INDEX(p_shape, EMISSION_SHAPE_MAX);
- emission_shape = p_shape;
-}
-
-void CPUParticles::set_emission_sphere_radius(float p_radius) {
- emission_sphere_radius = p_radius;
-}
-
-void CPUParticles::set_emission_box_extents(Vector3 p_extents) {
- emission_box_extents = p_extents;
-}
-
-void CPUParticles::set_emission_points(const PoolVector &p_points) {
- emission_points = p_points;
-}
-
-void CPUParticles::set_emission_normals(const PoolVector &p_normals) {
- emission_normals = p_normals;
-}
-
-void CPUParticles::set_emission_colors(const PoolVector &p_colors) {
- emission_colors = p_colors;
-}
-void CPUParticles::set_emission_ring_height(float p_height) {
- emission_ring_height = p_height;
-}
-
-void CPUParticles::set_emission_ring_radius(float p_radius) {
- emission_ring_radius = p_radius;
-}
-
-void CPUParticles::set_emission_ring_inner_radius(float p_offset) {
- emission_ring_inner_radius = p_offset;
-}
-
-void CPUParticles::set_emission_ring_axis(Vector3 p_axis) {
- emission_ring_axis = p_axis;
-}
-
-float CPUParticles::get_emission_sphere_radius() const {
- return emission_sphere_radius;
-}
-Vector3 CPUParticles::get_emission_box_extents() const {
- return emission_box_extents;
-}
-PoolVector CPUParticles::get_emission_points() const {
- return emission_points;
-}
-PoolVector CPUParticles::get_emission_normals() const {
- return emission_normals;
-}
-
-PoolVector CPUParticles::get_emission_colors() const {
- return emission_colors;
-}
-
-float CPUParticles::get_emission_ring_height() const {
- return emission_ring_height;
-}
-
-float CPUParticles::get_emission_ring_inner_radius() const {
- return emission_ring_inner_radius;
-}
-
-float CPUParticles::get_emission_ring_radius() const {
- return emission_ring_radius;
-}
-
-Vector3 CPUParticles::get_emission_ring_axis() const {
- return emission_ring_axis;
-}
-
-CPUParticles::EmissionShape CPUParticles::get_emission_shape() const {
- return emission_shape;
-}
-void CPUParticles::set_gravity(const Vector3 &p_gravity) {
- gravity = p_gravity;
-}
-
-Vector3 CPUParticles::get_gravity() const {
- return gravity;
-}
-
-void CPUParticles::_validate_property(PropertyInfo &property) const {
- if (property.name == "emission_sphere_radius" && emission_shape != EMISSION_SHAPE_SPHERE) {
- property.usage = 0;
- }
-
- if (property.name == "emission_box_extents" && emission_shape != EMISSION_SHAPE_BOX) {
- property.usage = 0;
- }
-
- if ((property.name == "emission_points" || property.name == "emission_colors") && (emission_shape != EMISSION_SHAPE_POINTS) && (emission_shape != EMISSION_SHAPE_DIRECTED_POINTS)) {
- property.usage = 0;
- }
-
- if (property.name == "emission_normals" && emission_shape != EMISSION_SHAPE_DIRECTED_POINTS) {
- property.usage = 0;
- }
-
- if (property.name.begins_with("emission_ring") && emission_shape != EMISSION_SHAPE_RING) {
- property.usage = 0;
- }
-
- if (property.name.begins_with("orbit_") && !flags[FLAG_DISABLE_Z]) {
- property.usage = 0;
- }
-}
-
-static uint32_t idhash(uint32_t x) {
- x = ((x >> uint32_t(16)) ^ x) * uint32_t(0x45d9f3b);
- x = ((x >> uint32_t(16)) ^ x) * uint32_t(0x45d9f3b);
- x = (x >> uint32_t(16)) ^ x;
- return x;
-}
-
-static float rand_from_seed(uint32_t &seed) {
- int k;
- int s = int(seed);
- if (s == 0) {
- s = 305420679;
- }
- k = s / 127773;
- s = 16807 * (s - k * 127773) - 2836 * k;
- if (s < 0) {
- s += 2147483647;
- }
- seed = uint32_t(s);
- return float(seed % uint32_t(65536)) / 65535.0;
-}
-
-void CPUParticles::_update_internal(bool p_on_physics_tick) {
- if (particles.size() == 0 || !is_visible_in_tree()) {
- _set_redraw(false);
- return;
- }
-
- // change update mode?
- _refresh_interpolation_state();
-
- float delta = 0.0f;
-
- // Is this update occurring on a physics tick (i.e. interpolated), or a frame tick?
- if (p_on_physics_tick) {
- delta = get_physics_process_delta_time();
- } else {
- delta = get_process_delta_time();
- }
- if (emitting) {
- inactive_time = 0;
- } else {
- inactive_time += delta;
- if (inactive_time > lifetime * 1.2) {
- _set_particles_processing(false);
- _set_redraw(false);
-
- //reset variables
- time = 0;
- inactive_time = 0;
- frame_remainder = 0;
- cycle = 0;
- return;
- }
- }
- _set_redraw(true);
-
- bool processed = false;
-
- if (time == 0 && pre_process_time > 0.0) {
- float frame_time;
- if (fixed_fps > 0) {
- frame_time = 1.0 / fixed_fps;
- } else {
- frame_time = 1.0 / 30.0;
- }
-
- float todo = pre_process_time;
-
- while (todo >= 0) {
- _particles_process(frame_time);
- processed = true;
- todo -= frame_time;
- }
- }
-
- if (fixed_fps > 0) {
- float frame_time = 1.0 / fixed_fps;
- float decr = frame_time;
-
- float ldelta = delta;
- if (ldelta > 0.1) { //avoid recursive stalls if fps goes below 10
- ldelta = 0.1;
- } else if (ldelta <= 0.0) { //unlikely but..
- ldelta = 0.001;
- }
- float todo = frame_remainder + ldelta;
-
- while (todo >= frame_time) {
- _particles_process(frame_time);
- processed = true;
- todo -= decr;
- }
-
- frame_remainder = todo;
-
- } else {
- _particles_process(delta);
- processed = true;
- }
-
- if (processed) {
- _update_particle_data_buffer();
- }
-
- // If we are interpolating, we send the data to the RenderingServer
- // right away on a physics tick instead of waiting until a render frame.
- if (p_on_physics_tick && redraw) {
- _update_render_thread();
- }
-}
-
-void CPUParticles::_particles_process(float p_delta) {
- p_delta *= speed_scale;
-
- int pcount = particles.size();
- PoolVector::Write w = particles.write();
-
- Particle *parray = w.ptr();
-
- float prev_time = time;
- time += p_delta;
- if (time > lifetime) {
- time = Math::fmod(time, lifetime);
- cycle++;
- if (one_shot && cycle > 0) {
- set_emitting(false);
- _change_notify();
- }
- }
-
- Transform emission_xform;
- Basis velocity_xform;
- if (!local_coords) {
- emission_xform = get_global_transform();
- velocity_xform = emission_xform.basis;
- }
-
- float system_phase = time / lifetime;
- real_t physics_tick_delta = 1.0 / Engine::get_singleton()->get_physics_ticks_per_second();
-
- // Streaky particles can "prime" started particles by placing them back in time
- // from the current physics tick, to place them in the position they would have reached
- // had they been created in an infinite timestream (rather than at fixed iteration times).
- bool streaky = _streaky && _interpolated && fractional_delta;
- real_t streak_fraction = 1.0f;
-
- for (int i = 0; i < pcount; i++) {
- Particle &p = parray[i];
-
- if (!emitting && !p.active) {
- continue;
- }
-
- // For interpolation we need to keep a record of previous particles
- if (_interpolated) {
- p.copy_to(particles_prev[i]);
- }
-
- float local_delta = p_delta;
-
- // The phase is a ratio between 0 (birth) and 1 (end of life) for each particle.
- // While we use time in tests later on, for randomness we use the phase as done in the
- // original shader code, and we later multiply by lifetime to get the time.
- float restart_phase = float(i) / float(pcount);
-
- if (randomness_ratio > 0.0) {
- uint32_t seed = cycle;
- if (restart_phase >= system_phase) {
- seed -= uint32_t(1);
- }
- seed *= uint32_t(pcount);
- seed += uint32_t(i);
- float random = float(idhash(seed) % uint32_t(65536)) / 65536.0;
- restart_phase += randomness_ratio * random * 1.0 / float(pcount);
- }
-
- restart_phase *= (1.0 - explosiveness_ratio);
- float restart_time = restart_phase * lifetime;
- bool restart = false;
-
- if (time > prev_time) {
- // restart_time >= prev_time is used so particles emit in the first frame they are processed
-
- if (restart_time >= prev_time && restart_time < time) {
- restart = true;
- if (fractional_delta) {
- local_delta = time - restart_time;
- }
- }
-
- } else if (local_delta > 0.0) {
- if (restart_time >= prev_time) {
- restart = true;
- if (fractional_delta) {
- local_delta = lifetime - restart_time + time;
- }
-
- } else if (restart_time < time) {
- restart = true;
- if (fractional_delta) {
- local_delta = time - restart_time;
- }
- }
- }
-
- // Normal condition for a starting particle, allow priming.
- // Possibly test emitting flag here too, if profiling shows it helps.
- if (streaky && restart) {
- streak_fraction = local_delta / physics_tick_delta;
- streak_fraction = CLAMP(streak_fraction, 0.0f, 1.0f);
- }
-
- if (p.time * (1.0 - explosiveness_ratio) > p.lifetime) {
- restart = true;
-
- // Not absolutely sure on this, may be able to streak this case,
- // but turning off in case this is expected to be a similar timed
- // explosion.
- if (streaky) {
- streak_fraction = 1.0f;
- }
- }
-
- float tv = 0.0;
-
- if (restart) {
- if (!emitting) {
- p.active = false;
- continue;
- }
- p.active = true;
-
- /*float tex_linear_velocity = 0;
- if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
- tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(0);
- }*/
-
- float tex_angle = 0.0;
- if (curve_parameters[PARAM_ANGLE].is_valid()) {
- tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv);
- }
-
- float tex_anim_offset = 0.0;
- if (curve_parameters[PARAM_ANGLE].is_valid()) {
- tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(tv);
- }
-
- p.seed = Math::rand();
-
- p.angle_rand = Math::randf();
- p.scale_rand = Math::randf();
- p.hue_rot_rand = Math::randf();
- p.anim_offset_rand = Math::randf();
-
- if (color_initial_ramp.is_valid()) {
- p.start_color_rand = color_initial_ramp->get_color_at_offset(Math::randf());
- } else {
- p.start_color_rand = Color(1, 1, 1, 1);
- }
-
- if (flags[FLAG_DISABLE_Z]) {
- float angle1_rad = Math::atan2(direction.y, direction.x) + (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0;
- Vector3 rot = Vector3(Math::cos(angle1_rad), Math::sin(angle1_rad), 0.0);
- p.velocity = rot * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp(1.0f, float(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]);
- } else {
- //initiate velocity spread in 3D
- float angle1_rad = (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0;
- float angle2_rad = (Math::randf() * 2.0 - 1.0) * (1.0 - flatness) * Math_PI * spread / 180.0;
-
- Vector3 direction_xz = Vector3(Math::sin(angle1_rad), 0, Math::cos(angle1_rad));
- Vector3 direction_yz = Vector3(0, Math::sin(angle2_rad), Math::cos(angle2_rad));
- Vector3 spread_direction = Vector3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);
- Vector3 direction_nrm = direction;
- if (direction_nrm.length_squared() > 0) {
- direction_nrm.normalize();
- } else {
- direction_nrm = Vector3(0, 0, 1);
- }
- // rotate spread to direction
- Vector3 binormal = Vector3(0.0, 1.0, 0.0).cross(direction_nrm);
- if (binormal.length_squared() < 0.00000001) {
- // direction is parallel to Y. Choose Z as the binormal.
- binormal = Vector3(0.0, 0.0, 1.0);
- }
- binormal.normalize();
- Vector3 normal = binormal.cross(direction_nrm);
- spread_direction = binormal * spread_direction.x + normal * spread_direction.y + direction_nrm * spread_direction.z;
- p.velocity = spread_direction * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp(1.0f, float(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]);
- }
-
- float base_angle = (parameters[PARAM_ANGLE] + tex_angle) * Math::lerp(1.0f, p.angle_rand, randomness[PARAM_ANGLE]);
- p.custom[0] = Math::deg2rad(base_angle); //angle
- p.custom[1] = 0.0; //phase
- p.custom[2] = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp(1.0f, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]); //animation offset (0-1)
- p.transform = Transform();
- p.time = 0;
- p.lifetime = lifetime * (1.0 - Math::randf() * lifetime_randomness);
- p.base_color = Color(1, 1, 1, 1);
-
- switch (emission_shape) {
- case EMISSION_SHAPE_POINT: {
- //do none
- } break;
- case EMISSION_SHAPE_SPHERE: {
- float s = 2.0 * Math::randf() - 1.0, t = 2.0 * Math_PI * Math::randf();
- float radius = emission_sphere_radius * Math::sqrt(1.0 - s * s);
- p.transform.origin = Vector3(radius * Math::cos(t), radius * Math::sin(t), emission_sphere_radius * s);
- } break;
- case EMISSION_SHAPE_BOX: {
- p.transform.origin = Vector3(Math::randf() * 2.0 - 1.0, Math::randf() * 2.0 - 1.0, Math::randf() * 2.0 - 1.0) * emission_box_extents;
- } break;
- case EMISSION_SHAPE_POINTS:
- case EMISSION_SHAPE_DIRECTED_POINTS: {
- int pc = emission_points.size();
- if (pc == 0) {
- break;
- }
-
- int random_idx = Math::rand() % pc;
-
- p.transform.origin = emission_points.get(random_idx);
-
- if (emission_shape == EMISSION_SHAPE_DIRECTED_POINTS && emission_normals.size() == pc) {
- if (flags[FLAG_DISABLE_Z]) {
- Vector3 normal = emission_normals.get(random_idx);
- Vector2 normal_2d(normal.x, normal.y);
- Transform2D m2;
- m2.set_axis(0, normal_2d);
- m2.set_axis(1, normal_2d.tangent());
- Vector2 velocity_2d(p.velocity.x, p.velocity.y);
- velocity_2d = m2.basis_xform(velocity_2d);
- p.velocity.x = velocity_2d.x;
- p.velocity.y = velocity_2d.y;
- } else {
- Vector3 normal = emission_normals.get(random_idx);
- Vector3 v0 = Math::abs(normal.z) < 0.999 ? Vector3(0.0, 0.0, 1.0) : Vector3(0, 1.0, 0.0);
- Vector3 tangent = v0.cross(normal).normalized();
- Vector3 bitangent = tangent.cross(normal).normalized();
- Basis m3;
- m3.set_axis(0, tangent);
- m3.set_axis(1, bitangent);
- m3.set_axis(2, normal);
- p.velocity = m3.xform(p.velocity);
- }
- }
-
- if (emission_colors.size() == pc) {
- p.base_color = emission_colors.get(random_idx);
- }
- } break;
- case EMISSION_SHAPE_RING: {
- float ring_random_angle = Math::randf() * 2.0 * Math_PI;
- float ring_random_radius = Math::randf() * (emission_ring_radius - emission_ring_inner_radius) + emission_ring_inner_radius;
- Vector3 axis = emission_ring_axis.normalized();
- Vector3 ortho_axis = Vector3();
- if (axis == Vector3(1.0, 0.0, 0.0)) {
- ortho_axis = Vector3(0.0, 1.0, 0.0).cross(axis);
- } else {
- ortho_axis = Vector3(1.0, 0.0, 0.0).cross(axis);
- }
- ortho_axis = ortho_axis.normalized();
- ortho_axis.rotate(axis, ring_random_angle);
- ortho_axis = ortho_axis.normalized();
- p.transform.origin = ortho_axis * ring_random_radius + (Math::randf() * emission_ring_height - emission_ring_height / 2.0) * axis;
- }
- case EMISSION_SHAPE_MAX: { // Max value for validity check.
- break;
- }
- }
-
- // We could possibly attempt streaking with local_coords as well, but NYI
- if (!local_coords) {
- // Apply streaking interpolation of start positions between ticks
- if (streaky) {
- emission_xform = _get_global_transform_interpolated(streak_fraction);
- velocity_xform = emission_xform.basis;
-
- p.velocity = velocity_xform.xform(p.velocity);
-
- // prime the particle by moving "backward" in time
- real_t adjusted_delta = (1.0f - streak_fraction) * physics_tick_delta;
- _particle_process(p, emission_xform, adjusted_delta, tv);
-
- } else {
- p.velocity = velocity_xform.xform(p.velocity);
- }
-
- p.transform = emission_xform * p.transform;
- }
-
- if (flags[FLAG_DISABLE_Z]) {
- p.velocity.z = 0.0;
- p.transform.origin.z = 0.0;
- }
-
- // Teleport if starting a new particle, so
- // we don't get a streak from the old position
- // to this new start.
- if (_interpolated) {
- p.copy_to(particles_prev[i]);
- }
-
- } else if (!p.active) {
- continue;
- } else if (p.time > p.lifetime) {
- p.active = false;
- tv = 1.0;
- } else {
- _particle_process(p, emission_xform, local_delta, tv);
- }
- //apply color
- //apply hue rotation
-
- float tex_scale = 1.0;
- if (curve_parameters[PARAM_SCALE].is_valid()) {
- tex_scale = curve_parameters[PARAM_SCALE]->interpolate(tv);
- }
-
- float tex_hue_variation = 0.0;
- if (curve_parameters[PARAM_HUE_VARIATION].is_valid()) {
- tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(tv);
- }
-
- float hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_PI * 2.0 * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]);
- float hue_rot_c = Math::cos(hue_rot_angle);
- float hue_rot_s = Math::sin(hue_rot_angle);
-
- Basis hue_rot_mat;
- {
- Basis mat1(0.299, 0.587, 0.114, 0.299, 0.587, 0.114, 0.299, 0.587, 0.114);
- Basis mat2(0.701, -0.587, -0.114, -0.299, 0.413, -0.114, -0.300, -0.588, 0.886);
- Basis mat3(0.168, 0.330, -0.497, -0.328, 0.035, 0.292, 1.250, -1.050, -0.203);
-
- for (int j = 0; j < 3; j++) {
- hue_rot_mat[j] = mat1[j] + mat2[j] * hue_rot_c + mat3[j] * hue_rot_s;
- }
- }
-
- if (color_ramp.is_valid()) {
- p.color = color_ramp->get_color_at_offset(tv) * color;
- } else {
- p.color = color;
- }
-
- Vector3 color_rgb = hue_rot_mat.xform_inv(Vector3(p.color.r, p.color.g, p.color.b));
- p.color.r = color_rgb.x;
- p.color.g = color_rgb.y;
- p.color.b = color_rgb.z;
-
- p.color *= p.base_color * p.start_color_rand;
-
- if (flags[FLAG_DISABLE_Z]) {
- if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) {
- if (p.velocity.length() > 0.0) {
- p.transform.basis.set_axis(1, p.velocity.normalized());
- } else {
- p.transform.basis.set_axis(1, p.transform.basis.get_axis(1));
- }
- p.transform.basis.set_axis(0, p.transform.basis.get_axis(1).cross(p.transform.basis.get_axis(2)).normalized());
- p.transform.basis.set_axis(2, Vector3(0, 0, 1));
-
- } else {
- p.transform.basis.set_axis(0, Vector3(Math::cos(p.custom[0]), -Math::sin(p.custom[0]), 0.0));
- p.transform.basis.set_axis(1, Vector3(Math::sin(p.custom[0]), Math::cos(p.custom[0]), 0.0));
- p.transform.basis.set_axis(2, Vector3(0, 0, 1));
- }
-
- } else {
- //orient particle Y towards velocity
- if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) {
- if (p.velocity.length() > 0.0) {
- p.transform.basis.set_axis(1, p.velocity.normalized());
- } else {
- p.transform.basis.set_axis(1, p.transform.basis.get_axis(1).normalized());
- }
- if (p.transform.basis.get_axis(1) == p.transform.basis.get_axis(0)) {
- p.transform.basis.set_axis(0, p.transform.basis.get_axis(1).cross(p.transform.basis.get_axis(2)).normalized());
- p.transform.basis.set_axis(2, p.transform.basis.get_axis(0).cross(p.transform.basis.get_axis(1)).normalized());
- } else {
- p.transform.basis.set_axis(2, p.transform.basis.get_axis(0).cross(p.transform.basis.get_axis(1)).normalized());
- p.transform.basis.set_axis(0, p.transform.basis.get_axis(1).cross(p.transform.basis.get_axis(2)).normalized());
- }
- } else {
- p.transform.basis.orthonormalize();
- }
-
- //turn particle by rotation in Y
- if (flags[FLAG_ROTATE_Y]) {
- Basis rot_y(Vector3(0, 1, 0), p.custom[0]);
- p.transform.basis = p.transform.basis * rot_y;
- }
- }
-
- //scale by scale
- float base_scale = tex_scale * Math::lerp(parameters[PARAM_SCALE], 1.0f, p.scale_rand * randomness[PARAM_SCALE]);
-
- // Prevent zero scale (which can cause rendering issues).
- base_scale = SGN(base_scale) * MAX(Math::abs(base_scale), 0.000001);
-
- p.transform.basis.scale(Vector3(1, 1, 1) * base_scale);
-
- if (flags[FLAG_DISABLE_Z]) {
- p.velocity.z = 0.0;
- p.transform.origin.z = 0.0;
- }
-
- p.transform.origin += p.velocity * local_delta;
- }
-}
-
-void CPUParticles::_particle_process(Particle &r_p, const Transform &p_emission_xform, float p_local_delta, float &r_tv) {
- uint32_t alt_seed = r_p.seed;
-
- r_p.time += p_local_delta;
- r_p.custom[1] = r_p.time / lifetime;
- r_tv = r_p.time / r_p.lifetime;
-
- float tex_linear_velocity = 0.0;
- if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
- tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(r_tv);
- }
-
- float tex_orbit_velocity = 0.0;
- if (flags[FLAG_DISABLE_Z]) {
- if (curve_parameters[PARAM_ORBIT_VELOCITY].is_valid()) {
- tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(r_tv);
- }
- }
-
- float tex_angular_velocity = 0.0;
- if (curve_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) {
- tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(r_tv);
- }
-
- float tex_linear_accel = 0.0;
- if (curve_parameters[PARAM_LINEAR_ACCEL].is_valid()) {
- tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(r_tv);
- }
-
- float tex_tangential_accel = 0.0;
- if (curve_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) {
- tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(r_tv);
- }
-
- float tex_radial_accel = 0.0;
- if (curve_parameters[PARAM_RADIAL_ACCEL].is_valid()) {
- tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(r_tv);
- }
-
- float tex_damping = 0.0;
- if (curve_parameters[PARAM_DAMPING].is_valid()) {
- tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(r_tv);
- }
-
- float tex_angle = 0.0;
- if (curve_parameters[PARAM_ANGLE].is_valid()) {
- tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(r_tv);
- }
- float tex_anim_speed = 0.0;
- if (curve_parameters[PARAM_ANIM_SPEED].is_valid()) {
- tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(r_tv);
- }
-
- float tex_anim_offset = 0.0;
- if (curve_parameters[PARAM_ANIM_OFFSET].is_valid()) {
- tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(r_tv);
- }
-
- Vector3 force = gravity;
- Vector3 position = r_p.transform.origin;
- if (flags[FLAG_DISABLE_Z]) {
- position.z = 0.0;
- }
- //apply linear acceleration
- force += r_p.velocity.length() > 0.0 ? r_p.velocity.normalized() * (parameters[PARAM_LINEAR_ACCEL] + tex_linear_accel) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_LINEAR_ACCEL]) : Vector3();
- //apply radial acceleration
- Vector3 org = p_emission_xform.origin;
- Vector3 diff = position - org;
- force += diff.length() > 0.0 ? diff.normalized() * (parameters[PARAM_RADIAL_ACCEL] + tex_radial_accel) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_RADIAL_ACCEL]) : Vector3();
- //apply tangential acceleration;
- if (flags[FLAG_DISABLE_Z]) {
- Vector2 yx = Vector2(diff.y, diff.x);
- Vector2 yx2 = (yx * Vector2(-1.0, 1.0)).normalized();
- force += yx.length() > 0.0 ? Vector3(yx2.x, yx2.y, 0.0) * ((parameters[PARAM_TANGENTIAL_ACCEL] + tex_tangential_accel) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_TANGENTIAL_ACCEL])) : Vector3();
-
- } else {
- Vector3 crossDiff = diff.normalized().cross(gravity.normalized());
- force += crossDiff.length() > 0.0 ? crossDiff.normalized() * ((parameters[PARAM_TANGENTIAL_ACCEL] + tex_tangential_accel) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_TANGENTIAL_ACCEL])) : Vector3();
- }
- //apply attractor forces
- r_p.velocity += force * p_local_delta;
- //orbit velocity
- if (flags[FLAG_DISABLE_Z]) {
- float orbit_amount = (parameters[PARAM_ORBIT_VELOCITY] + tex_orbit_velocity) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_ORBIT_VELOCITY]);
- if (orbit_amount != 0.0) {
- float ang = orbit_amount * p_local_delta * Math_PI * 2.0;
- // Not sure why the ParticlesMaterial code uses a clockwise rotation matrix,
- // but we use -ang here to reproduce its behavior.
- Transform2D rot = Transform2D(-ang, Vector2());
- Vector2 rotv = rot.basis_xform(Vector2(diff.x, diff.y));
- r_p.transform.origin -= Vector3(diff.x, diff.y, 0);
- r_p.transform.origin += Vector3(rotv.x, rotv.y, 0);
- }
- }
- if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
- r_p.velocity = r_p.velocity.normalized() * tex_linear_velocity;
- }
- if (parameters[PARAM_DAMPING] + tex_damping > 0.0) {
- float v = r_p.velocity.length();
- float damp = (parameters[PARAM_DAMPING] + tex_damping) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_DAMPING]);
- v -= damp * p_local_delta;
- if (v < 0.0) {
- r_p.velocity = Vector3();
- } else {
- r_p.velocity = r_p.velocity.normalized() * v;
- }
- }
- float base_angle = (parameters[PARAM_ANGLE] + tex_angle) * Math::lerp(1.0f, r_p.angle_rand, randomness[PARAM_ANGLE]);
- base_angle += r_p.custom[1] * lifetime * (parameters[PARAM_ANGULAR_VELOCITY] + tex_angular_velocity) * Math::lerp(1.0f, rand_from_seed(alt_seed) * 2.0f - 1.0f, randomness[PARAM_ANGULAR_VELOCITY]);
- r_p.custom[0] = Math::deg2rad(base_angle); //angle
- r_p.custom[2] = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp(1.0f, r_p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]) + r_tv * (parameters[PARAM_ANIM_SPEED] + tex_anim_speed) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_ANIM_SPEED]); //angle
-}
-
-void CPUParticles::_update_particle_data_buffer() {
- update_mutex.lock();
-
- {
- int pc = particles.size();
-
- PoolVector::Write ow;
- int *order = nullptr;
-
- PoolVector::Write w = particle_data.write();
- PoolVector::Read r = particles.read();
- float *ptr = w.ptr();
-
- PoolVector::Write w_prev;
- float *ptr_prev = nullptr;
-
- if (_interpolated) {
- w_prev = particle_data_prev.write();
- ptr_prev = w_prev.ptr();
- }
-
- if (draw_order != DRAW_ORDER_INDEX) {
- ow = particle_order.write();
- order = ow.ptr();
-
- for (int i = 0; i < pc; i++) {
- order[i] = i;
- }
- if (draw_order == DRAW_ORDER_LIFETIME) {
- SortArray sorter;
- sorter.compare.particles = r.ptr();
- sorter.sort(order, pc);
- } else if (draw_order == DRAW_ORDER_VIEW_DEPTH) {
- ERR_FAIL_NULL(get_viewport());
- Camera *c = get_viewport()->get_camera();
- if (c) {
- Vector3 dir = c->get_global_transform().basis.get_axis(2); //far away to close
-
- // now if local_coords is not set, the particles are in global coords
- // so should be sorted according to the camera direction
-
- // will look different from Particles in editor as this is based on the camera in the scenetree
- // and not the editor camera
- dir = dir.normalized();
-
- SortArray sorter;
- sorter.compare.particles = r.ptr();
- sorter.compare.axis = dir;
- sorter.sort(order, pc);
- }
- }
- }
-
- if (_interpolated) {
- for (int i = 0; i < pc; i++) {
- int idx = order ? order[i] : i;
- _fill_particle_data(r[idx], ptr, r[idx].active);
- ptr += 17;
- _fill_particle_data(particles_prev[idx], ptr_prev, r[idx].active);
- ptr_prev += 17;
- }
- } else {
- for (int i = 0; i < pc; i++) {
- int idx = order ? order[i] : i;
- _fill_particle_data(r[idx], ptr, r[idx].active);
- ptr += 17;
- }
- }
-
- can_update.set();
- }
-
- update_mutex.unlock();
-}
-
-void CPUParticles::_refresh_interpolation_state() {
- if (!is_inside_tree()) {
- return;
- }
- bool interpolated = is_physics_interpolated_and_enabled();
-
- if (_interpolated == interpolated) {
- return;
- }
-
- bool curr_redraw = redraw;
-
- // Remove all connections
- // This isn't super efficient, but should only happen rarely.
- _set_redraw(false);
-
- _interpolated = interpolated;
-
- if (_interpolated) {
- set_process_internal(false);
- set_physics_process_internal(emitting);
- } else {
- set_physics_process_internal(false);
- set_process_internal(emitting);
- }
-
- // re-establish all connections
- _set_redraw(curr_redraw);
-}
-
-void CPUParticles::_set_redraw(bool p_redraw) {
- if (redraw == p_redraw) {
- return;
- }
- redraw = p_redraw;
- update_mutex.lock();
-
- if (!_interpolated) {
- if (redraw) {
- RS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread");
- } else {
- if (RS::get_singleton()->is_connected("frame_pre_draw", this, "_update_render_thread")) {
- RS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread");
- }
- }
- }
-
- if (redraw) {
- RS::get_singleton()->instance_geometry_set_flag(get_instance(), RS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true);
- RS::get_singleton()->multimesh_set_visible_instances(multimesh, -1);
- } else {
- RS::get_singleton()->instance_geometry_set_flag(get_instance(), RS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, false);
- RS::get_singleton()->multimesh_set_visible_instances(multimesh, 0);
- }
- update_mutex.unlock();
-}
-
-void CPUParticles::_update_render_thread() {
- if (OS::get_singleton()->is_update_pending(true)) {
- update_mutex.lock();
-
- if (can_update.is_set()) {
- if (_interpolated) {
- RS::get_singleton()->multimesh_set_as_bulk_array_interpolated(multimesh, particle_data, particle_data_prev);
- } else {
- RS::get_singleton()->multimesh_set_as_bulk_array(multimesh, particle_data);
- }
- can_update.clear(); //wait for next time
- }
-
- update_mutex.unlock();
- }
-}
-
-void CPUParticles::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE) {
- set_process_internal(emitting);
-
- // first update before rendering to avoid one frame delay after emitting starts
- if (emitting && (time == 0) && !_interpolated) {
- _update_internal(false);
- }
- }
-
- if (p_what == NOTIFICATION_EXIT_TREE) {
- _set_redraw(false);
- }
-
- if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
- // first update before rendering to avoid one frame delay after emitting starts
- if (emitting && (time == 0) && !_interpolated) {
- _update_internal(false);
- }
- }
-
- if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
- _update_internal(false);
- }
-
- if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) {
- _update_internal(true);
- }
-}
-
-void CPUParticles::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_emitting", "emitting"), &CPUParticles::set_emitting);
- ClassDB::bind_method(D_METHOD("set_amount", "amount"), &CPUParticles::set_amount);
- ClassDB::bind_method(D_METHOD("set_lifetime", "secs"), &CPUParticles::set_lifetime);
- ClassDB::bind_method(D_METHOD("set_one_shot", "enable"), &CPUParticles::set_one_shot);
- ClassDB::bind_method(D_METHOD("set_pre_process_time", "secs"), &CPUParticles::set_pre_process_time);
- ClassDB::bind_method(D_METHOD("set_explosiveness_ratio", "ratio"), &CPUParticles::set_explosiveness_ratio);
- ClassDB::bind_method(D_METHOD("set_randomness_ratio", "ratio"), &CPUParticles::set_randomness_ratio);
- ClassDB::bind_method(D_METHOD("set_lifetime_randomness", "random"), &CPUParticles::set_lifetime_randomness);
- ClassDB::bind_method(D_METHOD("set_use_local_coordinates", "enable"), &CPUParticles::set_use_local_coordinates);
- ClassDB::bind_method(D_METHOD("set_fixed_fps", "fps"), &CPUParticles::set_fixed_fps);
- ClassDB::bind_method(D_METHOD("set_fractional_delta", "enable"), &CPUParticles::set_fractional_delta);
- ClassDB::bind_method(D_METHOD("set_speed_scale", "scale"), &CPUParticles::set_speed_scale);
-
- ClassDB::bind_method(D_METHOD("is_emitting"), &CPUParticles::is_emitting);
- ClassDB::bind_method(D_METHOD("get_amount"), &CPUParticles::get_amount);
- ClassDB::bind_method(D_METHOD("get_lifetime"), &CPUParticles::get_lifetime);
- ClassDB::bind_method(D_METHOD("get_one_shot"), &CPUParticles::get_one_shot);
- ClassDB::bind_method(D_METHOD("get_pre_process_time"), &CPUParticles::get_pre_process_time);
- ClassDB::bind_method(D_METHOD("get_explosiveness_ratio"), &CPUParticles::get_explosiveness_ratio);
- ClassDB::bind_method(D_METHOD("get_randomness_ratio"), &CPUParticles::get_randomness_ratio);
- ClassDB::bind_method(D_METHOD("get_lifetime_randomness"), &CPUParticles::get_lifetime_randomness);
- ClassDB::bind_method(D_METHOD("get_use_local_coordinates"), &CPUParticles::get_use_local_coordinates);
- ClassDB::bind_method(D_METHOD("get_fixed_fps"), &CPUParticles::get_fixed_fps);
- ClassDB::bind_method(D_METHOD("get_fractional_delta"), &CPUParticles::get_fractional_delta);
- ClassDB::bind_method(D_METHOD("get_speed_scale"), &CPUParticles::get_speed_scale);
-
- ClassDB::bind_method(D_METHOD("set_draw_order", "order"), &CPUParticles::set_draw_order);
-
- ClassDB::bind_method(D_METHOD("get_draw_order"), &CPUParticles::get_draw_order);
-
- ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &CPUParticles::set_mesh);
- ClassDB::bind_method(D_METHOD("get_mesh"), &CPUParticles::get_mesh);
-
- ClassDB::bind_method(D_METHOD("restart"), &CPUParticles::restart);
-
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_EXP_RANGE, "1,1000000,1"), "set_amount", "get_amount");
- ADD_GROUP("Time", "");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_EXP_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "preprocess", PROPERTY_HINT_EXP_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime_randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_lifetime_randomness", "get_lifetime_randomness");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_fps", PROPERTY_HINT_RANGE, "0,1000,1"), "set_fixed_fps", "get_fixed_fps");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fract_delta"), "set_fractional_delta", "get_fractional_delta");
- ADD_GROUP("Drawing", "");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "local_coords"), "set_use_local_coordinates", "get_use_local_coordinates");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "draw_order", PROPERTY_HINT_ENUM, "Index,Lifetime,View Depth"), "set_draw_order", "get_draw_order");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
-
- BIND_ENUM_CONSTANT(DRAW_ORDER_INDEX);
- BIND_ENUM_CONSTANT(DRAW_ORDER_LIFETIME);
- BIND_ENUM_CONSTANT(DRAW_ORDER_VIEW_DEPTH);
-
- ////////////////////////////////
-
- ClassDB::bind_method(D_METHOD("set_direction", "direction"), &CPUParticles::set_direction);
- ClassDB::bind_method(D_METHOD("get_direction"), &CPUParticles::get_direction);
-
- ClassDB::bind_method(D_METHOD("set_spread", "degrees"), &CPUParticles::set_spread);
- ClassDB::bind_method(D_METHOD("get_spread"), &CPUParticles::get_spread);
-
- ClassDB::bind_method(D_METHOD("set_flatness", "amount"), &CPUParticles::set_flatness);
- ClassDB::bind_method(D_METHOD("get_flatness"), &CPUParticles::get_flatness);
-
- ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &CPUParticles::set_param);
- ClassDB::bind_method(D_METHOD("get_param", "param"), &CPUParticles::get_param);
-
- ClassDB::bind_method(D_METHOD("set_param_randomness", "param", "randomness"), &CPUParticles::set_param_randomness);
- ClassDB::bind_method(D_METHOD("get_param_randomness", "param"), &CPUParticles::get_param_randomness);
-
- ClassDB::bind_method(D_METHOD("set_param_curve", "param", "curve"), &CPUParticles::set_param_curve);
- ClassDB::bind_method(D_METHOD("get_param_curve", "param"), &CPUParticles::get_param_curve);
-
- ClassDB::bind_method(D_METHOD("set_color", "color"), &CPUParticles::set_color);
- ClassDB::bind_method(D_METHOD("get_color"), &CPUParticles::get_color);
-
- ClassDB::bind_method(D_METHOD("set_color_ramp", "ramp"), &CPUParticles::set_color_ramp);
- ClassDB::bind_method(D_METHOD("get_color_ramp"), &CPUParticles::get_color_ramp);
-
- ClassDB::bind_method(D_METHOD("set_color_initial_ramp", "ramp"), &CPUParticles::set_color_initial_ramp);
- ClassDB::bind_method(D_METHOD("get_color_initial_ramp"), &CPUParticles::get_color_initial_ramp);
-
- ClassDB::bind_method(D_METHOD("set_particle_flag", "flag", "enable"), &CPUParticles::set_particle_flag);
- ClassDB::bind_method(D_METHOD("get_particle_flag", "flag"), &CPUParticles::get_particle_flag);
-
- ClassDB::bind_method(D_METHOD("set_emission_shape", "shape"), &CPUParticles::set_emission_shape);
- ClassDB::bind_method(D_METHOD("get_emission_shape"), &CPUParticles::get_emission_shape);
-
- ClassDB::bind_method(D_METHOD("set_emission_sphere_radius", "radius"), &CPUParticles::set_emission_sphere_radius);
- ClassDB::bind_method(D_METHOD("get_emission_sphere_radius"), &CPUParticles::get_emission_sphere_radius);
-
- ClassDB::bind_method(D_METHOD("set_emission_box_extents", "extents"), &CPUParticles::set_emission_box_extents);
- ClassDB::bind_method(D_METHOD("get_emission_box_extents"), &CPUParticles::get_emission_box_extents);
-
- ClassDB::bind_method(D_METHOD("set_emission_points", "array"), &CPUParticles::set_emission_points);
- ClassDB::bind_method(D_METHOD("get_emission_points"), &CPUParticles::get_emission_points);
-
- ClassDB::bind_method(D_METHOD("set_emission_normals", "array"), &CPUParticles::set_emission_normals);
- ClassDB::bind_method(D_METHOD("get_emission_normals"), &CPUParticles::get_emission_normals);
-
- ClassDB::bind_method(D_METHOD("set_emission_colors", "array"), &CPUParticles::set_emission_colors);
- ClassDB::bind_method(D_METHOD("get_emission_colors"), &CPUParticles::get_emission_colors);
-
- ClassDB::bind_method(D_METHOD("set_emission_ring_radius", "radius"), &CPUParticles::set_emission_ring_radius);
- ClassDB::bind_method(D_METHOD("get_emission_ring_radius"), &CPUParticles::get_emission_ring_radius);
-
- ClassDB::bind_method(D_METHOD("set_emission_ring_inner_radius", "offset"), &CPUParticles::set_emission_ring_inner_radius);
- ClassDB::bind_method(D_METHOD("get_emission_ring_inner_radius"), &CPUParticles::get_emission_ring_inner_radius);
-
- ClassDB::bind_method(D_METHOD("set_emission_ring_height", "height"), &CPUParticles::set_emission_ring_height);
- ClassDB::bind_method(D_METHOD("get_emission_ring_height"), &CPUParticles::get_emission_ring_height);
-
- ClassDB::bind_method(D_METHOD("set_emission_ring_axis", "axis"), &CPUParticles::set_emission_ring_axis);
- ClassDB::bind_method(D_METHOD("get_emission_ring_axis"), &CPUParticles::get_emission_ring_axis);
-
- ClassDB::bind_method(D_METHOD("get_gravity"), &CPUParticles::get_gravity);
- ClassDB::bind_method(D_METHOD("set_gravity", "accel_vec"), &CPUParticles::set_gravity);
-
- ClassDB::bind_method(D_METHOD("_update_render_thread"), &CPUParticles::_update_render_thread);
-
- ADD_GROUP("Emission Shape", "emission_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,Points,Directed Points,Ring", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_emission_shape", "get_emission_shape");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01,or_greater"), "set_emission_sphere_radius", "get_emission_sphere_radius");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "emission_box_extents"), "set_emission_box_extents", "get_emission_box_extents");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "emission_points"), "set_emission_points", "get_emission_points");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "emission_normals"), "set_emission_normals", "get_emission_normals");
- ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "emission_colors"), "set_emission_colors", "get_emission_colors");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_ring_radius", PROPERTY_HINT_RANGE, "0.01,1000,0.01,or_greater"), "set_emission_ring_radius", "get_emission_ring_radius");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_ring_inner_radius", PROPERTY_HINT_RANGE, "0.0,1000,0.01,or_greater"), "set_emission_ring_inner_radius", "get_emission_ring_inner_radius");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_ring_height", PROPERTY_HINT_RANGE, "0.0,100,0.01,or_greater"), "set_emission_ring_height", "get_emission_ring_height");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "emission_ring_axis"), "set_emission_ring_axis", "get_emission_ring_axis");
-
- ADD_GROUP("Flags", "flag_");
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_align_y"), "set_particle_flag", "get_particle_flag", FLAG_ALIGN_Y_TO_VELOCITY);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_rotate_y"), "set_particle_flag", "get_particle_flag", FLAG_ROTATE_Y);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_disable_z"), "set_particle_flag", "get_particle_flag", FLAG_DISABLE_Z);
- ADD_GROUP("Direction", "");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "direction"), "set_direction", "get_direction");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "flatness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_flatness", "get_flatness");
- ADD_GROUP("Gravity", "");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity"), "set_gravity", "get_gravity");
- ADD_GROUP("Initial Velocity", "initial_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_INITIAL_LINEAR_VELOCITY);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_INITIAL_LINEAR_VELOCITY);
- ADD_GROUP("Angular Velocity", "angular_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGULAR_VELOCITY);
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angular_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGULAR_VELOCITY);
- ADD_GROUP("Orbit Velocity", "orbit_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "orbit_velocity", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ORBIT_VELOCITY);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "orbit_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ORBIT_VELOCITY);
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orbit_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ORBIT_VELOCITY);
- ADD_GROUP("Linear Accel", "linear_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_LINEAR_ACCEL);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_LINEAR_ACCEL);
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "linear_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_LINEAR_ACCEL);
- ADD_GROUP("Radial Accel", "radial_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "radial_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_RADIAL_ACCEL);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "radial_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_RADIAL_ACCEL);
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "radial_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_RADIAL_ACCEL);
- ADD_GROUP("Tangential Accel", "tangential_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "tangential_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_TANGENTIAL_ACCEL);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "tangential_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_TANGENTIAL_ACCEL);
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "tangential_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_TANGENTIAL_ACCEL);
- ADD_GROUP("Damping", "");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "damping", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_param", "get_param", PARAM_DAMPING);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "damping_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_DAMPING);
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "damping_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_DAMPING);
- ADD_GROUP("Angle", "");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angle", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGLE);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angle_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGLE);
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angle_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGLE);
- ADD_GROUP("Scale", "");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale_amount", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_greater"), "set_param", "get_param", PARAM_SCALE);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale_amount_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_SCALE);
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "scale_amount_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_SCALE);
- ADD_GROUP("Color", "");
- ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_ramp", "get_color_ramp");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_initial_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_initial_ramp", "get_color_initial_ramp");
-
- ADD_GROUP("Hue Variation", "hue_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param", "get_param", PARAM_HUE_VARIATION);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_HUE_VARIATION);
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "hue_variation_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_HUE_VARIATION);
- ADD_GROUP("Animation", "anim_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_speed", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater"), "set_param", "get_param", PARAM_ANIM_SPEED);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_speed_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_SPEED);
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_speed_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANIM_SPEED);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset", PROPERTY_HINT_RANGE, "0,1,0.0001"), "set_param", "get_param", PARAM_ANIM_OFFSET);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset_random", PROPERTY_HINT_RANGE, "0,1,0.0001"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_OFFSET);
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_offset_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANIM_OFFSET);
-
- BIND_ENUM_CONSTANT(PARAM_INITIAL_LINEAR_VELOCITY);
- BIND_ENUM_CONSTANT(PARAM_ANGULAR_VELOCITY);
- BIND_ENUM_CONSTANT(PARAM_ORBIT_VELOCITY);
- BIND_ENUM_CONSTANT(PARAM_LINEAR_ACCEL);
- BIND_ENUM_CONSTANT(PARAM_RADIAL_ACCEL);
- BIND_ENUM_CONSTANT(PARAM_TANGENTIAL_ACCEL);
- BIND_ENUM_CONSTANT(PARAM_DAMPING);
- BIND_ENUM_CONSTANT(PARAM_ANGLE);
- BIND_ENUM_CONSTANT(PARAM_SCALE);
- BIND_ENUM_CONSTANT(PARAM_HUE_VARIATION);
- BIND_ENUM_CONSTANT(PARAM_ANIM_SPEED);
- BIND_ENUM_CONSTANT(PARAM_ANIM_OFFSET);
- BIND_ENUM_CONSTANT(PARAM_MAX);
-
- BIND_ENUM_CONSTANT(FLAG_ALIGN_Y_TO_VELOCITY);
- BIND_ENUM_CONSTANT(FLAG_ROTATE_Y);
- BIND_ENUM_CONSTANT(FLAG_DISABLE_Z);
- BIND_ENUM_CONSTANT(FLAG_MAX);
-
- BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINT);
- BIND_ENUM_CONSTANT(EMISSION_SHAPE_SPHERE);
- BIND_ENUM_CONSTANT(EMISSION_SHAPE_BOX);
- BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINTS);
- BIND_ENUM_CONSTANT(EMISSION_SHAPE_DIRECTED_POINTS);
- BIND_ENUM_CONSTANT(EMISSION_SHAPE_RING);
- BIND_ENUM_CONSTANT(EMISSION_SHAPE_MAX);
-}
-
-CPUParticles::CPUParticles() {
- time = 0;
- inactive_time = 0;
- frame_remainder = 0;
- cycle = 0;
- redraw = false;
- emitting = false;
-
- set_notify_transform(true);
-
- multimesh = RID_PRIME(RenderingServer::get_singleton()->multimesh_create());
- RenderingServer::get_singleton()->multimesh_set_visible_instances(multimesh, 0);
- set_base(multimesh);
-
- set_emitting(true);
- set_one_shot(false);
- set_amount(8);
- set_lifetime(1);
- set_fixed_fps(0);
- set_fractional_delta(true);
- set_pre_process_time(0);
- set_explosiveness_ratio(0);
- set_randomness_ratio(0);
- set_lifetime_randomness(0);
- set_use_local_coordinates(true);
-
- set_draw_order(DRAW_ORDER_INDEX);
- set_speed_scale(1);
-
- set_direction(Vector3(1, 0, 0));
- set_spread(45);
- set_flatness(0);
- set_param(PARAM_INITIAL_LINEAR_VELOCITY, 0);
- set_param(PARAM_ANGULAR_VELOCITY, 0);
- set_param(PARAM_ORBIT_VELOCITY, 0);
- set_param(PARAM_LINEAR_ACCEL, 0);
- set_param(PARAM_RADIAL_ACCEL, 0);
- set_param(PARAM_TANGENTIAL_ACCEL, 0);
- set_param(PARAM_DAMPING, 0);
- set_param(PARAM_ANGLE, 0);
- set_param(PARAM_SCALE, 1);
- set_param(PARAM_HUE_VARIATION, 0);
- set_param(PARAM_ANIM_SPEED, 0);
- set_param(PARAM_ANIM_OFFSET, 0);
- set_emission_shape(EMISSION_SHAPE_POINT);
- set_emission_sphere_radius(1);
- set_emission_box_extents(Vector3(1, 1, 1));
- set_emission_ring_height(1.0);
- set_emission_ring_radius(1.0);
- set_emission_ring_inner_radius(0.0);
- set_emission_ring_axis(Vector3(0.0, 0.0, 1.0));
-
- set_gravity(Vector3(0, -9.8, 0));
-
- for (int i = 0; i < PARAM_MAX; i++) {
- set_param_randomness(Parameter(i), 0);
- }
-
- for (int i = 0; i < FLAG_MAX; i++) {
- flags[i] = false;
- }
-
- set_color(Color(1, 1, 1, 1));
-}
-
-CPUParticles::~CPUParticles() {
- RS::get_singleton()->free(multimesh);
-}
diff --git a/scene/3d/cpu_particles.h b/scene/3d/cpu_particles.h
deleted file mode 100644
index 60bc872..0000000
--- a/scene/3d/cpu_particles.h
+++ /dev/null
@@ -1,367 +0,0 @@
-#ifndef CPU_PARTICLES_H
-#define CPU_PARTICLES_H
-/*************************************************************************/
-/* cpu_particles.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "core/object/reference.h"
-#include "core/containers/rid.h"
-#include "core/os/safe_refcount.h"
-#include "scene/3d/visual_instance.h"
-
-class Curve;
-class Gradient;
-
-class CPUParticles : public GeometryInstance {
-private:
- GDCLASS(CPUParticles, GeometryInstance);
-
-public:
- enum DrawOrder {
- DRAW_ORDER_INDEX,
- DRAW_ORDER_LIFETIME,
- DRAW_ORDER_VIEW_DEPTH,
- DRAW_ORDER_MAX
- };
-
- enum Parameter {
-
- PARAM_INITIAL_LINEAR_VELOCITY,
- PARAM_ANGULAR_VELOCITY,
- PARAM_ORBIT_VELOCITY,
- PARAM_LINEAR_ACCEL,
- PARAM_RADIAL_ACCEL,
- PARAM_TANGENTIAL_ACCEL,
- PARAM_DAMPING,
- PARAM_ANGLE,
- PARAM_SCALE,
- PARAM_HUE_VARIATION,
- PARAM_ANIM_SPEED,
- PARAM_ANIM_OFFSET,
- PARAM_MAX
- };
-
- enum Flags {
- FLAG_ALIGN_Y_TO_VELOCITY,
- FLAG_ROTATE_Y,
- FLAG_DISABLE_Z,
- FLAG_MAX
- };
-
- enum EmissionShape {
- EMISSION_SHAPE_POINT,
- EMISSION_SHAPE_SPHERE,
- EMISSION_SHAPE_BOX,
- EMISSION_SHAPE_POINTS,
- EMISSION_SHAPE_DIRECTED_POINTS,
- EMISSION_SHAPE_RING,
- EMISSION_SHAPE_MAX
- };
-
-private:
- bool emitting;
-
- // Previous minimal data for the particle,
- // for interpolation.
- struct ParticleBase {
- void blank() {
- for (int n = 0; n < 4; n++) {
- custom[n] = 0.0;
- }
- }
- Transform transform;
- Color color;
- float custom[4];
- };
-
- struct Particle : public ParticleBase {
- void copy_to(ParticleBase &r_o) {
- r_o.transform = transform;
- r_o.color = color;
- memcpy(r_o.custom, custom, sizeof(custom));
- }
- Vector3 velocity;
- bool active;
- float angle_rand;
- float scale_rand;
- float hue_rot_rand;
- float anim_offset_rand;
- Color start_color_rand;
- float time;
- float lifetime;
- Color base_color;
-
- uint32_t seed;
- };
-
- float time;
- float inactive_time;
- float frame_remainder;
- int cycle;
- bool redraw;
-
- RID multimesh;
-
- PoolVector particles;
- LocalVector particles_prev;
- PoolVector particle_data;
- PoolVector particle_data_prev;
- PoolVector particle_order;
-
- struct SortLifetime {
- const Particle *particles;
-
- bool operator()(int p_a, int p_b) const {
- return particles[p_a].time > particles[p_b].time;
- }
- };
-
- struct SortAxis {
- const Particle *particles;
- Vector3 axis;
- bool operator()(int p_a, int p_b) const {
- return axis.dot(particles[p_a].transform.origin) < axis.dot(particles[p_b].transform.origin);
- }
- };
-
- //
-
- bool one_shot;
-
- float lifetime;
- float pre_process_time;
- float explosiveness_ratio;
- float randomness_ratio;
- float lifetime_randomness;
- float speed_scale;
- bool local_coords;
- int fixed_fps;
- bool fractional_delta;
-
- SafeFlag can_update;
-
- DrawOrder draw_order;
-
- Ref mesh;
-
- ////////
-
- Vector3 direction;
- float spread;
- float flatness;
-
- float parameters[PARAM_MAX];
- float randomness[PARAM_MAX];
-
- Ref curve_parameters[PARAM_MAX];
- Color color;
- Ref color_ramp;
- Ref color_initial_ramp;
-
- bool flags[FLAG_MAX];
-
- EmissionShape emission_shape;
- float emission_sphere_radius;
- Vector3 emission_box_extents;
- PoolVector emission_points;
- PoolVector emission_normals;
- PoolVector emission_colors;
- int emission_point_count;
- float emission_ring_height;
- float emission_ring_inner_radius;
- float emission_ring_radius;
- Vector3 emission_ring_axis;
-
- Vector3 gravity;
-
- void _update_internal(bool p_on_physics_tick);
- void _particles_process(float p_delta);
- void _particle_process(Particle &r_p, const Transform &p_emission_xform, float p_local_delta, float &r_tv);
- void _update_particle_data_buffer();
-
- Mutex update_mutex;
- bool _interpolated = false;
-
- // Hard coded to true for now, if we decide after testing to always enable this
- // when using interpolation we can remove the variable, else we can expose to the UI.
- bool _streaky = true;
-
- void _update_render_thread();
-
- void _set_redraw(bool p_redraw);
- void _set_particles_processing(bool p_enable);
- void _refresh_interpolation_state();
-
- void _fill_particle_data(const ParticleBase &p_source, float *r_dest, bool p_active) const {
- const Transform &t = p_source.transform;
-
- if (p_active) {
- r_dest[0] = t.basis.rows[0][0];
- r_dest[1] = t.basis.rows[0][1];
- r_dest[2] = t.basis.rows[0][2];
- r_dest[3] = t.origin.x;
- r_dest[4] = t.basis.rows[1][0];
- r_dest[5] = t.basis.rows[1][1];
- r_dest[6] = t.basis.rows[1][2];
- r_dest[7] = t.origin.y;
- r_dest[8] = t.basis.rows[2][0];
- r_dest[9] = t.basis.rows[2][1];
- r_dest[10] = t.basis.rows[2][2];
- r_dest[11] = t.origin.z;
- } else {
- memset(r_dest, 0, sizeof(float) * 12);
- }
-
- Color c = p_source.color;
- uint8_t *data8 = (uint8_t *)&r_dest[12];
- data8[0] = CLAMP(c.r * 255.0, 0, 255);
- data8[1] = CLAMP(c.g * 255.0, 0, 255);
- data8[2] = CLAMP(c.b * 255.0, 0, 255);
- data8[3] = CLAMP(c.a * 255.0, 0, 255);
-
- r_dest[13] = p_source.custom[0];
- r_dest[14] = p_source.custom[1];
- r_dest[15] = p_source.custom[2];
- r_dest[16] = p_source.custom[3];
- }
-
-protected:
- static void _bind_methods();
- void _notification(int p_what);
- virtual void _validate_property(PropertyInfo &property) const;
-
-public:
- AABB get_aabb() const;
- PoolVector get_faces(uint32_t p_usage_flags) const;
-
- void set_emitting(bool p_emitting);
- void set_amount(int p_amount);
- void set_lifetime(float p_lifetime);
- void set_one_shot(bool p_one_shot);
- void set_pre_process_time(float p_time);
- void set_explosiveness_ratio(float p_ratio);
- void set_randomness_ratio(float p_ratio);
- void set_lifetime_randomness(float p_random);
- void set_use_local_coordinates(bool p_enable);
- void set_speed_scale(float p_scale);
-
- bool is_emitting() const;
- int get_amount() const;
- float get_lifetime() const;
- bool get_one_shot() const;
- float get_pre_process_time() const;
- float get_explosiveness_ratio() const;
- float get_randomness_ratio() const;
- float get_lifetime_randomness() const;
- bool get_use_local_coordinates() const;
- float get_speed_scale() const;
-
- void set_fixed_fps(int p_count);
- int get_fixed_fps() const;
-
- void set_fractional_delta(bool p_enable);
- bool get_fractional_delta() const;
-
- void set_draw_order(DrawOrder p_order);
- DrawOrder get_draw_order() const;
-
- void set_mesh(const Ref &p_mesh);
- Ref get_mesh() const;
-
- ///////////////////
-
- void set_direction(Vector3 p_direction);
- Vector3 get_direction() const;
-
- void set_spread(float p_spread);
- float get_spread() const;
-
- void set_flatness(float p_flatness);
- float get_flatness() const;
-
- void set_param(Parameter p_param, float p_value);
- float get_param(Parameter p_param) const;
-
- void set_param_randomness(Parameter p_param, float p_value);
- float get_param_randomness(Parameter p_param) const;
-
- void set_param_curve(Parameter p_param, const Ref &p_curve);
- Ref get_param_curve(Parameter p_param) const;
-
- void set_color(const Color &p_color);
- Color get_color() const;
-
- void set_color_ramp(const Ref &p_ramp);
- Ref get_color_ramp() const;
-
- void set_color_initial_ramp(const Ref &p_ramp);
- Ref get_color_initial_ramp() const;
-
- void set_particle_flag(Flags p_flag, bool p_enable);
- bool get_particle_flag(Flags p_flag) const;
-
- void set_emission_shape(EmissionShape p_shape);
- void set_emission_sphere_radius(float p_radius);
- void set_emission_box_extents(Vector3 p_extents);
- void set_emission_points(const PoolVector &p_points);
- void set_emission_normals(const PoolVector &p_normals);
- void set_emission_colors(const PoolVector &p_colors);
- void set_emission_ring_height(float p_height);
- void set_emission_ring_inner_radius(float p_inner_radius);
- void set_emission_ring_radius(float p_radius);
- void set_emission_ring_axis(Vector3 p_axis);
-
- EmissionShape get_emission_shape() const;
- float get_emission_sphere_radius() const;
- Vector3 get_emission_box_extents() const;
- PoolVector get_emission_points() const;
- PoolVector get_emission_normals() const;
- PoolVector get_emission_colors() const;
- float get_emission_ring_height() const;
- float get_emission_ring_inner_radius() const;
- float get_emission_ring_radius() const;
- Vector3 get_emission_ring_axis() const;
-
- void set_gravity(const Vector3 &p_gravity);
- Vector3 get_gravity() const;
-
- virtual String get_configuration_warning() const;
-
- void restart();
-
- CPUParticles();
- ~CPUParticles();
-};
-
-VARIANT_ENUM_CAST(CPUParticles::DrawOrder)
-VARIANT_ENUM_CAST(CPUParticles::Parameter)
-VARIANT_ENUM_CAST(CPUParticles::Flags)
-VARIANT_ENUM_CAST(CPUParticles::EmissionShape)
-
-#endif // CPU_PARTICLES_H
diff --git a/scene/3d/cull_instance.cpp b/scene/3d/cull_instance.cpp
deleted file mode 100644
index a8100e3..0000000
--- a/scene/3d/cull_instance.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*************************************************************************/
-/* cull_instance.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "cull_instance.h"
-
-VARIANT_ENUM_CAST(CullInstance::PortalMode);
-
-void CullInstance::set_portal_mode(CullInstance::PortalMode p_mode) {
- _portal_mode = p_mode;
- _refresh_portal_mode();
-}
-
-CullInstance::PortalMode CullInstance::get_portal_mode() const {
- return _portal_mode;
-}
-
-void CullInstance::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_portal_mode", "mode"), &CullInstance::set_portal_mode);
- ClassDB::bind_method(D_METHOD("get_portal_mode"), &CullInstance::get_portal_mode);
-
- ClassDB::bind_method(D_METHOD("set_include_in_bound", "enabled"), &CullInstance::set_include_in_bound);
- ClassDB::bind_method(D_METHOD("get_include_in_bound"), &CullInstance::get_include_in_bound);
-
- ClassDB::bind_method(D_METHOD("set_allow_merging", "enabled"), &CullInstance::set_allow_merging);
- ClassDB::bind_method(D_METHOD("get_allow_merging"), &CullInstance::get_allow_merging);
-
- ClassDB::bind_method(D_METHOD("set_portal_autoplace_priority", "priority"), &CullInstance::set_portal_autoplace_priority);
- ClassDB::bind_method(D_METHOD("get_portal_autoplace_priority"), &CullInstance::get_portal_autoplace_priority);
-
- ADD_GROUP("Portals", "");
-
- BIND_ENUM_CONSTANT(PORTAL_MODE_STATIC);
- BIND_ENUM_CONSTANT(PORTAL_MODE_DYNAMIC);
- BIND_ENUM_CONSTANT(PORTAL_MODE_ROAMING);
- BIND_ENUM_CONSTANT(PORTAL_MODE_GLOBAL);
- BIND_ENUM_CONSTANT(PORTAL_MODE_IGNORE);
-
- ADD_PROPERTY(PropertyInfo(Variant::INT, "portal_mode", PROPERTY_HINT_ENUM, "Static,Dynamic,Roaming,Global,Ignore"), "set_portal_mode", "get_portal_mode");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "include_in_bound"), "set_include_in_bound", "get_include_in_bound");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_merging"), "set_allow_merging", "get_allow_merging");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "autoplace_priority", PROPERTY_HINT_RANGE, "-16,16,1", PROPERTY_USAGE_DEFAULT), "set_portal_autoplace_priority", "get_portal_autoplace_priority");
-}
-
-CullInstance::CullInstance() {
- _portal_mode = PORTAL_MODE_STATIC;
- _include_in_bound = true;
- _allow_merging = true;
- _portal_autoplace_priority = 0;
-}
diff --git a/scene/3d/cull_instance.h b/scene/3d/cull_instance.h
deleted file mode 100644
index 03097f3..0000000
--- a/scene/3d/cull_instance.h
+++ /dev/null
@@ -1,80 +0,0 @@
-#ifndef CULL_INSTANCE_H
-#define CULL_INSTANCE_H
-/*************************************************************************/
-/* cull_instance.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "scene/main/spatial.h"
-
-class CullInstance : public Spatial {
- GDCLASS(CullInstance, Spatial);
-
-public:
- enum PortalMode {
- PORTAL_MODE_STATIC, // not moving within a room
- PORTAL_MODE_DYNAMIC, // moving within room
- PORTAL_MODE_ROAMING, // moving between rooms
- PORTAL_MODE_GLOBAL, // frustum culled only
- PORTAL_MODE_IGNORE, // don't show at all - e.g. manual bounds, hidden portals
- };
-
- void set_portal_mode(CullInstance::PortalMode p_mode);
- CullInstance::PortalMode get_portal_mode() const;
-
- void set_include_in_bound(bool p_enabled) { _include_in_bound = p_enabled; }
- bool get_include_in_bound() const { return _include_in_bound; }
-
- void set_allow_merging(bool p_enabled) { _allow_merging = p_enabled; }
- bool get_allow_merging() const { return _allow_merging; }
-
- void set_portal_autoplace_priority(int p_priority) { _portal_autoplace_priority = p_priority; }
- int get_portal_autoplace_priority() const { return _portal_autoplace_priority; }
-
- CullInstance();
-
-protected:
- virtual void _refresh_portal_mode() = 0;
-
- static void _bind_methods();
-
-private:
- PortalMode _portal_mode;
- bool _include_in_bound : 1;
- bool _allow_merging : 1;
-
- // Allows instances to prefer to be autoplaced
- // in specific RoomGroups. This allows building exteriors
- // to be autoplaced in outside RoomGroups, allowing a complete
- // exterior / interior of building in one reusable Scene.
- // The default value 0 gives no preference (chooses the highest priority).
- // All other values will autoplace in the selected RoomGroup priority by preference.
- int _portal_autoplace_priority;
-};
-
-#endif
diff --git a/scene/3d/immediate_geometry.cpp b/scene/3d/immediate_geometry.cpp
deleted file mode 100644
index 53fd7d7..0000000
--- a/scene/3d/immediate_geometry.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-/*************************************************************************/
-/* immediate_geometry.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "immediate_geometry.h"
-
-void ImmediateGeometry::begin(Mesh::PrimitiveType p_primitive, const Ref &p_texture) {
- RS::get_singleton()->immediate_begin(im, (RS::PrimitiveType)p_primitive, p_texture.is_valid() ? p_texture->get_rid() : RID());
- if (p_texture.is_valid()) {
- cached_textures.push_back(p_texture);
- }
-}
-
-void ImmediateGeometry::set_normal(const Vector3 &p_normal) {
- RS::get_singleton()->immediate_normal(im, p_normal);
-}
-
-void ImmediateGeometry::set_tangent(const Plane &p_tangent) {
- RS::get_singleton()->immediate_tangent(im, p_tangent);
-}
-
-void ImmediateGeometry::set_color(const Color &p_color) {
- RS::get_singleton()->immediate_color(im, p_color);
-}
-
-void ImmediateGeometry::set_uv(const Vector2 &p_uv) {
- RS::get_singleton()->immediate_uv(im, p_uv);
-}
-
-void ImmediateGeometry::set_uv2(const Vector2 &p_uv2) {
- RS::get_singleton()->immediate_uv2(im, p_uv2);
-}
-
-void ImmediateGeometry::add_vertex(const Vector3 &p_vertex) {
- RS::get_singleton()->immediate_vertex(im, p_vertex);
- if (empty) {
- aabb.position = p_vertex;
- aabb.size = Vector3();
- empty = false;
- } else {
- aabb.expand_to(p_vertex);
- }
-}
-
-void ImmediateGeometry::end() {
- RS::get_singleton()->immediate_end(im);
-}
-
-void ImmediateGeometry::clear() {
- RS::get_singleton()->immediate_clear(im);
- empty = true;
- cached_textures.clear();
-}
-
-AABB ImmediateGeometry::get_aabb() const {
- return aabb;
-}
-PoolVector ImmediateGeometry::get_faces(uint32_t p_usage_flags) const {
- return PoolVector();
-}
-
-void ImmediateGeometry::add_sphere(int p_lats, int p_lons, float p_radius, bool p_add_uv) {
- for (int i = 1; i <= p_lats; i++) {
- double lat0 = Math_PI * (-0.5 + (double)(i - 1) / p_lats);
- double z0 = Math::sin(lat0);
- double zr0 = Math::cos(lat0);
-
- double lat1 = Math_PI * (-0.5 + (double)i / p_lats);
- double z1 = Math::sin(lat1);
- double zr1 = Math::cos(lat1);
-
- for (int j = p_lons; j >= 1; j--) {
- double lng0 = 2 * Math_PI * (double)(j - 1) / p_lons;
- double x0 = Math::cos(lng0);
- double y0 = Math::sin(lng0);
-
- double lng1 = 2 * Math_PI * (double)(j) / p_lons;
- double x1 = Math::cos(lng1);
- double y1 = Math::sin(lng1);
-
- Vector3 v[4] = {
- Vector3(x1 * zr0, z0, y1 * zr0),
- Vector3(x1 * zr1, z1, y1 * zr1),
- Vector3(x0 * zr1, z1, y0 * zr1),
- Vector3(x0 * zr0, z0, y0 * zr0)
- };
-
-#define ADD_POINT(m_idx) \
- if (p_add_uv) { \
- set_uv(Vector2(Math::atan2(v[m_idx].x, v[m_idx].z) / Math_PI * 0.5 + 0.5, v[m_idx].y * 0.5 + 0.5)); \
- set_tangent(Plane(Vector3(-v[m_idx].z, v[m_idx].y, v[m_idx].x), 1)); \
- } \
- set_normal(v[m_idx]); \
- add_vertex(v[m_idx] * p_radius);
-
- ADD_POINT(0);
- ADD_POINT(1);
- ADD_POINT(2);
-
- ADD_POINT(2);
- ADD_POINT(3);
- ADD_POINT(0);
- }
- }
-}
-
-void ImmediateGeometry::_bind_methods() {
- ClassDB::bind_method(D_METHOD("begin", "primitive", "texture"), &ImmediateGeometry::begin, DEFVAL(Ref()));
- ClassDB::bind_method(D_METHOD("set_normal", "normal"), &ImmediateGeometry::set_normal);
- ClassDB::bind_method(D_METHOD("set_tangent", "tangent"), &ImmediateGeometry::set_tangent);
- ClassDB::bind_method(D_METHOD("set_color", "color"), &ImmediateGeometry::set_color);
- ClassDB::bind_method(D_METHOD("set_uv", "uv"), &ImmediateGeometry::set_uv);
- ClassDB::bind_method(D_METHOD("set_uv2", "uv"), &ImmediateGeometry::set_uv2);
- ClassDB::bind_method(D_METHOD("add_vertex", "position"), &ImmediateGeometry::add_vertex);
- ClassDB::bind_method(D_METHOD("add_sphere", "lats", "lons", "radius", "add_uv"), &ImmediateGeometry::add_sphere, DEFVAL(true));
- ClassDB::bind_method(D_METHOD("end"), &ImmediateGeometry::end);
- ClassDB::bind_method(D_METHOD("clear"), &ImmediateGeometry::clear);
-}
-
-ImmediateGeometry::ImmediateGeometry() {
- im = RID_PRIME(RenderingServer::get_singleton()->immediate_create());
- set_base(im);
- empty = true;
-}
-
-ImmediateGeometry::~ImmediateGeometry() {
- RenderingServer::get_singleton()->free(im);
-}
diff --git a/scene/3d/immediate_geometry.h b/scene/3d/immediate_geometry.h
deleted file mode 100644
index 545eb93..0000000
--- a/scene/3d/immediate_geometry.h
+++ /dev/null
@@ -1,74 +0,0 @@
-#ifndef IMMEDIATE_GEOMETRY_H
-#define IMMEDIATE_GEOMETRY_H
-/*************************************************************************/
-/* immediate_geometry.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "scene/3d/visual_instance.h"
-
-#include "scene/resources/mesh/mesh.h"
-
-class Texture;
-
-class ImmediateGeometry : public GeometryInstance {
- GDCLASS(ImmediateGeometry, GeometryInstance);
-
- RID im;
- //a list of textures drawn need to be kept, to avoid references
- // in RenderingServer from becoming invalid if the texture is no longer used
- List> cached_textures;
- bool empty;
- AABB aabb;
-
-protected:
- static void _bind_methods();
-
-public:
- void begin(Mesh::PrimitiveType p_primitive, const Ref &p_texture = Ref());
- void set_normal(const Vector3 &p_normal);
- void set_tangent(const Plane &p_tangent);
- void set_color(const Color &p_color);
- void set_uv(const Vector2 &p_uv);
- void set_uv2(const Vector2 &p_uv2);
-
- void add_vertex(const Vector3 &p_vertex);
-
- void end();
- void clear();
-
- void add_sphere(int p_lats, int p_lons, float p_radius, bool p_add_uv = true);
-
- virtual AABB get_aabb() const;
- virtual PoolVector get_faces(uint32_t p_usage_flags) const;
-
- ImmediateGeometry();
- ~ImmediateGeometry();
-};
-
-#endif // IMMEDIATE_GEOMETRY_H
diff --git a/scene/3d/importer_mesh_instance_3d.cpp b/scene/3d/importer_mesh_instance_3d.cpp
deleted file mode 100644
index 3180fe5..0000000
--- a/scene/3d/importer_mesh_instance_3d.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*************************************************************************/
-/* importer_mesh_instance_3d.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "importer_mesh_instance_3d.h"
-
-#include "scene/resources/mesh/importer_mesh.h"
-
-void ImporterMeshInstance3D::set_mesh(const Ref &p_mesh) {
- mesh = p_mesh;
-}
-Ref ImporterMeshInstance3D::get_mesh() const {
- return mesh;
-}
-
-#ifdef MODULE_SKELETON_3D_ENABLED
-void ImporterMeshInstance3D::set_skin(const Ref &p_skin) {
- skin = p_skin;
-}
-Ref ImporterMeshInstance3D::get_skin() const {
- return skin;
-}
-#endif
-
-void ImporterMeshInstance3D::set_surface_material(int p_idx, const Ref &p_material) {
- ERR_FAIL_COND(p_idx < 0);
- if (p_idx >= surface_materials.size()) {
- surface_materials.resize(p_idx + 1);
- }
-
- surface_materials.write[p_idx] = p_material;
-}
-Ref ImporterMeshInstance3D::get_surface_material(int p_idx) const {
- ERR_FAIL_COND_V(p_idx < 0, Ref());
- if (p_idx >= surface_materials.size()) {
- return Ref();
- }
- return surface_materials[p_idx];
-}
-
-#ifdef MODULE_SKELETON_3D_ENABLED
-void ImporterMeshInstance3D::set_skeleton_path(const NodePath &p_path) {
- skeleton_path = p_path;
-}
-NodePath ImporterMeshInstance3D::get_skeleton_path() const {
- return skeleton_path;
-}
-#endif
-
-void ImporterMeshInstance3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &ImporterMeshInstance3D::set_mesh);
- ClassDB::bind_method(D_METHOD("get_mesh"), &ImporterMeshInstance3D::get_mesh);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "ImporterMesh"), "set_mesh", "get_mesh");
-
-#ifdef MODULE_SKELETON_3D_ENABLED
- ClassDB::bind_method(D_METHOD("set_skin", "skin"), &ImporterMeshInstance3D::set_skin);
- ClassDB::bind_method(D_METHOD("get_skin"), &ImporterMeshInstance3D::get_skin);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "skin", PROPERTY_HINT_RESOURCE_TYPE, "Skin"), "set_skin", "get_skin");
-#endif
-
-#ifdef MODULE_SKELETON_3D_ENABLED
- ClassDB::bind_method(D_METHOD("set_skeleton_path", "skeleton_path"), &ImporterMeshInstance3D::set_skeleton_path);
- ClassDB::bind_method(D_METHOD("get_skeleton_path"), &ImporterMeshInstance3D::get_skeleton_path);
- ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton_path", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton"), "set_skeleton_path", "get_skeleton_path");
-#endif
-}
diff --git a/scene/3d/importer_mesh_instance_3d.h b/scene/3d/importer_mesh_instance_3d.h
deleted file mode 100644
index a92adaf..0000000
--- a/scene/3d/importer_mesh_instance_3d.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*************************************************************************/
-/* importer_mesh_instance_3d.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef IMPORTER_MESH_INSTANCE_3D_H
-#define IMPORTER_MESH_INSTANCE_3D_H
-
-#include "scene/main/spatial.h"
-
-#include "modules/modules_enabled.gen.h"
-
-#ifdef MODULE_SKELETON_3D_ENABLED
-#include "modules/skeleton_3d/resources/skin.h"
-#endif
-
-class ImporterMesh;
-
-class ImporterMeshInstance3D : public Spatial {
- GDCLASS(ImporterMeshInstance3D, Spatial)
-
- Ref mesh;
-#ifdef MODULE_SKELETON_3D_ENABLED
- Ref skin;
- NodePath skeleton_path;
-#endif
- Vector> surface_materials;
-
-protected:
- static void _bind_methods();
-
-public:
- void set_mesh(const Ref &p_mesh);
- Ref get_mesh() const;
-
-#ifdef MODULE_SKELETON_3D_ENABLED
- void set_skin(const Ref &p_skin);
- Ref get_skin() const;
-#endif
-
- void set_surface_material(int p_idx, const Ref &p_material);
- Ref get_surface_material(int p_idx) const;
-
-#ifdef MODULE_SKELETON_3D_ENABLED
- void set_skeleton_path(const NodePath &p_path);
- NodePath get_skeleton_path() const;
-#endif
-};
-
-#endif // IMPORTER_MESH_INSTANCE_3D_H
diff --git a/scene/3d/interpolated_camera.cpp b/scene/3d/interpolated_camera.cpp
deleted file mode 100644
index 8aeda8c..0000000
--- a/scene/3d/interpolated_camera.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/*************************************************************************/
-/* interpolated_camera.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "interpolated_camera.h"
-
-#include "core/config/engine.h"
-
-void InterpolatedCamera::_notification(int p_what) {
- switch (p_what) {
- case NOTIFICATION_ENTER_TREE: {
- _update_process_mode();
- } break;
- case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
- if (!enabled) {
- break;
- }
- if (has_node(target)) {
- Spatial *node = Object::cast_to(get_node(target));
- if (!node) {
- break;
- }
-
- float delta = speed * (process_mode == INTERPOLATED_CAMERA_PROCESS_PHYSICS ? get_physics_process_delta_time() : get_process_delta_time());
- Transform target_xform = node->get_global_transform();
- Transform local_transform = get_global_transform();
- local_transform = local_transform.interpolate_with(target_xform, delta);
- set_global_transform(local_transform);
- Camera *cam = Object::cast_to(node);
- if (cam) {
- if (cam->get_projection() == get_projection()) {
- float new_near = Math::lerp(get_znear(), cam->get_znear(), delta);
- float new_far = Math::lerp(get_zfar(), cam->get_zfar(), delta);
-
- if (cam->get_projection() == PROJECTION_ORTHOGONAL) {
- float size = Math::lerp(get_size(), cam->get_size(), delta);
- set_orthogonal(size, new_near, new_far);
- } else {
- float fov = Math::lerp(get_fov(), cam->get_fov(), delta);
- set_perspective(fov, new_near, new_far);
- }
- }
- }
- }
-
- } break;
- }
-}
-
-void InterpolatedCamera::set_process_mode(InterpolatedCameraProcessMode p_mode) {
- if (process_mode == p_mode) {
- return;
- }
- process_mode = p_mode;
- _update_process_mode();
-}
-
-InterpolatedCamera::InterpolatedCameraProcessMode InterpolatedCamera::get_process_mode() const {
- return process_mode;
-}
-
-void InterpolatedCamera::_set_target(const Object *p_target) {
- ERR_FAIL_NULL(p_target);
- set_target(Object::cast_to(p_target));
-}
-
-void InterpolatedCamera::set_target(const Spatial *p_target) {
- ERR_FAIL_NULL(p_target);
- target = get_path_to(p_target);
-}
-
-void InterpolatedCamera::set_target_path(const NodePath &p_path) {
- target = p_path;
-}
-
-NodePath InterpolatedCamera::get_target_path() const {
- return target;
-}
-
-void InterpolatedCamera::set_interpolation_enabled(bool p_enable) {
- if (enabled == p_enable) {
- return;
- }
- enabled = p_enable;
- _update_process_mode();
-}
-
-void InterpolatedCamera::_update_process_mode() {
- if (Engine::get_singleton()->is_editor_hint() || !enabled) {
- set_process_internal(false);
- set_physics_process_internal(false);
- } else if (process_mode == INTERPOLATED_CAMERA_PROCESS_IDLE) {
- set_process_internal(true);
- set_physics_process_internal(false);
- } else {
- set_process_internal(false);
- set_physics_process_internal(true);
- }
-}
-
-bool InterpolatedCamera::is_interpolation_enabled() const {
- return enabled;
-}
-
-void InterpolatedCamera::set_speed(real_t p_speed) {
- speed = p_speed;
-}
-
-real_t InterpolatedCamera::get_speed() const {
- return speed;
-}
-
-void InterpolatedCamera::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_target_path", "target_path"), &InterpolatedCamera::set_target_path);
- ClassDB::bind_method(D_METHOD("get_target_path"), &InterpolatedCamera::get_target_path);
- ClassDB::bind_method(D_METHOD("set_target", "target"), &InterpolatedCamera::_set_target);
-
- ClassDB::bind_method(D_METHOD("set_speed", "speed"), &InterpolatedCamera::set_speed);
- ClassDB::bind_method(D_METHOD("get_speed"), &InterpolatedCamera::get_speed);
-
- ClassDB::bind_method(D_METHOD("set_interpolation_enabled", "target_path"), &InterpolatedCamera::set_interpolation_enabled);
- ClassDB::bind_method(D_METHOD("is_interpolation_enabled"), &InterpolatedCamera::is_interpolation_enabled);
-
- ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &InterpolatedCamera::set_process_mode);
- ClassDB::bind_method(D_METHOD("get_process_mode"), &InterpolatedCamera::get_process_mode);
-
- ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "target"), "set_target_path", "get_target_path");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed"), "set_speed", "get_speed");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_interpolation_enabled", "is_interpolation_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_mode", "get_process_mode");
-
- BIND_ENUM_CONSTANT(INTERPOLATED_CAMERA_PROCESS_PHYSICS);
- BIND_ENUM_CONSTANT(INTERPOLATED_CAMERA_PROCESS_IDLE);
-}
-
-InterpolatedCamera::InterpolatedCamera() {
- enabled = false;
- speed = 1;
- process_mode = INTERPOLATED_CAMERA_PROCESS_IDLE;
-}
diff --git a/scene/3d/interpolated_camera.h b/scene/3d/interpolated_camera.h
deleted file mode 100644
index 7067a4c..0000000
--- a/scene/3d/interpolated_camera.h
+++ /dev/null
@@ -1,76 +0,0 @@
-#ifndef INTERPOLATED_CAMERA_H
-#define INTERPOLATED_CAMERA_H
-/*************************************************************************/
-/* interpolated_camera.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "scene/3d/camera.h"
-
-class InterpolatedCamera : public Camera {
- GDCLASS(InterpolatedCamera, Camera);
-
-public:
- enum InterpolatedCameraProcessMode {
- INTERPOLATED_CAMERA_PROCESS_PHYSICS,
- INTERPOLATED_CAMERA_PROCESS_IDLE
- };
-
-private:
- bool enabled;
- real_t speed;
- NodePath target;
- InterpolatedCameraProcessMode process_mode;
-
- void _update_process_mode();
-
-protected:
- void _notification(int p_what);
- static void _bind_methods();
- void _set_target(const Object *p_target);
-
-public:
- void set_target(const Spatial *p_target);
- void set_target_path(const NodePath &p_path);
- NodePath get_target_path() const;
-
- void set_speed(real_t p_speed);
- real_t get_speed() const;
-
- void set_interpolation_enabled(bool p_enable);
- bool is_interpolation_enabled() const;
-
- void set_process_mode(InterpolatedCameraProcessMode p_mode);
- InterpolatedCameraProcessMode get_process_mode() const;
-
- InterpolatedCamera();
-};
-
-VARIANT_ENUM_CAST(InterpolatedCamera::InterpolatedCameraProcessMode);
-
-#endif // INTERPOLATED_CAMERA_H
diff --git a/scene/3d/label_3d.cpp b/scene/3d/label_3d.cpp
deleted file mode 100644
index 729f58b..0000000
--- a/scene/3d/label_3d.cpp
+++ /dev/null
@@ -1,1065 +0,0 @@
-/*************************************************************************/
-/* label_3d.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "label_3d.h"
-
-#include "core/core_string_names.h"
-#include "scene/resources/mesh/primitive_meshes.h"
-#include "scene/resources/theme.h"
-#include "scene/main/scene_string_names.h"
-
-void Label3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_horizontal_alignment", "alignment"), &Label3D::set_horizontal_alignment);
- ClassDB::bind_method(D_METHOD("get_horizontal_alignment"), &Label3D::get_horizontal_alignment);
-
- ClassDB::bind_method(D_METHOD("set_vertical_alignment", "alignment"), &Label3D::set_vertical_alignment);
- ClassDB::bind_method(D_METHOD("get_vertical_alignment"), &Label3D::get_vertical_alignment);
-
- ClassDB::bind_method(D_METHOD("set_modulate", "modulate"), &Label3D::set_modulate);
- ClassDB::bind_method(D_METHOD("get_modulate"), &Label3D::get_modulate);
-
- ClassDB::bind_method(D_METHOD("set_outline_modulate", "modulate"), &Label3D::set_outline_modulate);
- ClassDB::bind_method(D_METHOD("get_outline_modulate"), &Label3D::get_outline_modulate);
-
- ClassDB::bind_method(D_METHOD("set_text", "text"), &Label3D::set_text);
- ClassDB::bind_method(D_METHOD("get_text"), &Label3D::get_text);
-
- ClassDB::bind_method(D_METHOD("set_uppercase", "enable"), &Label3D::set_uppercase);
- ClassDB::bind_method(D_METHOD("is_uppercase"), &Label3D::is_uppercase);
-
- ClassDB::bind_method(D_METHOD("set_render_priority", "priority"), &Label3D::set_render_priority);
- ClassDB::bind_method(D_METHOD("get_render_priority"), &Label3D::get_render_priority);
-
- ClassDB::bind_method(D_METHOD("set_outline_render_priority", "priority"), &Label3D::set_outline_render_priority);
- ClassDB::bind_method(D_METHOD("get_outline_render_priority"), &Label3D::get_outline_render_priority);
-
- ClassDB::bind_method(D_METHOD("set_font", "font"), &Label3D::set_font);
- ClassDB::bind_method(D_METHOD("get_font"), &Label3D::get_font);
-
- ClassDB::bind_method(D_METHOD("set_line_spacing", "line_spacing"), &Label3D::set_line_spacing);
- ClassDB::bind_method(D_METHOD("get_line_spacing"), &Label3D::get_line_spacing);
-
- ClassDB::bind_method(D_METHOD("set_autowrap", "autowrap_mode"), &Label3D::set_autowrap);
- ClassDB::bind_method(D_METHOD("get_autowrap"), &Label3D::get_autowrap);
-
- ClassDB::bind_method(D_METHOD("set_width", "width"), &Label3D::set_width);
- ClassDB::bind_method(D_METHOD("get_width"), &Label3D::get_width);
-
- ClassDB::bind_method(D_METHOD("set_pixel_size", "pixel_size"), &Label3D::set_pixel_size);
- ClassDB::bind_method(D_METHOD("get_pixel_size"), &Label3D::get_pixel_size);
-
- ClassDB::bind_method(D_METHOD("set_offset", "offset"), &Label3D::set_offset);
- ClassDB::bind_method(D_METHOD("get_offset"), &Label3D::get_offset);
-
- ClassDB::bind_method(D_METHOD("set_draw_flag", "flag", "enabled"), &Label3D::set_draw_flag);
- ClassDB::bind_method(D_METHOD("get_draw_flag", "flag"), &Label3D::get_draw_flag);
-
- ClassDB::bind_method(D_METHOD("set_billboard_mode", "mode"), &Label3D::set_billboard_mode);
- ClassDB::bind_method(D_METHOD("get_billboard_mode"), &Label3D::get_billboard_mode);
-
- ClassDB::bind_method(D_METHOD("set_alpha_cut_mode", "mode"), &Label3D::set_alpha_cut_mode);
- ClassDB::bind_method(D_METHOD("get_alpha_cut_mode"), &Label3D::get_alpha_cut_mode);
-
- ClassDB::bind_method(D_METHOD("set_alpha_scissor_threshold", "threshold"), &Label3D::set_alpha_scissor_threshold);
- ClassDB::bind_method(D_METHOD("get_alpha_scissor_threshold"), &Label3D::get_alpha_scissor_threshold);
-
- ClassDB::bind_method(D_METHOD("generate_triangle_mesh"), &Label3D::generate_triangle_mesh);
-
- ClassDB::bind_method(D_METHOD("_queue_update"), &Label3D::_queue_update);
- ClassDB::bind_method(D_METHOD("_font_changed"), &Label3D::_font_changed);
- ClassDB::bind_method(D_METHOD("_im_update"), &Label3D::_im_update);
-
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "pixel_size", PROPERTY_HINT_RANGE, "0.0001,128,0.0001"), "set_pixel_size", "get_pixel_size");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
-
- ADD_GROUP("Flags", "");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "billboard", PROPERTY_HINT_ENUM, "Disabled,Enabled,Y-Billboard"), "set_billboard_mode", "get_billboard_mode");
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "shaded"), "set_draw_flag", "get_draw_flag", FLAG_SHADED);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "double_sided"), "set_draw_flag", "get_draw_flag", FLAG_DOUBLE_SIDED);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "no_depth_test"), "set_draw_flag", "get_draw_flag", FLAG_DISABLE_DEPTH_TEST);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "fixed_size"), "set_draw_flag", "get_draw_flag", FLAG_FIXED_SIZE);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_cut", PROPERTY_HINT_ENUM, "Disabled,Discard,Opaque Pre-Pass"), "set_alpha_cut_mode", "get_alpha_cut_mode");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "render_priority", PROPERTY_HINT_RANGE, itos(RS::MATERIAL_RENDER_PRIORITY_MIN) + "," + itos(RS::MATERIAL_RENDER_PRIORITY_MAX) + ",1"), "set_render_priority", "get_render_priority");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_render_priority", PROPERTY_HINT_RANGE, itos(RS::MATERIAL_RENDER_PRIORITY_MIN) + "," + itos(RS::MATERIAL_RENDER_PRIORITY_MAX) + ",1"), "set_outline_render_priority", "get_outline_render_priority");
-
- ADD_GROUP("Text", "");
- ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate"), "set_modulate", "get_modulate");
- ADD_PROPERTY(PropertyInfo(Variant::COLOR, "outline_modulate"), "set_outline_modulate", "get_outline_modulate");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, ""), "set_text", "get_text");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "font", PROPERTY_HINT_RESOURCE_TYPE, "Font"), "set_font", "get_font");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "horizontal_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "vertical_alignment", PROPERTY_HINT_ENUM, "Top,Center,Bottom"), "set_vertical_alignment", "get_vertical_alignment");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "uppercase"), "set_uppercase", "is_uppercase");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "line_spacing"), "set_line_spacing", "get_line_spacing");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autowrap"), "set_autowrap", "get_autowrap");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "width"), "set_width", "get_width");
-
- BIND_ENUM_CONSTANT(FLAG_SHADED);
- BIND_ENUM_CONSTANT(FLAG_DOUBLE_SIDED);
- BIND_ENUM_CONSTANT(FLAG_DISABLE_DEPTH_TEST);
- BIND_ENUM_CONSTANT(FLAG_FIXED_SIZE);
- BIND_ENUM_CONSTANT(FLAG_MAX);
-
- BIND_ENUM_CONSTANT(ALPHA_CUT_DISABLED);
- BIND_ENUM_CONSTANT(ALPHA_CUT_DISCARD);
- BIND_ENUM_CONSTANT(ALPHA_CUT_OPAQUE_PREPASS);
-
- BIND_ENUM_CONSTANT(ALIGN_LEFT);
- BIND_ENUM_CONSTANT(ALIGN_CENTER);
- BIND_ENUM_CONSTANT(ALIGN_RIGHT);
- BIND_ENUM_CONSTANT(ALIGN_FILL);
-
- BIND_ENUM_CONSTANT(VALIGN_TOP);
- BIND_ENUM_CONSTANT(VALIGN_CENTER);
- BIND_ENUM_CONSTANT(VALIGN_BOTTOM);
- BIND_ENUM_CONSTANT(VALIGN_FILL);
-}
-
-void Label3D::_validate_property(PropertyInfo &property) const {
- if (property.name == "material_override" || property.name == "material_overlay") {
- property.usage = PROPERTY_USAGE_NOEDITOR;
- }
-}
-
-int Label3D::get_longest_line_width() const {
- Ref font = _get_font_or_default();
- real_t max_line_width = 0;
- real_t line_width = 0;
-
- for (int i = 0; i < xl_text.size(); i++) {
- CharType current = xl_text[i];
- if (uppercase) {
- current = String::char_uppercase(current);
- }
-
- if (current < 32) {
- if (current == '\n') {
- if (line_width > max_line_width) {
- max_line_width = line_width;
- }
- line_width = 0;
- }
- } else {
- real_t char_width = font->get_char_size(current, xl_text[i + 1]).width;
- line_width += char_width;
- }
- }
-
- if (line_width > max_line_width) {
- max_line_width = line_width;
- }
-
- // ceiling to ensure autowrapping does not cut text
- return Math::ceil(max_line_width);
-}
-
-void Label3D::regenerate_word_cache() {
- while (word_cache) {
- WordCache *current = word_cache;
- word_cache = current->next;
- memdelete(current);
- }
-
- int max_line_width;
- if (autowrap) {
- max_line_width = width;
- } else {
- max_line_width = get_longest_line_width();
- }
-
- Ref font = _get_font_or_default();
-
- real_t current_word_size = 0;
- int word_pos = 0;
- real_t line_width = 0;
- int space_count = 0;
- real_t space_width = font->get_char_size(' ').width;
- line_count = 1;
- bool was_separatable = false;
-
- WordCache *last = nullptr;
-
- for (int i = 0; i <= xl_text.length(); i++) {
- CharType current = i < xl_text.length() ? xl_text[i] : L' '; //always a space at the end, so the algo works
-
- if (uppercase) {
- current = String::char_uppercase(current);
- }
-
- // ranges taken from https://en.wikipedia.org/wiki/Plane_(Unicode)
- // if your language is not well supported, consider helping improve
- // the unicode support in Godot.
- bool separatable = (current >= 0x2E08 && current <= 0x9FFF) || // CJK scripts and symbols.
- (current >= 0xAC00 && current <= 0xD7FF) || // Hangul Syllables and Hangul Jamo Extended-B.
- (current >= 0xF900 && current <= 0xFAFF) || // CJK Compatibility Ideographs.
- (current >= 0xFE30 && current <= 0xFE4F) || // CJK Compatibility Forms.
- (current >= 0xFF65 && current <= 0xFF9F) || // Halfwidth forms of katakana
- (current >= 0xFFA0 && current <= 0xFFDC) || // Halfwidth forms of compatibility jamo characters for Hangul
- (current >= 0x20000 && current <= 0x2FA1F) || // CJK Unified Ideographs Extension B ~ F and CJK Compatibility Ideographs Supplement.
- (current >= 0x30000 && current <= 0x3134F); // CJK Unified Ideographs Extension G.
- bool insert_newline = false;
- real_t char_width = 0;
-
- bool separation_changed = i > 0 && was_separatable != separatable;
- was_separatable = separatable;
-
- if (current < 33) { // Control characters and space.
- if (current_word_size > 0) { // These characters always create a word-break.
- WordCache *wc = memnew(WordCache);
- if (word_cache) {
- last->next = wc;
- } else {
- word_cache = wc;
- }
- last = wc;
-
- wc->pixel_width = current_word_size;
- wc->char_pos = word_pos;
- wc->word_len = i - word_pos;
- wc->space_count = space_count;
- current_word_size = 0;
- space_count = 0;
- } else if ((i == xl_text.length() || current == '\n') && last != nullptr && space_count != 0) {
- // In case there are trailing white spaces we add a placeholder word cache with just the spaces.
- WordCache *wc = memnew(WordCache);
- if (word_cache) {
- last->next = wc;
- } else {
- word_cache = wc;
- }
- last = wc;
-
- wc->pixel_width = 0;
- wc->char_pos = 0;
- wc->word_len = 0;
- wc->space_count = space_count;
- current_word_size = 0;
- space_count = 0;
- }
-
- if (current == '\n') {
- insert_newline = true;
- }
-
- if (i < xl_text.length() && xl_text[i] == ' ') {
- if (line_width == 0) {
- if (current_word_size == 0) {
- word_pos = i;
- }
- current_word_size += space_width;
- line_width += space_width;
- } else if (line_width > 0 || last == nullptr || last->char_pos != WordCache::CHAR_WRAPLINE) {
- space_count++;
- line_width += space_width;
- } else {
- space_count = 0;
- }
- }
-
- } else { // Characters with graphical representation.
- // Word-break on CJK & non-CJK edge.
- if (separation_changed && current_word_size > 0) {
- WordCache *wc = memnew(WordCache);
- if (word_cache) {
- last->next = wc;
- } else {
- word_cache = wc;
- }
- last = wc;
-
- wc->pixel_width = current_word_size;
- wc->char_pos = word_pos;
- wc->word_len = i - word_pos;
- wc->space_count = space_count;
- current_word_size = 0;
- space_count = 0;
- }
- if (current_word_size == 0) {
- word_pos = i;
- }
- char_width = font->get_char_size(current, xl_text[i + 1]).width;
- current_word_size += char_width;
- line_width += char_width;
-
- // allow autowrap to cut words when they exceed line width
- if (autowrap && (current_word_size > max_line_width)) {
- separatable = true;
- }
- }
-
- if ((autowrap && (line_width >= max_line_width) && ((last && last->char_pos >= 0) || separatable)) || insert_newline) {
- if (separatable) {
- if (current_word_size > 0) {
- WordCache *wc = memnew(WordCache);
- if (word_cache) {
- last->next = wc;
- } else {
- word_cache = wc;
- }
- last = wc;
-
- wc->pixel_width = current_word_size - char_width;
- wc->char_pos = word_pos;
- wc->word_len = i - word_pos;
- wc->space_count = space_count;
- current_word_size = char_width;
- word_pos = i;
- }
- }
-
- WordCache *wc = memnew(WordCache);
- if (word_cache) {
- last->next = wc;
- } else {
- word_cache = wc;
- }
- last = wc;
-
- wc->pixel_width = 0;
- wc->char_pos = insert_newline ? WordCache::CHAR_NEWLINE : WordCache::CHAR_WRAPLINE;
-
- line_width = current_word_size;
- line_count++;
- space_count = 0;
- }
- }
-
- word_cache_dirty = false;
-}
-
-void Label3D::_notification(int p_what) {
- switch (p_what) {
- case NOTIFICATION_ENTER_TREE: {
- if (!pending_update) {
- _im_update();
- }
- } break;
- case NOTIFICATION_TRANSLATION_CHANGED: {
- String new_text = tr(text);
- if (new_text == xl_text) {
- return; // Nothing new.
- }
- xl_text = new_text;
-
- regenerate_word_cache();
- _queue_update();
- } break;
- }
-}
-
-void Label3D::_im_update() {
- _shape();
-
- triangle_mesh.unref();
- update_gizmos();
-
- pending_update = false;
-}
-
-void Label3D::_queue_update() {
- if (pending_update) {
- return;
- }
-
- pending_update = true;
- call_deferred(SceneStringNames::get_singleton()->_im_update);
-}
-
-AABB Label3D::get_aabb() const {
- return aabb;
-}
-
-Ref Label3D::generate_triangle_mesh() const {
- if (triangle_mesh.is_valid()) {
- return triangle_mesh;
- }
-
- Ref font = _get_font_or_default();
- if (font.is_null()) {
- return Ref();
- }
-
- PoolVector faces;
- faces.resize(6);
- PoolVector::Write facesw = faces.write();
-
- if (word_cache_dirty) {
- const_cast(this)->regenerate_word_cache();
- }
-
- float font_h = font->get_height() + line_spacing;
- real_t space_w = font->get_char_size(' ').width;
- float total_h = line_count * font_h;
-
- float vbegin = 0;
- switch (vertical_alignment) {
- case VALIGN_FILL:
- case VALIGN_TOP: {
- // Nothing.
- } break;
- case VALIGN_CENTER: {
- vbegin = (total_h - line_spacing) / 2.0;
- } break;
- case VALIGN_BOTTOM: {
- vbegin = (total_h - line_spacing);
- } break;
- }
-
- WordCache *wc = word_cache;
- if (!wc) {
- return Ref();
- }
-
- float max_line_w = 0.0;
- int line = 0;
- while (wc) {
- if (line >= line_count) {
- break;
- }
-
- if (wc->char_pos < 0) {
- wc = wc->next;
- line++;
- continue;
- }
-
- WordCache *to = wc;
-
- float taken = 0;
- int spaces = 0;
- while (to && to->char_pos >= 0) {
- taken += to->pixel_width;
- if (to->space_count) {
- spaces += to->space_count;
- }
- to = to->next;
- }
-
- max_line_w = MAX(max_line_w, (taken + spaces * space_w));
-
- wc = to ? to->next : nullptr;
- line++;
- }
-
- Vector2 offset = Vector2(0, vbegin);
- switch (horizontal_alignment) {
- case ALIGN_FILL:
- case ALIGN_LEFT: {
- // Noting
- } break;
- case ALIGN_CENTER: {
- offset.x = -max_line_w / 2.0;
- } break;
- case ALIGN_RIGHT: {
- offset.x = -max_line_w;
- } break;
- }
-
- Rect2 final_rect = Rect2(offset + lbl_offset, Size2(max_line_w, total_h));
-
- if (final_rect.size.x == 0 || final_rect.size.y == 0) {
- return Ref();
- }
-
- real_t pixel_size = get_pixel_size();
-
- Vector2 vertices[4] = {
-
- (final_rect.position + Vector2(0, -final_rect.size.y)) * pixel_size,
- (final_rect.position + Vector2(final_rect.size.x, -final_rect.size.y)) * pixel_size,
- (final_rect.position + Vector2(final_rect.size.x, 0)) * pixel_size,
- final_rect.position * pixel_size,
-
- };
-
- static const int indices[6] = {
- 0, 1, 2,
- 0, 2, 3
- };
-
- for (int j = 0; j < 6; j++) {
- int i = indices[j];
- Vector3 vtx;
- vtx[0] = vertices[i][0];
- vtx[1] = vertices[i][1];
- facesw[j] = vtx;
- }
-
- triangle_mesh = Ref(memnew(TriangleMesh));
- triangle_mesh->create(faces);
-
- return triangle_mesh;
-}
-
-PoolVector Label3D::get_faces(uint32_t p_usage_flags) const {
- return PoolVector();
-}
-
-float Label3D::_generate_glyph_surfaces(const Ref &p_font, CharType p_char, CharType p_next, Vector2 p_offset, const Color &p_modulate, int p_priority, bool p_outline) {
- Vector2 gl_of;
- Vector2 gl_sz;
- Rect2 gl_uv;
- Size2 texs;
- RID tex;
-
- tex = p_font->get_char_texture(p_char, p_next, p_outline);
- gl_of = p_font->get_char_tx_offset(p_char, p_next, p_outline);
- gl_sz = p_font->get_char_tx_size(p_char, p_next, p_outline);
- gl_uv = p_font->get_char_tx_uv_rect(p_char, p_next, p_outline);
- texs = p_font->get_char_texture_size(p_char, p_next, p_outline);
-
- SurfaceKey key = SurfaceKey(tex.get_id(), p_priority);
- if (!surfaces.has(key)) {
- SurfaceData surf;
- surf.material = RID_PRIME(RenderingServer::get_singleton()->material_create());
- // Set defaults for material, names need to match up those in SpatialMaterial
- RS::get_singleton()->material_set_param(surf.material, "albedo", Color(1, 1, 1, 1));
- RS::get_singleton()->material_set_param(surf.material, "specular", 0.5);
- RS::get_singleton()->material_set_param(surf.material, "metallic", 0.0);
- RS::get_singleton()->material_set_param(surf.material, "roughness", 1.0);
- RS::get_singleton()->material_set_param(surf.material, "uv1_offset", Vector3(0, 0, 0));
- RS::get_singleton()->material_set_param(surf.material, "uv1_scale", Vector3(1, 1, 1));
- RS::get_singleton()->material_set_param(surf.material, "uv2_offset", Vector3(0, 0, 0));
- RS::get_singleton()->material_set_param(surf.material, "uv2_scale", Vector3(1, 1, 1));
- RS::get_singleton()->material_set_param(surf.material, "alpha_scissor_threshold", alpha_scissor_threshold);
-
- RID shader_rid = SpatialMaterial::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), true, get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == SpatialMaterial::BILLBOARD_ENABLED, get_billboard_mode() == SpatialMaterial::BILLBOARD_FIXED_Y, get_draw_flag(FLAG_DISABLE_DEPTH_TEST), get_draw_flag(FLAG_FIXED_SIZE), p_font->is_distance_field_hint());
-
- RS::get_singleton()->material_set_shader(surf.material, RS::get_singleton()->material_get_shader(shader_rid));
- RS::get_singleton()->material_set_param(surf.material, "texture_albedo", tex);
- if (get_alpha_cut_mode() == ALPHA_CUT_DISABLED) {
- RS::get_singleton()->material_set_render_priority(surf.material, p_priority);
- } else {
- surf.z_shift = p_priority;
- }
-
- surfaces[key] = surf;
- }
- SurfaceData &s = surfaces[key];
-
- s.mesh_vertices.resize((s.offset + 1) * 4);
- s.mesh_normals.resize((s.offset + 1) * 4);
- s.mesh_tangents.resize((s.offset + 1) * 16);
- s.mesh_colors.resize((s.offset + 1) * 4);
- s.mesh_uvs.resize((s.offset + 1) * 4);
-
- s.mesh_vertices.write()[(s.offset * 4) + 3] = Vector3(p_offset.x + gl_of.x, p_offset.y - gl_of.y - gl_sz.y, s.z_shift) * pixel_size;
- s.mesh_vertices.write()[(s.offset * 4) + 2] = Vector3(p_offset.x + gl_of.x + gl_sz.x, p_offset.y - gl_of.y - gl_sz.y, s.z_shift) * pixel_size;
- s.mesh_vertices.write()[(s.offset * 4) + 1] = Vector3(p_offset.x + gl_of.x + gl_sz.x, p_offset.y - gl_of.y, s.z_shift) * pixel_size;
- s.mesh_vertices.write()[(s.offset * 4) + 0] = Vector3(p_offset.x + gl_of.x, p_offset.y - gl_of.y, s.z_shift) * pixel_size;
-
- for (int i = 0; i < 4; i++) {
- s.mesh_normals.write()[(s.offset * 4) + i] = Vector3(0.0, 0.0, 1.0);
- s.mesh_tangents.write()[(s.offset * 16) + (i * 4) + 0] = 1.0;
- s.mesh_tangents.write()[(s.offset * 16) + (i * 4) + 1] = 0.0;
- s.mesh_tangents.write()[(s.offset * 16) + (i * 4) + 2] = 0.0;
- s.mesh_tangents.write()[(s.offset * 16) + (i * 4) + 3] = 1.0;
- s.mesh_colors.write()[(s.offset * 4) + i] = p_modulate;
- s.mesh_uvs.write()[(s.offset * 4) + i] = Vector2();
-
- if (aabb == AABB()) {
- aabb.position = s.mesh_vertices[(s.offset * 4) + i];
- } else {
- aabb.expand_to(s.mesh_vertices[(s.offset * 4) + i]);
- }
- }
-
- if (tex != RID()) {
- s.mesh_uvs.write()[(s.offset * 4) + 3] = Vector2(gl_uv.position.x / texs.x, (gl_uv.position.y + gl_uv.size.y) / texs.y);
- s.mesh_uvs.write()[(s.offset * 4) + 2] = Vector2((gl_uv.position.x + gl_uv.size.x) / texs.x, (gl_uv.position.y + gl_uv.size.y) / texs.y);
- s.mesh_uvs.write()[(s.offset * 4) + 1] = Vector2((gl_uv.position.x + gl_uv.size.x) / texs.x, gl_uv.position.y / texs.y);
- s.mesh_uvs.write()[(s.offset * 4) + 0] = Vector2(gl_uv.position.x / texs.x, gl_uv.position.y / texs.y);
- }
-
- s.indices.resize((s.offset + 1) * 6);
- s.indices.write()[(s.offset * 6) + 0] = (s.offset * 4) + 0;
- s.indices.write()[(s.offset * 6) + 1] = (s.offset * 4) + 1;
- s.indices.write()[(s.offset * 6) + 2] = (s.offset * 4) + 2;
- s.indices.write()[(s.offset * 6) + 3] = (s.offset * 4) + 0;
- s.indices.write()[(s.offset * 6) + 4] = (s.offset * 4) + 2;
- s.indices.write()[(s.offset * 6) + 5] = (s.offset * 4) + 3;
-
- s.offset++;
- return p_font->get_char_size(p_char, p_next).x;
-}
-
-void Label3D::_shape() {
- // Clear mesh.
- RS::get_singleton()->mesh_clear(mesh);
- aabb = AABB();
-
- // Clear materials.
- {
- const SurfaceKey *k = nullptr;
- while ((k = surfaces.next(k))) {
- RS::get_singleton()->free(surfaces[*k].material);
- }
- surfaces.clear();
- }
-
- Ref font = _get_font_or_default();
- ERR_FAIL_COND(font.is_null());
-
- if (word_cache_dirty) {
- regenerate_word_cache();
- }
-
- // Generate surfaces and materials.
-
- float font_h = font->get_height() + line_spacing;
- real_t space_w = font->get_char_size(' ').width;
- float total_h = line_count * font_h;
-
- float vbegin = 0.0;
- switch (vertical_alignment) {
- case VALIGN_FILL:
- case VALIGN_TOP: {
- // Nothing.
- } break;
- case VALIGN_CENTER: {
- vbegin = (total_h - line_spacing) / 2.0;
- } break;
- case VALIGN_BOTTOM: {
- vbegin = (total_h - line_spacing);
- } break;
- }
-
- WordCache *wc = word_cache;
- if (!wc) {
- return;
- }
-
- int line = 0;
- while (wc) {
- if (line >= line_count) {
- break;
- }
-
- if (wc->char_pos < 0) {
- wc = wc->next;
- line++;
- continue;
- }
-
- WordCache *from = wc;
- WordCache *to = wc;
-
- float taken = 0;
- int spaces = 0;
- while (to && to->char_pos >= 0) {
- taken += to->pixel_width;
- if (to->space_count) {
- spaces += to->space_count;
- }
- to = to->next;
- }
-
- bool can_fill = to && (to->char_pos == WordCache::CHAR_WRAPLINE || to->char_pos == WordCache::CHAR_NEWLINE);
-
- float x_ofs = 0;
- switch (horizontal_alignment) {
- case ALIGN_FILL: {
- x_ofs = -width / 2.0;
- } break;
- case ALIGN_LEFT: {
- // Noting
- } break;
- case ALIGN_CENTER: {
- x_ofs = -(taken + spaces * space_w) / 2.0;
- } break;
- case ALIGN_RIGHT: {
- x_ofs = -(taken + spaces * space_w);
- } break;
- }
-
- float y_ofs = 0;
- y_ofs -= line * font_h + font->get_ascent();
- y_ofs += vbegin;
-
- while (from != to) {
- // draw a word
- int pos = from->char_pos;
- if (from->char_pos < 0) {
- ERR_PRINT("BUG");
- return;
- }
- if (from->space_count) {
- /* spacing */
- x_ofs += space_w * from->space_count;
- if (can_fill && horizontal_alignment == ALIGN_FILL && spaces) {
- x_ofs += ((width - (taken + space_w * spaces)) / spaces);
- }
- }
-
- if (font->has_outline()) {
- float x_ofs_ol = x_ofs;
- for (int i = 0; i < from->word_len; i++) {
- CharType c = xl_text[i + pos];
- CharType n = xl_text[i + pos + 1];
- if (uppercase) {
- c = String::char_uppercase(c);
- n = String::char_uppercase(n);
- }
-
- x_ofs_ol += _generate_glyph_surfaces(font, c, n, lbl_offset + Point2(x_ofs_ol, y_ofs), outline_modulate, outline_render_priority, true);
- }
- }
- for (int i = 0; i < from->word_len; i++) {
- CharType c = xl_text[i + pos];
- CharType n = xl_text[i + pos + 1];
- if (uppercase) {
- c = String::char_uppercase(c);
- n = String::char_uppercase(n);
- }
- x_ofs += _generate_glyph_surfaces(font, c, n, lbl_offset + Point2(x_ofs, y_ofs), modulate, render_priority, false);
- }
- from = from->next;
- }
-
- wc = to ? to->next : nullptr;
- line++;
- }
-
- const SurfaceKey *k = nullptr;
- int idx = 0;
- while ((k = surfaces.next(k))) {
- const SurfaceData &surf = surfaces[*k];
- Array mesh_array;
- mesh_array.resize(RS::ARRAY_MAX);
- mesh_array[RS::ARRAY_VERTEX] = surf.mesh_vertices;
- mesh_array[RS::ARRAY_NORMAL] = surf.mesh_normals;
- mesh_array[RS::ARRAY_TANGENT] = surf.mesh_tangents;
- mesh_array[RS::ARRAY_COLOR] = surf.mesh_colors;
- mesh_array[RS::ARRAY_TEX_UV] = surf.mesh_uvs;
- mesh_array[RS::ARRAY_INDEX] = surf.indices;
-
- RS::get_singleton()->mesh_add_surface_from_arrays(mesh, RS::PRIMITIVE_TRIANGLES, mesh_array);
- RS::get_singleton()->instance_set_surface_material(get_instance(), idx++, surf.material);
- }
-}
-
-void Label3D::set_text(const String &p_string) {
- text = p_string;
- xl_text = tr(p_string);
- word_cache_dirty = true;
- _queue_update();
-}
-
-String Label3D::get_text() const {
- return text;
-}
-
-void Label3D::set_horizontal_alignment(Label3D::Align p_alignment) {
- ERR_FAIL_INDEX((int)p_alignment, 4);
- if (horizontal_alignment != p_alignment) {
- horizontal_alignment = p_alignment;
- _queue_update();
- }
-}
-
-Label3D::Align Label3D::get_horizontal_alignment() const {
- return horizontal_alignment;
-}
-
-void Label3D::set_vertical_alignment(Label3D::VAlign p_alignment) {
- ERR_FAIL_INDEX((int)p_alignment, 4);
- if (vertical_alignment != p_alignment) {
- vertical_alignment = p_alignment;
- _queue_update();
- }
-}
-
-Label3D::VAlign Label3D::get_vertical_alignment() const {
- return vertical_alignment;
-}
-
-void Label3D::set_uppercase(bool p_uppercase) {
- if (uppercase != p_uppercase) {
- uppercase = p_uppercase;
- word_cache_dirty = true;
- _queue_update();
- }
-}
-
-bool Label3D::is_uppercase() const {
- return uppercase;
-}
-
-void Label3D::set_render_priority(int p_priority) {
- ERR_FAIL_COND(p_priority < RS::MATERIAL_RENDER_PRIORITY_MIN || p_priority > RS::MATERIAL_RENDER_PRIORITY_MAX);
- if (render_priority != p_priority) {
- render_priority = p_priority;
- _queue_update();
- }
-}
-
-int Label3D::get_render_priority() const {
- return render_priority;
-}
-
-void Label3D::set_outline_render_priority(int p_priority) {
- ERR_FAIL_COND(p_priority < RS::MATERIAL_RENDER_PRIORITY_MIN || p_priority > RS::MATERIAL_RENDER_PRIORITY_MAX);
- if (outline_render_priority != p_priority) {
- outline_render_priority = p_priority;
- _queue_update();
- }
-}
-
-int Label3D::get_outline_render_priority() const {
- return outline_render_priority;
-}
-
-void Label3D::_font_changed() {
- word_cache_dirty = true;
- _queue_update();
-}
-
-void Label3D::set_font(const Ref &p_font) {
- if (font_override != p_font) {
- if (font_override.is_valid()) {
- font_override->disconnect(CoreStringNames::get_singleton()->changed, this, "_font_changed");
- }
- font_override = p_font;
- if (font_override.is_valid()) {
- font_override->connect(CoreStringNames::get_singleton()->changed, this, "_font_changed");
- }
- _queue_update();
- }
-}
-
-Ref Label3D::get_font() const {
- return font_override;
-}
-
-Ref Label3D::_get_font_or_default() const {
- if (theme_font.is_valid()) {
- theme_font->disconnect(CoreStringNames::get_singleton()->changed, const_cast(this), "_font_changed");
- theme_font.unref();
- }
-
- if (font_override.is_valid()) {
- return font_override;
- }
-
- // Check the project-defined Theme resource.
- if (Theme::get_project_default().is_valid()) {
- List theme_types;
- Theme::get_project_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
-
- for (List::Element *E = theme_types.front(); E; E = E->next()) {
- if (Theme::get_project_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E->get())) {
- Ref f = Theme::get_project_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E->get());
- if (f.is_valid()) {
- theme_font = f;
- theme_font->connect(CoreStringNames::get_singleton()->changed, const_cast(this), "_font_changed");
- }
- return f;
- }
- }
- }
-
- // Lastly, fall back on the items defined in the default Theme, if they exist.
- {
- List theme_types;
- Theme::get_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
-
- for (List::Element *E = theme_types.front(); E; E = E->next()) {
- if (Theme::get_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E->get())) {
- Ref f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E->get());
- if (f.is_valid()) {
- theme_font = f;
- theme_font->connect(CoreStringNames::get_singleton()->changed, const_cast(this), "_font_changed");
- }
- return f;
- }
- }
- }
-
- // If they don't exist, use any type to return the default/empty value.
- Ref f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
- if (f.is_valid()) {
- theme_font = f;
- theme_font->connect(CoreStringNames::get_singleton()->changed, const_cast(this), "_font_changed");
- }
- return f;
-}
-
-void Label3D::set_modulate(const Color &p_color) {
- if (modulate != p_color) {
- modulate = p_color;
- _queue_update();
- }
-}
-
-Color Label3D::get_modulate() const {
- return modulate;
-}
-
-void Label3D::set_outline_modulate(const Color &p_color) {
- if (outline_modulate != p_color) {
- outline_modulate = p_color;
- _queue_update();
- }
-}
-
-Color Label3D::get_outline_modulate() const {
- return outline_modulate;
-}
-
-void Label3D::set_autowrap(bool p_autowrap) {
- if (autowrap != p_autowrap) {
- autowrap = p_autowrap;
- word_cache_dirty = true;
- _queue_update();
- }
-}
-
-bool Label3D::get_autowrap() const {
- return autowrap;
-}
-
-void Label3D::set_width(float p_width) {
- if (width != p_width) {
- width = p_width;
- word_cache_dirty = true;
- _queue_update();
- }
-}
-
-float Label3D::get_width() const {
- return width;
-}
-
-void Label3D::set_pixel_size(real_t p_amount) {
- if (pixel_size != p_amount) {
- pixel_size = p_amount;
- _queue_update();
- }
-}
-
-real_t Label3D::get_pixel_size() const {
- return pixel_size;
-}
-
-void Label3D::set_offset(const Point2 &p_offset) {
- if (lbl_offset != p_offset) {
- lbl_offset = p_offset;
- _queue_update();
- }
-}
-
-Point2 Label3D::get_offset() const {
- return lbl_offset;
-}
-
-void Label3D::set_line_spacing(float p_line_spacing) {
- if (line_spacing != p_line_spacing) {
- line_spacing = p_line_spacing;
- _queue_update();
- }
-}
-
-float Label3D::get_line_spacing() const {
- return line_spacing;
-}
-
-void Label3D::set_draw_flag(DrawFlags p_flag, bool p_enable) {
- ERR_FAIL_INDEX(p_flag, FLAG_MAX);
- if (flags[p_flag] != p_enable) {
- flags[p_flag] = p_enable;
- _queue_update();
- }
-}
-
-bool Label3D::get_draw_flag(DrawFlags p_flag) const {
- ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
- return flags[p_flag];
-}
-
-void Label3D::set_billboard_mode(SpatialMaterial::BillboardMode p_mode) {
- ERR_FAIL_INDEX(p_mode, 3);
- if (billboard_mode != p_mode) {
- billboard_mode = p_mode;
- _queue_update();
- }
-}
-
-SpatialMaterial::BillboardMode Label3D::get_billboard_mode() const {
- return billboard_mode;
-}
-
-void Label3D::set_alpha_cut_mode(AlphaCutMode p_mode) {
- ERR_FAIL_INDEX(p_mode, 3);
- if (alpha_cut != p_mode) {
- alpha_cut = p_mode;
- _queue_update();
- }
-}
-
-Label3D::AlphaCutMode Label3D::get_alpha_cut_mode() const {
- return alpha_cut;
-}
-
-void Label3D::set_alpha_scissor_threshold(float p_threshold) {
- if (alpha_scissor_threshold != p_threshold) {
- alpha_scissor_threshold = p_threshold;
- _queue_update();
- }
-}
-
-float Label3D::get_alpha_scissor_threshold() const {
- return alpha_scissor_threshold;
-}
-
-Label3D::Label3D() {
- for (int i = 0; i < FLAG_MAX; i++) {
- flags[i] = (i == FLAG_DOUBLE_SIDED);
- }
-
- mesh = RID_PRIME(RenderingServer::get_singleton()->mesh_create());
-
- set_base(mesh);
-}
-
-Label3D::~Label3D() {
- while (word_cache) {
- WordCache *current = word_cache;
- word_cache = current->next;
- memdelete(current);
- }
-
- RS::get_singleton()->free(mesh);
- const SurfaceKey *k = nullptr;
- while ((k = surfaces.next(k))) {
- RS::get_singleton()->free(surfaces[*k].material);
- }
- surfaces.clear();
-}
diff --git a/scene/3d/label_3d.h b/scene/3d/label_3d.h
deleted file mode 100644
index 6d6c0f9..0000000
--- a/scene/3d/label_3d.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/*************************************************************************/
-/* label_3d.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef LABEL_3D_H
-#define LABEL_3D_H
-
-#include "scene/3d/visual_instance.h"
-#include "scene/resources/font/font.h"
-#include "scene/resources/material/material.h"
-#include "scene/resources/material/spatial_material.h"
-
-class TriangleMesh;
-
-class Label3D : public GeometryInstance {
- GDCLASS(Label3D, GeometryInstance);
-
-public:
- enum DrawFlags {
- FLAG_SHADED,
- FLAG_DOUBLE_SIDED,
- FLAG_DISABLE_DEPTH_TEST,
- FLAG_FIXED_SIZE,
- FLAG_MAX
- };
-
- enum AlphaCutMode {
- ALPHA_CUT_DISABLED,
- ALPHA_CUT_DISCARD,
- ALPHA_CUT_OPAQUE_PREPASS
- };
-
- enum Align {
-
- ALIGN_LEFT,
- ALIGN_CENTER,
- ALIGN_RIGHT,
- ALIGN_FILL
- };
-
- enum VAlign {
-
- VALIGN_TOP,
- VALIGN_CENTER,
- VALIGN_BOTTOM,
- VALIGN_FILL
- };
-
-private:
- real_t pixel_size = 0.01;
- bool flags[FLAG_MAX] = {};
- AlphaCutMode alpha_cut = ALPHA_CUT_DISABLED;
- float alpha_scissor_threshold = 0.5;
-
- AABB aabb;
-
- mutable Ref triangle_mesh;
- RID mesh;
-
- struct SurfaceData {
- PoolVector3Array mesh_vertices;
- PoolVector3Array mesh_normals;
- PoolRealArray mesh_tangents;
- PoolColorArray mesh_colors;
- PoolVector2Array mesh_uvs;
- PoolIntArray indices;
- int offset = 0;
- float z_shift = 0.0;
- RID material;
- };
-
- struct SurfaceKey {
- uint64_t texture_id;
- int32_t priority;
-
- bool operator==(const SurfaceKey &p_b) const {
- return (texture_id == p_b.texture_id) && (priority == p_b.priority);
- }
-
- SurfaceKey(uint64_t p_texture_id, int p_priority) {
- texture_id = p_texture_id;
- priority = p_priority;
- }
- };
-
- struct SurfaceKeyHasher {
- _FORCE_INLINE_ static uint32_t hash(const SurfaceKey &p_a) {
- uint32_t hash = hash_djb2_one_32(p_a.texture_id);
- return hash_djb2_one_32(p_a.priority, hash);
- }
- };
-
- HashMap surfaces;
-
- struct WordCache {
- enum {
- CHAR_NEWLINE = -1,
- CHAR_WRAPLINE = -2
- };
- int char_pos; // if -1, then newline
- int word_len;
- int pixel_width;
- int space_count;
- WordCache *next;
- WordCache() {
- char_pos = 0;
- word_len = 0;
- pixel_width = 0;
- next = nullptr;
- space_count = 0;
- }
- };
- bool word_cache_dirty = true;
-
- WordCache *word_cache = nullptr;
- int line_count = 0;
-
- Align horizontal_alignment = ALIGN_CENTER;
- VAlign vertical_alignment = VALIGN_CENTER;
- String text;
- String xl_text;
- bool uppercase = false;
-
- bool autowrap = false;
- float width = 500.0;
-
- Ref font_override;
- mutable Ref theme_font;
- Color modulate = Color(1, 1, 1, 1);
- Point2 lbl_offset;
- int outline_render_priority = -1;
- int render_priority = 0;
-
- Color outline_modulate = Color(0, 0, 0, 1);
-
- float line_spacing = 0.f;
-
- RID base_material;
- SpatialMaterial::BillboardMode billboard_mode = SpatialMaterial::BILLBOARD_DISABLED;
-
- bool pending_update = false;
-
- void regenerate_word_cache();
- int get_longest_line_width() const;
- float _generate_glyph_surfaces(const Ref &p_font, CharType p_char, CharType p_next, Vector2 p_offset, const Color &p_modulate, int p_priority, bool p_outline);
-
-protected:
- void _notification(int p_what);
-
- static void _bind_methods();
-
- void _validate_property(PropertyInfo &property) const;
-
- void _im_update();
- void _font_changed();
- void _queue_update();
-
- void _shape();
-
-public:
- void set_horizontal_alignment(Align p_alignment);
- Align get_horizontal_alignment() const;
-
- void set_vertical_alignment(VAlign p_alignment);
- VAlign get_vertical_alignment() const;
-
- void set_render_priority(int p_priority);
- int get_render_priority() const;
-
- void set_outline_render_priority(int p_priority);
- int get_outline_render_priority() const;
-
- void set_text(const String &p_string);
- String get_text() const;
-
- void set_uppercase(bool p_uppercase);
- bool is_uppercase() const;
-
- void set_font(const Ref &p_font);
- Ref get_font() const;
- Ref _get_font_or_default() const;
-
- void set_line_spacing(float p_size);
- float get_line_spacing() const;
-
- void set_modulate(const Color &p_color);
- Color get_modulate() const;
-
- void set_outline_modulate(const Color &p_color);
- Color get_outline_modulate() const;
-
- void set_autowrap(bool p_mode);
- bool get_autowrap() const;
-
- void set_width(float p_width);
- float get_width() const;
-
- void set_pixel_size(real_t p_amount);
- real_t get_pixel_size() const;
-
- void set_offset(const Point2 &p_offset);
- Point2 get_offset() const;
-
- void set_draw_flag(DrawFlags p_flag, bool p_enable);
- bool get_draw_flag(DrawFlags p_flag) const;
-
- void set_alpha_cut_mode(AlphaCutMode p_mode);
- AlphaCutMode get_alpha_cut_mode() const;
-
- void set_alpha_scissor_threshold(float p_threshold);
- float get_alpha_scissor_threshold() const;
-
- void set_billboard_mode(SpatialMaterial::BillboardMode p_mode);
- SpatialMaterial::BillboardMode get_billboard_mode() const;
-
- virtual AABB get_aabb() const;
- Ref generate_triangle_mesh() const;
-
- virtual PoolVector get_faces(uint32_t p_usage_flags) const;
-
- Label3D();
- ~Label3D();
-};
-
-VARIANT_ENUM_CAST(Label3D::DrawFlags);
-VARIANT_ENUM_CAST(Label3D::AlphaCutMode);
-VARIANT_ENUM_CAST(Label3D::Align);
-VARIANT_ENUM_CAST(Label3D::VAlign);
-
-#endif // LABEL_3D_H
diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp
deleted file mode 100644
index 65b424f..0000000
--- a/scene/3d/light.cpp
+++ /dev/null
@@ -1,460 +0,0 @@
-/*************************************************************************/
-/* light.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "light.h"
-
-#include "core/config/engine.h"
-#include "core/config/project_settings.h"
-#include "scene/resources/mesh/surface_tool.h"
-
-void Light::set_param(Param p_param, float p_value) {
- ERR_FAIL_INDEX(p_param, PARAM_MAX);
- param[p_param] = p_value;
-
- RS::get_singleton()->light_set_param(light, RS::LightParam(p_param), p_value);
-
- if (p_param == PARAM_SPOT_ANGLE || p_param == PARAM_RANGE) {
- update_gizmos();
-
- if (p_param == PARAM_SPOT_ANGLE) {
- _change_notify("spot_angle");
- update_configuration_warning();
- } else if (p_param == PARAM_RANGE) {
- _change_notify("omni_range");
- _change_notify("spot_range");
- }
- }
-}
-
-float Light::get_param(Param p_param) const {
- ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
- return param[p_param];
-}
-
-void Light::set_shadow(bool p_enable) {
- shadow = p_enable;
- RS::get_singleton()->light_set_shadow(light, p_enable);
-
- if (type == RenderingServer::LIGHT_SPOT) {
- update_configuration_warning();
- }
-}
-bool Light::has_shadow() const {
- return shadow;
-}
-
-void Light::set_negative(bool p_enable) {
- negative = p_enable;
- RS::get_singleton()->light_set_negative(light, p_enable);
-}
-bool Light::is_negative() const {
- return negative;
-}
-
-void Light::set_cull_mask(uint32_t p_cull_mask) {
- cull_mask = p_cull_mask;
- RS::get_singleton()->light_set_cull_mask(light, p_cull_mask);
-}
-uint32_t Light::get_cull_mask() const {
- return cull_mask;
-}
-
-void Light::set_color(const Color &p_color) {
- color = p_color;
- RS::get_singleton()->light_set_color(light, p_color);
- // The gizmo color depends on the light color, so update it.
- update_gizmos();
-}
-Color Light::get_color() const {
- return color;
-}
-
-void Light::set_shadow_color(const Color &p_shadow_color) {
- shadow_color = p_shadow_color;
- RS::get_singleton()->light_set_shadow_color(light, p_shadow_color);
-}
-
-Color Light::get_shadow_color() const {
- return shadow_color;
-}
-
-void Light::set_shadow_reverse_cull_face(bool p_enable) {
- reverse_cull = p_enable;
- RS::get_singleton()->light_set_reverse_cull_face_mode(light, reverse_cull);
-}
-
-bool Light::get_shadow_reverse_cull_face() const {
- return reverse_cull;
-}
-
-AABB Light::get_aabb() const {
- if (type == RenderingServer::LIGHT_DIRECTIONAL) {
- return AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
-
- } else if (type == RenderingServer::LIGHT_OMNI) {
- return AABB(Vector3(-1, -1, -1) * param[PARAM_RANGE], Vector3(2, 2, 2) * param[PARAM_RANGE]);
-
- } else if (type == RenderingServer::LIGHT_SPOT) {
- float len = param[PARAM_RANGE];
- float size = Math::tan(Math::deg2rad(param[PARAM_SPOT_ANGLE])) * len;
- return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len));
- }
-
- return AABB();
-}
-
-PoolVector Light::get_faces(uint32_t p_usage_flags) const {
- return PoolVector();
-}
-
-void Light::owner_changed_notify() {
- // For cases where owner changes _after_ entering tree (as example, editor editing).
- _update_visibility();
-}
-
-void Light::_update_visibility() {
- if (!is_inside_tree()) {
- return;
- }
-
- bool editor_ok = true;
-
-#ifdef TOOLS_ENABLED
- if (editor_only) {
- if (!Engine::get_singleton()->is_editor_hint()) {
- editor_ok = false;
- } else {
- editor_ok = (get_tree()->get_edited_scene_root() && (this == get_tree()->get_edited_scene_root() || get_owner() == get_tree()->get_edited_scene_root()));
- }
- }
-#else
- if (editor_only) {
- editor_ok = false;
- }
-#endif
-
- RS::get_singleton()->instance_set_visible(get_instance(), is_visible_in_tree() && editor_ok);
-
- _change_notify("geometry/visible");
-}
-
-void Light::_notification(int p_what) {
- if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
- _update_visibility();
- }
-
- if (p_what == NOTIFICATION_ENTER_TREE) {
- _update_visibility();
- }
-}
-
-void Light::set_editor_only(bool p_editor_only) {
- editor_only = p_editor_only;
- _update_visibility();
-}
-
-bool Light::is_editor_only() const {
- return editor_only;
-}
-
-void Light::_validate_property(PropertyInfo &property) const {
- if (RenderingServer::get_singleton()->is_low_end() && property.name == "shadow_contact") {
- property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
- }
-}
-
-void Light::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_editor_only", "editor_only"), &Light::set_editor_only);
- ClassDB::bind_method(D_METHOD("is_editor_only"), &Light::is_editor_only);
-
- ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &Light::set_param);
- ClassDB::bind_method(D_METHOD("get_param", "param"), &Light::get_param);
-
- ClassDB::bind_method(D_METHOD("set_shadow", "enabled"), &Light::set_shadow);
- ClassDB::bind_method(D_METHOD("has_shadow"), &Light::has_shadow);
-
- ClassDB::bind_method(D_METHOD("set_negative", "enabled"), &Light::set_negative);
- ClassDB::bind_method(D_METHOD("is_negative"), &Light::is_negative);
-
- ClassDB::bind_method(D_METHOD("set_cull_mask", "cull_mask"), &Light::set_cull_mask);
- ClassDB::bind_method(D_METHOD("get_cull_mask"), &Light::get_cull_mask);
-
- ClassDB::bind_method(D_METHOD("set_color", "color"), &Light::set_color);
- ClassDB::bind_method(D_METHOD("get_color"), &Light::get_color);
-
- ClassDB::bind_method(D_METHOD("set_shadow_reverse_cull_face", "enable"), &Light::set_shadow_reverse_cull_face);
- ClassDB::bind_method(D_METHOD("get_shadow_reverse_cull_face"), &Light::get_shadow_reverse_cull_face);
-
- ClassDB::bind_method(D_METHOD("set_shadow_color", "shadow_color"), &Light::set_shadow_color);
- ClassDB::bind_method(D_METHOD("get_shadow_color"), &Light::get_shadow_color);
-
- ADD_GROUP("Light", "light_");
- ADD_PROPERTY(PropertyInfo(Variant::COLOR, "light_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_color", "get_color");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "light_energy", PROPERTY_HINT_RANGE, "0,16,0.001,or_greater"), "set_param", "get_param", PARAM_ENERGY);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "light_indirect_energy", PROPERTY_HINT_RANGE, "0,16,0.001,or_greater"), "set_param", "get_param", PARAM_INDIRECT_ENERGY);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "light_size", PROPERTY_HINT_RANGE, "0,1,0.001,or_greater"), "set_param", "get_param", PARAM_SIZE);
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "light_negative"), "set_negative", "is_negative");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "light_specular", PROPERTY_HINT_RANGE, "0,16,0.001,or_greater"), "set_param", "get_param", PARAM_SPECULAR);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "light_cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask");
- ADD_GROUP("Shadow", "shadow_");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_enabled"), "set_shadow", "has_shadow");
- ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_shadow_color", "get_shadow_color");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "shadow_bias", PROPERTY_HINT_RANGE, "-10,10,0.001"), "set_param", "get_param", PARAM_SHADOW_BIAS);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "shadow_contact", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_CONTACT_SHADOW_SIZE);
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_reverse_cull_face"), "set_shadow_reverse_cull_face", "get_shadow_reverse_cull_face");
- ADD_GROUP("Editor", "");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only");
- ADD_GROUP("", "");
-
- BIND_ENUM_CONSTANT(PARAM_ENERGY);
- BIND_ENUM_CONSTANT(PARAM_INDIRECT_ENERGY);
- BIND_ENUM_CONSTANT(PARAM_SIZE);
- BIND_ENUM_CONSTANT(PARAM_SPECULAR);
- BIND_ENUM_CONSTANT(PARAM_RANGE);
- BIND_ENUM_CONSTANT(PARAM_ATTENUATION);
- BIND_ENUM_CONSTANT(PARAM_SPOT_ANGLE);
- BIND_ENUM_CONSTANT(PARAM_SPOT_ATTENUATION);
- BIND_ENUM_CONSTANT(PARAM_CONTACT_SHADOW_SIZE);
- BIND_ENUM_CONSTANT(PARAM_SHADOW_MAX_DISTANCE);
- BIND_ENUM_CONSTANT(PARAM_SHADOW_SPLIT_1_OFFSET);
- BIND_ENUM_CONSTANT(PARAM_SHADOW_SPLIT_2_OFFSET);
- BIND_ENUM_CONSTANT(PARAM_SHADOW_SPLIT_3_OFFSET);
- BIND_ENUM_CONSTANT(PARAM_SHADOW_NORMAL_BIAS);
- BIND_ENUM_CONSTANT(PARAM_SHADOW_BIAS);
- BIND_ENUM_CONSTANT(PARAM_SHADOW_BIAS_SPLIT_SCALE);
- BIND_ENUM_CONSTANT(PARAM_MAX);
-}
-
-Light::Light(RenderingServer::LightType p_type) {
- type = p_type;
- switch (p_type) {
- case RS::LIGHT_DIRECTIONAL:
- light = RID_PRIME(RenderingServer::get_singleton()->directional_light_create());
- break;
- case RS::LIGHT_OMNI:
- light = RID_PRIME(RenderingServer::get_singleton()->omni_light_create());
- break;
- case RS::LIGHT_SPOT:
- light = RID_PRIME(RenderingServer::get_singleton()->spot_light_create());
- break;
- default: {
- };
- }
-
- RS::get_singleton()->instance_set_base(get_instance(), light);
-
- reverse_cull = false;
-
- editor_only = false;
- set_color(Color(1, 1, 1, 1));
- set_shadow(false);
- set_negative(false);
- set_cull_mask(0xFFFFFFFF);
-
- set_param(PARAM_ENERGY, 1);
- set_param(PARAM_INDIRECT_ENERGY, 1);
- set_param(PARAM_SIZE, 0);
- set_param(PARAM_SPECULAR, 0.5);
- set_param(PARAM_RANGE, 5);
- set_param(PARAM_ATTENUATION, 1);
- set_param(PARAM_SPOT_ANGLE, 45);
- set_param(PARAM_SPOT_ATTENUATION, 1);
- set_param(PARAM_CONTACT_SHADOW_SIZE, 0);
- set_param(PARAM_SHADOW_MAX_DISTANCE, 0);
- set_param(PARAM_SHADOW_SPLIT_1_OFFSET, 0.1);
- set_param(PARAM_SHADOW_SPLIT_2_OFFSET, 0.2);
- set_param(PARAM_SHADOW_SPLIT_3_OFFSET, 0.5);
- set_param(PARAM_SHADOW_NORMAL_BIAS, 0.0);
- set_param(PARAM_SHADOW_BIAS, 0.15);
- set_disable_scale(true);
-}
-
-Light::Light() {
- type = RenderingServer::LIGHT_DIRECTIONAL;
- ERR_PRINT("Light should not be instanced directly; use the DirectionalLight, OmniLight or SpotLight subtypes instead.");
-}
-
-Light::~Light() {
- RS::get_singleton()->instance_set_base(get_instance(), RID());
-
- if (light.is_valid()) {
- RenderingServer::get_singleton()->free(light);
- }
-}
-/////////////////////////////////////////
-
-void DirectionalLight::set_shadow_mode(ShadowMode p_mode) {
- shadow_mode = p_mode;
- RS::get_singleton()->light_directional_set_shadow_mode(light, RS::LightDirectionalShadowMode(p_mode));
- property_list_changed_notify();
-}
-
-DirectionalLight::ShadowMode DirectionalLight::get_shadow_mode() const {
- return shadow_mode;
-}
-
-void DirectionalLight::set_shadow_depth_range(ShadowDepthRange p_range) {
- shadow_depth_range = p_range;
- RS::get_singleton()->light_directional_set_shadow_depth_range_mode(light, RS::LightDirectionalShadowDepthRangeMode(p_range));
-}
-
-DirectionalLight::ShadowDepthRange DirectionalLight::get_shadow_depth_range() const {
- return shadow_depth_range;
-}
-
-void DirectionalLight::set_blend_splits(bool p_enable) {
- blend_splits = p_enable;
- RS::get_singleton()->light_directional_set_blend_splits(light, p_enable);
-}
-
-bool DirectionalLight::is_blend_splits_enabled() const {
- return blend_splits;
-}
-
-void DirectionalLight::_validate_property(PropertyInfo &property) const {
- if (shadow_mode == SHADOW_ORTHOGONAL && (property.name == "directional_shadow_split_1" || property.name == "directional_shadow_blend_splits" || property.name == "directional_shadow_bias_split_scale")) {
- // Split 2, split blending and bias split scale are only used with the PSSM 2 Splits and PSSM 4 Splits shadow modes.
- property.usage = PROPERTY_USAGE_NOEDITOR;
- }
-
- if ((shadow_mode == SHADOW_ORTHOGONAL || shadow_mode == SHADOW_PARALLEL_2_SPLITS) && (property.name == "directional_shadow_split_2" || property.name == "directional_shadow_split_3")) {
- // Splits 3 and 4 are only used with the PSSM 4 Splits shadow mode.
- property.usage = PROPERTY_USAGE_NOEDITOR;
- }
-
- Light::_validate_property(property);
-}
-
-void DirectionalLight::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_shadow_mode", "mode"), &DirectionalLight::set_shadow_mode);
- ClassDB::bind_method(D_METHOD("get_shadow_mode"), &DirectionalLight::get_shadow_mode);
-
- ClassDB::bind_method(D_METHOD("set_shadow_depth_range", "mode"), &DirectionalLight::set_shadow_depth_range);
- ClassDB::bind_method(D_METHOD("get_shadow_depth_range"), &DirectionalLight::get_shadow_depth_range);
-
- ClassDB::bind_method(D_METHOD("set_blend_splits", "enabled"), &DirectionalLight::set_blend_splits);
- ClassDB::bind_method(D_METHOD("is_blend_splits_enabled"), &DirectionalLight::is_blend_splits_enabled);
-
- ADD_GROUP("Directional Shadow", "directional_shadow_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "directional_shadow_mode", PROPERTY_HINT_ENUM, "Orthogonal (Fast),PSSM 2 Splits (Average),PSSM 3 Splits (Slow),PSSM 4 Splits (Very Slow)"), "set_shadow_mode", "get_shadow_mode");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_split_1", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_1_OFFSET);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_split_2", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_2_OFFSET);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_split_3", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_3_OFFSET);
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "directional_shadow_blend_splits"), "set_blend_splits", "is_blend_splits_enabled");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_normal_bias", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_bias_split_scale", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_BIAS_SPLIT_SCALE);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "directional_shadow_depth_range", PROPERTY_HINT_ENUM, "Stable,Optimized"), "set_shadow_depth_range", "get_shadow_depth_range");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_max_distance", PROPERTY_HINT_EXP_RANGE, "0,8192,0.1,or_greater"), "set_param", "get_param", PARAM_SHADOW_MAX_DISTANCE);
-
- BIND_ENUM_CONSTANT(SHADOW_ORTHOGONAL);
- BIND_ENUM_CONSTANT(SHADOW_PARALLEL_2_SPLITS);
- BIND_ENUM_CONSTANT(SHADOW_PARALLEL_3_SPLITS);
- BIND_ENUM_CONSTANT(SHADOW_PARALLEL_4_SPLITS);
-
- BIND_ENUM_CONSTANT(SHADOW_DEPTH_RANGE_STABLE);
- BIND_ENUM_CONSTANT(SHADOW_DEPTH_RANGE_OPTIMIZED);
-}
-
-DirectionalLight::DirectionalLight() :
- Light(RenderingServer::LIGHT_DIRECTIONAL) {
- set_param(PARAM_SHADOW_NORMAL_BIAS, 0.8);
- set_param(PARAM_SHADOW_BIAS, 0.1);
- set_param(PARAM_SHADOW_MAX_DISTANCE, 100);
- set_param(PARAM_SHADOW_BIAS_SPLIT_SCALE, 0.25);
- set_shadow_mode(SHADOW_PARALLEL_4_SPLITS);
- set_shadow_depth_range(SHADOW_DEPTH_RANGE_STABLE);
-
- blend_splits = false;
-}
-
-void OmniLight::set_shadow_mode(ShadowMode p_mode) {
- shadow_mode = p_mode;
- RS::get_singleton()->light_omni_set_shadow_mode(light, RS::LightOmniShadowMode(p_mode));
-}
-
-OmniLight::ShadowMode OmniLight::get_shadow_mode() const {
- return shadow_mode;
-}
-
-void OmniLight::set_shadow_detail(ShadowDetail p_detail) {
- shadow_detail = p_detail;
- RS::get_singleton()->light_omni_set_shadow_detail(light, RS::LightOmniShadowDetail(p_detail));
-}
-OmniLight::ShadowDetail OmniLight::get_shadow_detail() const {
- return shadow_detail;
-}
-
-void OmniLight::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_shadow_mode", "mode"), &OmniLight::set_shadow_mode);
- ClassDB::bind_method(D_METHOD("get_shadow_mode"), &OmniLight::get_shadow_mode);
-
- ClassDB::bind_method(D_METHOD("set_shadow_detail", "detail"), &OmniLight::set_shadow_detail);
- ClassDB::bind_method(D_METHOD("get_shadow_detail"), &OmniLight::get_shadow_detail);
-
- ADD_GROUP("Omni", "omni_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "omni_range", PROPERTY_HINT_EXP_RANGE, "0,4096,0.001,or_greater"), "set_param", "get_param", PARAM_RANGE);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "omni_attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_param", "get_param", PARAM_ATTENUATION);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "omni_shadow_mode", PROPERTY_HINT_ENUM, "Dual Paraboloid,Cube"), "set_shadow_mode", "get_shadow_mode");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "omni_shadow_detail", PROPERTY_HINT_ENUM, "Vertical,Horizontal"), "set_shadow_detail", "get_shadow_detail");
-
- BIND_ENUM_CONSTANT(SHADOW_DUAL_PARABOLOID);
- BIND_ENUM_CONSTANT(SHADOW_CUBE);
-
- BIND_ENUM_CONSTANT(SHADOW_DETAIL_VERTICAL);
- BIND_ENUM_CONSTANT(SHADOW_DETAIL_HORIZONTAL);
-}
-
-OmniLight::OmniLight() :
- Light(RenderingServer::LIGHT_OMNI) {
- set_shadow_mode(SHADOW_CUBE);
- set_shadow_detail(SHADOW_DETAIL_HORIZONTAL);
-}
-
-String SpotLight::get_configuration_warning() const {
- String warning = Light::get_configuration_warning();
-
- if (has_shadow() && get_param(PARAM_SPOT_ANGLE) >= 90.0) {
- if (warning != String()) {
- warning += "\n\n";
- }
-
- warning += TTR("A SpotLight with an angle wider than 90 degrees cannot cast shadows.");
- }
-
- return warning;
-}
-
-void SpotLight::_bind_methods() {
- ADD_GROUP("Spot", "spot_");
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "spot_range", PROPERTY_HINT_EXP_RANGE, "0,4096,0.001,or_greater"), "set_param", "get_param", PARAM_RANGE);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "spot_attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_param", "get_param", PARAM_ATTENUATION);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "spot_angle", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_param", "get_param", PARAM_SPOT_ANGLE);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "spot_angle_attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_param", "get_param", PARAM_SPOT_ATTENUATION);
-}
diff --git a/scene/3d/light.h b/scene/3d/light.h
deleted file mode 100644
index f0cd8e2..0000000
--- a/scene/3d/light.h
+++ /dev/null
@@ -1,212 +0,0 @@
-#ifndef LIGHT_H
-#define LIGHT_H
-/*************************************************************************/
-/* light.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "scene/3d/visual_instance.h"
-#include "servers/rendering_server.h"
-
-class Light : public VisualInstance {
- GDCLASS(Light, VisualInstance);
- OBJ_CATEGORY("3D Light Nodes");
-
-public:
- enum Param {
- PARAM_ENERGY = RS::LIGHT_PARAM_ENERGY,
- PARAM_INDIRECT_ENERGY = RS::LIGHT_PARAM_INDIRECT_ENERGY,
- PARAM_SIZE = RS::LIGHT_PARAM_SIZE,
- PARAM_SPECULAR = RS::LIGHT_PARAM_SPECULAR,
- PARAM_RANGE = RS::LIGHT_PARAM_RANGE,
- PARAM_ATTENUATION = RS::LIGHT_PARAM_ATTENUATION,
- PARAM_SPOT_ANGLE = RS::LIGHT_PARAM_SPOT_ANGLE,
- PARAM_SPOT_ATTENUATION = RS::LIGHT_PARAM_SPOT_ATTENUATION,
- PARAM_CONTACT_SHADOW_SIZE = RS::LIGHT_PARAM_CONTACT_SHADOW_SIZE,
- PARAM_SHADOW_MAX_DISTANCE = RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE,
- PARAM_SHADOW_SPLIT_1_OFFSET = RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET,
- PARAM_SHADOW_SPLIT_2_OFFSET = RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET,
- PARAM_SHADOW_SPLIT_3_OFFSET = RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET,
- PARAM_SHADOW_NORMAL_BIAS = RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS,
- PARAM_SHADOW_BIAS = RS::LIGHT_PARAM_SHADOW_BIAS,
- PARAM_SHADOW_BIAS_SPLIT_SCALE = RS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE,
- PARAM_MAX = RS::LIGHT_PARAM_MAX
- };
-
-private:
- Color color;
- float param[PARAM_MAX];
- Color shadow_color;
- bool shadow;
- bool negative;
- bool reverse_cull;
- uint32_t cull_mask;
- RS::LightType type;
- bool editor_only;
- void _update_visibility();
-
- // bind helpers
-
- virtual void owner_changed_notify();
-
-protected:
- RID light;
-
- static void _bind_methods();
- void _notification(int p_what);
- virtual void _validate_property(PropertyInfo &property) const;
-
- Light(RenderingServer::LightType p_type);
-
-public:
- RS::LightType get_light_type() const { return type; }
-
- void set_editor_only(bool p_editor_only);
- bool is_editor_only() const;
-
- void set_param(Param p_param, float p_value);
- float get_param(Param p_param) const;
-
- void set_shadow(bool p_enable);
- bool has_shadow() const;
-
- void set_negative(bool p_enable);
- bool is_negative() const;
-
- void set_cull_mask(uint32_t p_cull_mask);
- uint32_t get_cull_mask() const;
-
- void set_color(const Color &p_color);
- Color get_color() const;
-
- void set_shadow_color(const Color &p_shadow_color);
- Color get_shadow_color() const;
-
- void set_shadow_reverse_cull_face(bool p_enable);
- bool get_shadow_reverse_cull_face() const;
-
- virtual AABB get_aabb() const;
- virtual PoolVector get_faces(uint32_t p_usage_flags) const;
-
- Light();
- ~Light();
-};
-
-VARIANT_ENUM_CAST(Light::Param);
-
-class DirectionalLight : public Light {
- GDCLASS(DirectionalLight, Light);
-
-public:
- enum ShadowMode {
- SHADOW_ORTHOGONAL,
- SHADOW_PARALLEL_2_SPLITS,
- SHADOW_PARALLEL_3_SPLITS,
- SHADOW_PARALLEL_4_SPLITS
- };
-
- enum ShadowDepthRange {
- SHADOW_DEPTH_RANGE_STABLE = RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE,
- SHADOW_DEPTH_RANGE_OPTIMIZED = RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_OPTIMIZED,
- };
-
-private:
- bool blend_splits;
- ShadowMode shadow_mode;
- ShadowDepthRange shadow_depth_range;
-
-protected:
- static void _bind_methods();
- virtual void _validate_property(PropertyInfo &property) const;
-
-public:
- void set_shadow_mode(ShadowMode p_mode);
- ShadowMode get_shadow_mode() const;
-
- void set_shadow_depth_range(ShadowDepthRange p_range);
- ShadowDepthRange get_shadow_depth_range() const;
-
- void set_blend_splits(bool p_enable);
- bool is_blend_splits_enabled() const;
-
- DirectionalLight();
-};
-
-VARIANT_ENUM_CAST(DirectionalLight::ShadowMode)
-VARIANT_ENUM_CAST(DirectionalLight::ShadowDepthRange)
-
-class OmniLight : public Light {
- GDCLASS(OmniLight, Light);
-
-public:
- // omni light
- enum ShadowMode {
- SHADOW_DUAL_PARABOLOID,
- SHADOW_CUBE,
- };
-
- // omni light
- enum ShadowDetail {
- SHADOW_DETAIL_VERTICAL,
- SHADOW_DETAIL_HORIZONTAL
- };
-
-private:
- ShadowMode shadow_mode;
- ShadowDetail shadow_detail;
-
-protected:
- static void _bind_methods();
-
-public:
- void set_shadow_mode(ShadowMode p_mode);
- ShadowMode get_shadow_mode() const;
-
- void set_shadow_detail(ShadowDetail p_detail);
- ShadowDetail get_shadow_detail() const;
-
- OmniLight();
-};
-
-VARIANT_ENUM_CAST(OmniLight::ShadowMode)
-VARIANT_ENUM_CAST(OmniLight::ShadowDetail)
-
-class SpotLight : public Light {
- GDCLASS(SpotLight, Light);
-
-protected:
- static void _bind_methods();
-
-public:
- virtual String get_configuration_warning() const;
-
- SpotLight() :
- Light(RenderingServer::LIGHT_SPOT) {}
-};
-
-#endif
diff --git a/scene/3d/listener.cpp b/scene/3d/listener.cpp
deleted file mode 100644
index f5b82e0..0000000
--- a/scene/3d/listener.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/*************************************************************************/
-/* listener.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "listener.h"
-
-#include "scene/main/viewport.h"
-#include "scene/resources/mesh/mesh.h"
-
-void Listener::_update_audio_listener_state() {
-}
-
-void Listener::_request_listener_update() {
- _update_listener();
-}
-
-bool Listener::_set(const StringName &p_name, const Variant &p_value) {
- if (p_name == "current") {
- if (p_value.operator bool()) {
- make_current();
- } else {
- clear_current();
- }
- } else {
- return false;
- }
-
- return true;
-}
-bool Listener::_get(const StringName &p_name, Variant &r_ret) const {
- if (p_name == "current") {
- if (is_inside_tree() && get_tree()->is_node_being_edited(this)) {
- r_ret = current;
- } else {
- r_ret = is_current();
- }
- } else {
- return false;
- }
-
- return true;
-}
-
-void Listener::_get_property_list(List *p_list) const {
- p_list->push_back(PropertyInfo(Variant::BOOL, "current"));
-}
-
-void Listener::_update_listener() {
- if (is_inside_tree() && is_current()) {
- get_viewport()->_listener_transform_changed_notify();
- }
-}
-
-void Listener::_notification(int p_what) {
- switch (p_what) {
- case NOTIFICATION_ENTER_WORLD: {
- bool first_listener = get_viewport()->_listener_add(this);
- if (!get_tree()->is_node_being_edited(this) && (current || first_listener)) {
- make_current();
- }
- } break;
- case NOTIFICATION_TRANSFORM_CHANGED: {
- _request_listener_update();
- } break;
- case NOTIFICATION_EXIT_WORLD: {
- if (!get_tree()->is_node_being_edited(this)) {
- if (is_current()) {
- clear_current();
- current = true; //keep it true
-
- } else {
- current = false;
- }
- }
-
- get_viewport()->_listener_remove(this);
-
- } break;
- }
-}
-
-Transform Listener::get_listener_transform() const {
- return get_global_transform().orthonormalized();
-}
-
-void Listener::make_current() {
- current = true;
-
- if (!is_inside_tree()) {
- return;
- }
-
- get_viewport()->_listener_set(this);
-}
-
-void Listener::clear_current() {
- current = false;
- if (!is_inside_tree()) {
- return;
- }
-
- if (get_viewport()->get_listener() == this) {
- get_viewport()->_listener_set(nullptr);
- get_viewport()->_listener_make_next_current(this);
- }
-}
-
-bool Listener::is_current() const {
- if (is_inside_tree() && !get_tree()->is_node_being_edited(this)) {
- return get_viewport()->get_listener() == this;
- } else {
- return current;
- }
-
- return false;
-}
-
-void Listener::_bind_methods() {
- ClassDB::bind_method(D_METHOD("make_current"), &Listener::make_current);
- ClassDB::bind_method(D_METHOD("clear_current"), &Listener::clear_current);
- ClassDB::bind_method(D_METHOD("is_current"), &Listener::is_current);
- ClassDB::bind_method(D_METHOD("get_listener_transform"), &Listener::get_listener_transform);
-}
-
-Listener::Listener() {
- current = false;
- force_change = false;
- set_notify_transform(true);
-}
-
-Listener::~Listener() {
-}
diff --git a/scene/3d/listener.h b/scene/3d/listener.h
deleted file mode 100644
index fd0cd24..0000000
--- a/scene/3d/listener.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef LISTENER_H
-#define LISTENER_H
-/*************************************************************************/
-/* listener.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "scene/main/spatial.h"
-
-class Viewport;
-
-class Listener : public Spatial {
- GDCLASS(Listener, Spatial);
-
-private:
- bool force_change;
- bool current;
-
- RID scenario_id;
-
- friend class Viewport;
- void _update_audio_listener_state();
-
-protected:
- void _update_listener();
- virtual void _request_listener_update();
-
- bool _set(const StringName &p_name, const Variant &p_value);
- bool _get(const StringName &p_name, Variant &r_ret) const;
- void _get_property_list(List *p_list) const;
- void _notification(int p_what);
-
- static void _bind_methods();
-
-public:
- void make_current();
- void clear_current();
- bool is_current() const;
-
- virtual Transform get_listener_transform() const;
-
- Listener();
- ~Listener();
-};
-
-#endif
diff --git a/scene/3d/mesh_instance.cpp b/scene/3d/mesh_instance.cpp
deleted file mode 100644
index 32c8a12..0000000
--- a/scene/3d/mesh_instance.cpp
+++ /dev/null
@@ -1,841 +0,0 @@
-/*************************************************************************/
-/* mesh_instance.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "mesh_instance.h"
-
-#include "core/config/project_settings.h"
-#include "core/core_string_names.h"
-#include "scene/resources/material/material.h"
-#include "scene/resources/material/spatial_material.h"
-#include "scene/resources/mesh/mesh.h"
-#include "scene/main/scene_string_names.h"
-#include "servers/rendering/rendering_server_globals.h"
-
-bool MeshInstance::_set(const StringName &p_name, const Variant &p_value) {
- //this is not _too_ bad performance wise, really. it only arrives here if the property was not set anywhere else.
- //add to it that it's probably found on first call to _set anyway.
-
- if (!get_instance().is_valid()) {
- return false;
- }
-
- RBMap::Element *E = blend_shape_tracks.find(p_name);
- if (E) {
- E->get().value = p_value;
- RenderingServer::get_singleton()->instance_set_blend_shape_weight(get_instance(), E->get().idx, E->get().value);
- return true;
- }
-
- if (p_name.operator String().begins_with("material/")) {
- int idx = p_name.operator String().get_slicec('/', 1).to_int();
- if (idx >= materials.size() || idx < 0) {
- return false;
- }
-
- set_surface_material(idx, p_value);
- return true;
- }
-
- return false;
-}
-
-bool MeshInstance::_get(const StringName &p_name, Variant &r_ret) const {
- if (!get_instance().is_valid()) {
- return false;
- }
-
- const RBMap::Element *E = blend_shape_tracks.find(p_name);
- if (E) {
- r_ret = E->get().value;
- return true;
- }
-
- if (p_name.operator String().begins_with("material/")) {
- int idx = p_name.operator String().get_slicec('/', 1).to_int();
- if (idx >= materials.size() || idx < 0) {
- return false;
- }
- r_ret = materials[idx];
- return true;
- }
- return false;
-}
-
-void MeshInstance::_get_property_list(List *p_list) const {
- List ls;
- for (const RBMap::Element *E = blend_shape_tracks.front(); E; E = E->next()) {
- ls.push_back(E->key());
- }
-
- ls.sort();
-
- for (List::Element *E = ls.front(); E; E = E->next()) {
- p_list->push_back(PropertyInfo(Variant::REAL, E->get(), PROPERTY_HINT_RANGE, "-1,1,0.00001"));
- }
-
- if (mesh.is_valid()) {
- for (int i = 0; i < mesh->get_surface_count(); i++) {
- p_list->push_back(PropertyInfo(Variant::OBJECT, "material/" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,SpatialMaterial"));
- }
- }
-}
-
-void MeshInstance::set_mesh(const Ref &p_mesh) {
- if (mesh == p_mesh) {
- return;
- }
-
- if (mesh.is_valid()) {
- mesh->disconnect(CoreStringNames::get_singleton()->changed, this, SceneStringNames::get_singleton()->_mesh_changed);
- }
-
- mesh = p_mesh;
-
- blend_shape_tracks.clear();
- if (mesh.is_valid()) {
- for (int i = 0; i < mesh->get_blend_shape_count(); i++) {
- BlendShapeTrack mt;
- mt.idx = i;
- mt.value = 0;
- blend_shape_tracks["blend_shapes/" + String(mesh->get_blend_shape_name(i))] = mt;
- }
-
- mesh->connect(CoreStringNames::get_singleton()->changed, this, SceneStringNames::get_singleton()->_mesh_changed);
- materials.resize(mesh->get_surface_count());
-
-#ifdef MODULE_SKELETON_3D_ENABLED
- _initialize_skinning(false, true);
-#endif
- } else {
- set_base(RID());
- }
-
- update_gizmos();
-
- _change_notify();
-}
-Ref MeshInstance::get_mesh() const {
- return mesh;
-}
-
-AABB MeshInstance::get_aabb() const {
- if (!mesh.is_null()) {
- return mesh->get_aabb();
- }
-
- return AABB();
-}
-
-PoolVector MeshInstance::get_faces(uint32_t p_usage_flags) const {
- if (!(p_usage_flags & (FACES_SOLID | FACES_ENCLOSING))) {
- return PoolVector();
- }
-
- if (mesh.is_null()) {
- return PoolVector();
- }
-
- return mesh->get_faces();
-}
-
-Node *MeshInstance::create_trimesh_collision_node() {
- return NULL;
-}
-
-void MeshInstance::create_trimesh_collision() {
-}
-
-Node *MeshInstance::create_multiple_convex_collisions_node() {
- return NULL;
-}
-
-void MeshInstance::create_multiple_convex_collisions() {
-}
-
-Node *MeshInstance::create_convex_collision_node(bool p_clean, bool p_simplify) {
- return NULL;
-}
-
-void MeshInstance::create_convex_collision(bool p_clean, bool p_simplify) {
-}
-
-void MeshInstance::_notification(int p_what) {
-}
-
-int MeshInstance::get_surface_material_count() const {
- return materials.size();
-}
-
-void MeshInstance::set_surface_material(int p_surface, const Ref &p_material) {
- ERR_FAIL_INDEX(p_surface, materials.size());
-
- materials.write[p_surface] = p_material;
-
- if (materials[p_surface].is_valid()) {
- RS::get_singleton()->instance_set_surface_material(get_instance(), p_surface, materials[p_surface]->get_rid());
- } else {
- RS::get_singleton()->instance_set_surface_material(get_instance(), p_surface, RID());
- }
-}
-
-Ref MeshInstance::get_surface_material(int p_surface) const {
- ERR_FAIL_INDEX_V(p_surface, materials.size(), Ref());
-
- return materials[p_surface];
-}
-
-Ref MeshInstance::get_active_material(int p_surface) const {
- Ref material_override = get_material_override();
- if (material_override.is_valid()) {
- return material_override;
- }
-
- Ref surface_material = get_surface_material(p_surface);
- if (surface_material.is_valid()) {
- return surface_material;
- }
-
- Ref mesh = get_mesh();
- if (mesh.is_valid()) {
- return mesh->surface_get_material(p_surface);
- }
-
- return Ref();
-}
-
-void MeshInstance::set_material_override(const Ref &p_material) {
- if (p_material == get_material_override()) {
- return;
- }
-
- GeometryInstance::set_material_override(p_material);
-}
-
-void MeshInstance::set_material_overlay(const Ref &p_material) {
- if (p_material == get_material_overlay()) {
- return;
- }
-
- GeometryInstance::set_material_overlay(p_material);
-}
-
-void MeshInstance::_mesh_changed() {
- ERR_FAIL_COND(mesh.is_null());
- materials.resize(mesh->get_surface_count());
-}
-
-void MeshInstance::create_debug_tangents() {
- Vector lines;
- Vector colors;
-
- Ref mesh = get_mesh();
- if (!mesh.is_valid()) {
- return;
- }
-
- for (int i = 0; i < mesh->get_surface_count(); i++) {
- Array arrays = mesh->surface_get_arrays(i);
- Vector verts = arrays[Mesh::ARRAY_VERTEX];
- Vector norms = arrays[Mesh::ARRAY_NORMAL];
- if (norms.size() == 0) {
- continue;
- }
- Vector tangents = arrays[Mesh::ARRAY_TANGENT];
- if (tangents.size() == 0) {
- continue;
- }
-
- for (int j = 0; j < verts.size(); j++) {
- Vector3 v = verts[j];
- Vector3 n = norms[j];
- Vector3 t = Vector3(tangents[j * 4 + 0], tangents[j * 4 + 1], tangents[j * 4 + 2]);
- Vector3 b = (n.cross(t)).normalized() * tangents[j * 4 + 3];
-
- lines.push_back(v); //normal
- colors.push_back(Color(0, 0, 1)); //color
- lines.push_back(v + n * 0.04); //normal
- colors.push_back(Color(0, 0, 1)); //color
-
- lines.push_back(v); //tangent
- colors.push_back(Color(1, 0, 0)); //color
- lines.push_back(v + t * 0.04); //tangent
- colors.push_back(Color(1, 0, 0)); //color
-
- lines.push_back(v); //binormal
- colors.push_back(Color(0, 1, 0)); //color
- lines.push_back(v + b * 0.04); //binormal
- colors.push_back(Color(0, 1, 0)); //color
- }
- }
-
- if (lines.size()) {
- Ref sm;
- sm.instance();
-
- sm->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- sm->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- sm->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
-
- Ref am;
- am.instance();
- Array a;
- a.resize(Mesh::ARRAY_MAX);
- a[Mesh::ARRAY_VERTEX] = lines;
- a[Mesh::ARRAY_COLOR] = colors;
-
- am->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a);
- am->surface_set_material(0, sm);
-
- MeshInstance *mi = memnew(MeshInstance);
- mi->set_mesh(am);
- mi->set_name("DebugTangents");
- add_child(mi);
- }
-}
-
-bool MeshInstance::merge_meshes(Vector p_list, bool p_use_global_space, bool p_check_compatibility) {
- // bound function only support variants, so we need to convert to a list of MeshInstances
- Vector mis;
-
- for (int n = 0; n < p_list.size(); n++) {
- MeshInstance *mi = Object::cast_to(p_list[n]);
- if (mi) {
- if (mi != this) {
- mis.push_back(mi);
- } else {
- ERR_PRINT("Destination MeshInstance cannot be a source.");
- }
- } else {
- ERR_PRINT("Only MeshInstances can be merged.");
- }
- }
-
- ERR_FAIL_COND_V(!mis.size(), "Array contains no MeshInstances");
- return _merge_meshes(mis, p_use_global_space, p_check_compatibility);
-}
-
-bool MeshInstance::is_mergeable_with(Node *p_other) const {
- const MeshInstance *mi = Object::cast_to(p_other);
-
- if (mi) {
- return _is_mergeable_with(*mi);
- }
-
- return false;
-}
-
-bool MeshInstance::_is_mergeable_with(const MeshInstance &p_other) const {
- if (!get_mesh().is_valid() || !p_other.get_mesh().is_valid()) {
- return false;
- }
- if (!get_allow_merging() || !p_other.get_allow_merging()) {
- return false;
- }
-
- // various settings that must match
- if (get_material_overlay() != p_other.get_material_overlay()) {
- return false;
- }
- if (get_material_override() != p_other.get_material_override()) {
- return false;
- }
- if (get_cast_shadows_setting() != p_other.get_cast_shadows_setting()) {
- return false;
- }
- if (is_visible() != p_other.is_visible()) {
- return false;
- }
-
- Ref rmesh_a = get_mesh();
- Ref rmesh_b = p_other.get_mesh();
-
- int num_surfaces = rmesh_a->get_surface_count();
- if (num_surfaces != rmesh_b->get_surface_count()) {
- return false;
- }
-
- for (int n = 0; n < num_surfaces; n++) {
- // materials must match
- if (get_active_material(n) != p_other.get_active_material(n)) {
- return false;
- }
-
- // formats must match
- uint32_t format_a = rmesh_a->surface_get_format(n);
- uint32_t format_b = rmesh_b->surface_get_format(n);
-
- if (format_a != format_b) {
- return false;
- }
- }
-
- // NOTE : These three commented out sections below are more conservative
- // checks for whether to allow mesh merging. I am not absolutely sure a priori
- // how conservative we need to be, so we can further enable this if testing
- // shows they are required.
-
- // if (get_surface_material_count() != p_other.get_surface_material_count()) {
- // return false;
- // }
-
- // for (int n = 0; n < get_surface_material_count(); n++) {
- // if (get_surface_material(n) != p_other.get_surface_material(n)) {
- // return false;
- // }
- // }
-
- // test only allow identical meshes
- // if (get_mesh() != p_other.get_mesh()) {
- // return false;
- // }
-
- return true;
-}
-
-void MeshInstance::_merge_into_mesh_data(const MeshInstance &p_mi, const Transform &p_dest_tr_inv, int p_surface_id, LocalVector &r_verts, LocalVector &r_norms, LocalVector &r_tangents, LocalVector &r_colors, LocalVector &r_uvs, LocalVector &r_uv2s, LocalVector &r_inds) {
- _merge_log("\t\t\tmesh data from " + p_mi.get_name());
-
- // get the mesh verts in local space
- Ref rmesh = p_mi.get_mesh();
-
- if (rmesh->get_surface_count() <= p_surface_id) {
- return;
- }
-
- Array arrays = rmesh->surface_get_arrays(p_surface_id);
-
- LocalVector verts = PoolVector(arrays[RS::ARRAY_VERTEX]);
- if (!verts.size()) {
- // early out if there are no vertices, no point in doing anything else
- return;
- }
-
- LocalVector normals = PoolVector(arrays[RS::ARRAY_NORMAL]);
- LocalVector tangents = PoolVector(arrays[RS::ARRAY_TANGENT]);
- LocalVector colors = PoolVector(arrays[RS::ARRAY_COLOR]);
- LocalVector uvs = PoolVector(arrays[RS::ARRAY_TEX_UV]);
- LocalVector uv2s = PoolVector(arrays[RS::ARRAY_TEX_UV2]);
- LocalVector indices = PoolVector(arrays[RS::ARRAY_INDEX]);
-
- // The attributes present must match the first mesh for the attributes
- // to remain in sync. Here we reject meshes with different attributes.
- // We could alternatively invent missing attributes.
- // This should hopefully be already caught by the mesh_format, but is included just in case here.
-
- // Don't perform these checks on the first Mesh, the first Mesh is a master
- // and determines the attributes we want to be present.
- if (r_verts.size() != 0) {
- if ((bool)r_norms.size() != (bool)normals.size()) {
- ERR_FAIL_MSG("Attribute mismatch with first Mesh (Normals), ignoring surface.");
- }
- if ((bool)r_tangents.size() != (bool)tangents.size()) {
- ERR_FAIL_MSG("Attribute mismatch with first Mesh (Tangents), ignoring surface.");
- }
- if ((bool)r_colors.size() != (bool)colors.size()) {
- ERR_FAIL_MSG("Attribute mismatch with first Mesh (Colors), ignoring surface.");
- }
- if ((bool)r_uvs.size() != (bool)uvs.size()) {
- ERR_FAIL_MSG("Attribute mismatch with first Mesh (UVs), ignoring surface.");
- }
- if ((bool)r_uv2s.size() != (bool)uv2s.size()) {
- ERR_FAIL_MSG("Attribute mismatch with first Mesh (UV2s), ignoring surface.");
- }
- }
-
- // The checking for valid triangles should be on WORLD SPACE vertices,
- // NOT model space
-
- // special case, if no indices, create some
- int num_indices_before = indices.size();
- if (!_ensure_indices_valid(indices, verts)) {
- _merge_log("\tignoring INVALID TRIANGLES (duplicate indices or zero area triangle) detected in " + p_mi.get_name() + ", num inds before / after " + itos(num_indices_before) + " / " + itos(indices.size()));
- }
-
- // the first index of this mesh is offset from the verts we already have stored in the merged mesh
- int starting_index = r_verts.size();
-
- // transform verts to world space
- Transform tr = p_mi.get_global_transform();
-
- // But relative to the destination transform.
- // This can either be identity (when the destination is global space),
- // or the global transform of the owner MeshInstance (if using local space is selected).
- tr = p_dest_tr_inv * tr;
-
- // to transform normals
- Basis normal_basis = tr.basis.inverse();
- normal_basis.transpose();
-
- int num_verts = verts.size();
-
- // verts
- DEV_ASSERT(num_verts > 0);
- int first_vert = r_verts.size();
- r_verts.resize(first_vert + num_verts);
- Vector3 *dest_verts = &r_verts[first_vert];
-
- for (int n = 0; n < num_verts; n++) {
- Vector3 pt_world = tr.xform(verts[n]);
- *dest_verts++ = pt_world;
- }
-
- // normals
- if (normals.size()) {
- int first_norm = r_norms.size();
- r_norms.resize(first_norm + num_verts);
- Vector3 *dest_norms = &r_norms[first_norm];
- for (int n = 0; n < num_verts; n++) {
- Vector3 pt_norm = normal_basis.xform(normals[n]);
- pt_norm.normalize();
- *dest_norms++ = pt_norm;
- }
- }
-
- // tangents
- if (tangents.size()) {
- int first_tang = r_tangents.size();
- r_tangents.resize(first_tang + (num_verts * 4));
- real_t *dest_tangents = &r_tangents[first_tang];
-
- for (int n = 0; n < num_verts; n++) {
- int tstart = n * 4;
- Vector3 pt_tangent = Vector3(tangents[tstart], tangents[tstart + 1], tangents[tstart + 2]);
- real_t fourth = tangents[tstart + 3];
-
- pt_tangent = normal_basis.xform(pt_tangent);
- pt_tangent.normalize();
- *dest_tangents++ = pt_tangent.x;
- *dest_tangents++ = pt_tangent.y;
- *dest_tangents++ = pt_tangent.z;
- *dest_tangents++ = fourth;
- }
- }
-
- // colors
- if (colors.size()) {
- int first_col = r_colors.size();
- r_colors.resize(first_col + num_verts);
- Color *dest_colors = &r_colors[first_col];
-
- for (int n = 0; n < num_verts; n++) {
- *dest_colors++ = colors[n];
- }
- }
-
- // uvs
- if (uvs.size()) {
- int first_uv = r_uvs.size();
- r_uvs.resize(first_uv + num_verts);
- Vector2 *dest_uvs = &r_uvs[first_uv];
-
- for (int n = 0; n < num_verts; n++) {
- *dest_uvs++ = uvs[n];
- }
- }
-
- // uv2s
- if (uv2s.size()) {
- int first_uv2 = r_uv2s.size();
- r_uv2s.resize(first_uv2 + num_verts);
- Vector2 *dest_uv2s = &r_uv2s[first_uv2];
-
- for (int n = 0; n < num_verts; n++) {
- *dest_uv2s++ = uv2s[n];
- }
- }
-
- // indices
- if (indices.size()) {
- int first_ind = r_inds.size();
- r_inds.resize(first_ind + indices.size());
- int *dest_inds = &r_inds[first_ind];
-
- for (unsigned int n = 0; n < indices.size(); n++) {
- int ind = indices[n] + starting_index;
- *dest_inds++ = ind;
- }
- }
-}
-
-bool MeshInstance::_ensure_indices_valid(LocalVector &r_indices, const PoolVector &p_verts) const {
- // no indices? create some
- if (!r_indices.size()) {
- _merge_log("\t\t\t\tindices are blank, creating...");
-
- // indices are blank!! let's create some, assuming the mesh is using triangles
- r_indices.resize(p_verts.size());
-
- // this is assuming each triangle vertex is unique
- for (unsigned int n = 0; n < r_indices.size(); n++) {
- r_indices[n] = n;
- }
- }
-
- if (!_check_for_valid_indices(r_indices, p_verts, nullptr)) {
- LocalVector new_inds;
- _check_for_valid_indices(r_indices, p_verts, &new_inds);
-
- // copy the new indices
- r_indices = new_inds;
-
- return false;
- }
-
- return true;
-}
-
-// check for invalid tris, or make a list of the valid triangles, depending on whether r_inds is set
-bool MeshInstance::_check_for_valid_indices(const LocalVector &p_inds, const PoolVector &p_verts, LocalVector *r_inds) const {
- int nTris = p_inds.size();
- nTris /= 3;
- int indCount = 0;
-
- for (int t = 0; t < nTris; t++) {
- int i0 = p_inds[indCount++];
- int i1 = p_inds[indCount++];
- int i2 = p_inds[indCount++];
-
- bool ok = true;
-
- // if the indices are the same, the triangle is invalid
- if (i0 == i1) {
- ok = false;
- }
- if (i1 == i2) {
- ok = false;
- }
- if (i0 == i2) {
- ok = false;
- }
-
- // check positions
- if (ok) {
- // vertex positions
- const Vector3 &p0 = p_verts[i0];
- const Vector3 &p1 = p_verts[i1];
- const Vector3 &p2 = p_verts[i2];
-
- // if the area is zero, the triangle is invalid (and will crash xatlas if we use it)
- if (_triangle_is_degenerate(p0, p1, p2, 0.00001)) {
- _merge_log("\t\tdetected zero area triangle, ignoring");
- ok = false;
- }
- }
-
- if (ok) {
- // if the triangle is ok, we will output it if we are outputting
- if (r_inds) {
- r_inds->push_back(i0);
- r_inds->push_back(i1);
- r_inds->push_back(i2);
- }
- } else {
- // if triangle not ok, return failed check if we are not outputting
- if (!r_inds) {
- return false;
- }
- }
- }
-
- return true;
-}
-
-bool MeshInstance::_triangle_is_degenerate(const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_c, real_t p_epsilon) const {
- // not interested in the actual area, but numerical stability
- Vector3 edge1 = p_b - p_a;
- Vector3 edge2 = p_c - p_a;
-
- // for numerical stability keep these values reasonably high
- edge1 *= 1024.0;
- edge2 *= 1024.0;
-
- Vector3 vec = edge1.cross(edge2);
- real_t sl = vec.length_squared();
-
- if (sl <= p_epsilon) {
- return true;
- }
-
- return false;
-}
-
-// If p_check_compatibility is set to false you MUST have performed a prior check using
-// is_mergeable_with, otherwise you could get mismatching surface formats leading to graphical errors etc.
-bool MeshInstance::_merge_meshes(Vector p_list, bool p_use_global_space, bool p_check_compatibility) {
- if (p_list.size() < 1) {
- // should not happen but just in case
- return false;
- }
-
- // use the first mesh instance to get common data like number of surfaces
- const MeshInstance *first = p_list[0];
-
- // Mesh compatibility checking. This is relatively expensive, so if done already (e.g. in Room system)
- // this step can be avoided.
- LocalVector compat_list;
- if (p_check_compatibility) {
- compat_list.resize(p_list.size());
-
- for (int n = 0; n < p_list.size(); n++) {
- compat_list[n] = false;
- }
-
- compat_list[0] = true;
-
- for (uint32_t n = 1; n < compat_list.size(); n++) {
- compat_list[n] = first->_is_mergeable_with(*p_list[n]);
-
- if (compat_list[n] == false) {
- WARN_PRINT("MeshInstance " + p_list[n]->get_name() + " is incompatible for merging with " + first->get_name() + ", ignoring.");
- }
- }
- }
-
- Ref am;
- am.instance();
-
- // If we want a local space result, we need the world space transform of this MeshInstance
- // available to back transform verts from world space.
- Transform dest_tr_inv;
- if (!p_use_global_space) {
- if (is_inside_tree()) {
- dest_tr_inv = get_global_transform();
- dest_tr_inv.affine_invert();
- } else {
- WARN_PRINT("MeshInstance must be inside tree to merge using local space, falling back to global space.");
- }
- }
-
- for (int s = 0; s < first->get_mesh()->get_surface_count(); s++) {
- LocalVector verts;
- LocalVector normals;
- LocalVector tangents;
- LocalVector colors;
- LocalVector uvs;
- LocalVector uv2s;
- LocalVector inds;
-
- for (int n = 0; n < p_list.size(); n++) {
- // Ignore if the mesh is incompatible
- if (p_check_compatibility && (!compat_list[n])) {
- continue;
- }
-
- _merge_into_mesh_data(*p_list[n], dest_tr_inv, s, verts, normals, tangents, colors, uvs, uv2s, inds);
- } // for n through source meshes
-
- if (!verts.size()) {
- WARN_PRINT_ONCE("No vertices for surface");
- }
-
- // sanity check on the indices
- for (unsigned int n = 0; n < inds.size(); n++) {
- int i = inds[n];
- if ((unsigned int)i >= verts.size()) {
- WARN_PRINT_ONCE("Mesh index out of range, invalid mesh, aborting");
- return false;
- }
- }
-
- Array arr;
- arr.resize(Mesh::ARRAY_MAX);
- arr[Mesh::ARRAY_VERTEX] = PoolVector(verts);
- if (normals.size()) {
- arr[Mesh::ARRAY_NORMAL] = PoolVector(normals);
- }
- if (tangents.size()) {
- arr[Mesh::ARRAY_TANGENT] = PoolVector(tangents);
- }
- if (colors.size()) {
- arr[Mesh::ARRAY_COLOR] = PoolVector(colors);
- }
- if (uvs.size()) {
- arr[Mesh::ARRAY_TEX_UV] = PoolVector(uvs);
- }
- if (uv2s.size()) {
- arr[Mesh::ARRAY_TEX_UV2] = PoolVector(uv2s);
- }
- arr[Mesh::ARRAY_INDEX] = PoolVector(inds);
-
- am->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arr, Array(), Mesh::ARRAY_COMPRESS_DEFAULT);
- } // for s through surfaces
-
- // set all the surfaces on the mesh
- set_mesh(am);
-
- // set merged materials
- int num_surfaces = first->get_mesh()->get_surface_count();
- for (int n = 0; n < num_surfaces; n++) {
- set_surface_material(n, first->get_active_material(n));
- }
-
- // set some properties to match the merged meshes
- set_material_overlay(first->get_material_overlay());
- set_material_override(first->get_material_override());
- set_cast_shadows_setting(first->get_cast_shadows_setting());
-
- return true;
-}
-
-void MeshInstance::_merge_log(String p_string) const {
- print_verbose(p_string);
-}
-
-void MeshInstance::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &MeshInstance::set_mesh);
- ClassDB::bind_method(D_METHOD("get_mesh"), &MeshInstance::get_mesh);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
-
- ClassDB::bind_method(D_METHOD("get_surface_material_count"), &MeshInstance::get_surface_material_count);
- ClassDB::bind_method(D_METHOD("set_surface_material", "surface", "material"), &MeshInstance::set_surface_material);
- ClassDB::bind_method(D_METHOD("get_surface_material", "surface"), &MeshInstance::get_surface_material);
- ClassDB::bind_method(D_METHOD("get_active_material", "surface"), &MeshInstance::get_active_material);
-
- ClassDB::bind_method(D_METHOD("create_trimesh_collision"), &MeshInstance::create_trimesh_collision);
- ClassDB::set_method_flags("MeshInstance", "create_trimesh_collision", METHOD_FLAGS_DEFAULT);
- ClassDB::bind_method(D_METHOD("create_multiple_convex_collisions"), &MeshInstance::create_multiple_convex_collisions);
- ClassDB::set_method_flags("MeshInstance", "create_multiple_convex_collisions", METHOD_FLAGS_DEFAULT);
- ClassDB::bind_method(D_METHOD("create_convex_collision", "clean", "simplify"), &MeshInstance::create_convex_collision, DEFVAL(true), DEFVAL(false));
- ClassDB::set_method_flags("MeshInstance", "create_convex_collision", METHOD_FLAGS_DEFAULT);
- ClassDB::bind_method(D_METHOD("_mesh_changed"), &MeshInstance::_mesh_changed);
-
- ClassDB::bind_method(D_METHOD("create_debug_tangents"), &MeshInstance::create_debug_tangents);
- ClassDB::set_method_flags("MeshInstance", "create_debug_tangents", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
-
- ClassDB::bind_method(D_METHOD("is_mergeable_with", "other_mesh_instance"), &MeshInstance::is_mergeable_with);
- ClassDB::bind_method(D_METHOD("merge_meshes", "mesh_instances", "use_global_space", "check_compatibility"), &MeshInstance::merge_meshes, DEFVAL(Vector()), DEFVAL(false), DEFVAL(true));
- ClassDB::set_method_flags("MeshInstance", "merge_meshes", METHOD_FLAGS_DEFAULT);
-}
-
-MeshInstance::MeshInstance() {
-}
-
-MeshInstance::~MeshInstance() {
-}
diff --git a/scene/3d/mesh_instance.h b/scene/3d/mesh_instance.h
deleted file mode 100644
index 5f1d45d..0000000
--- a/scene/3d/mesh_instance.h
+++ /dev/null
@@ -1,117 +0,0 @@
-#ifndef MESH_INSTANCE_H
-#define MESH_INSTANCE_H
-/*************************************************************************/
-/* mesh_instance.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "scene/3d/visual_instance.h"
-
-#include "core/containers/local_vector.h"
-#include "core/object/reference.h"
-
-class Mesh;
-class NodePath;
-
-class MeshInstance : public GeometryInstance {
- GDCLASS(MeshInstance, GeometryInstance);
-
-protected:
- Ref mesh;
-
- struct BlendShapeTrack {
- int idx;
- float value;
- BlendShapeTrack() {
- idx = 0;
- value = 0;
- }
- };
-
- RBMap blend_shape_tracks;
- Vector> materials;
-
- void _mesh_changed();
-
-private:
- // merging
- bool _merge_meshes(Vector p_list, bool p_use_global_space, bool p_check_compatibility);
- bool _is_mergeable_with(const MeshInstance &p_other) const;
- void _merge_into_mesh_data(const MeshInstance &p_mi, const Transform &p_dest_tr_inv, int p_surface_id, LocalVector &r_verts, LocalVector &r_norms, LocalVector &r_tangents, LocalVector &r_colors, LocalVector &r_uvs, LocalVector