diff options
39 files changed, 1611 insertions, 137 deletions
diff --git a/core/math/math_2d.cpp b/core/math/math_2d.cpp index c77fe96ff2..11003c1cd5 100644 --- a/core/math/math_2d.cpp +++ b/core/math/math_2d.cpp @@ -222,35 +222,6 @@ Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, c (2.0 * p0 - 5.0 * p1 + 4 * p2 - p3) * t2 + (-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3); return out; - - /* - real_t mu = p_t; - real_t mu2 = mu*mu; - - Vector2 a0 = p_post_b - p_b - p_pre_a + *this; - Vector2 a1 = p_pre_a - *this - a0; - Vector2 a2 = p_b - p_pre_a; - Vector2 a3 = *this; - - return ( a0*mu*mu2 + a1*mu2 + a2*mu + a3 ); -*/ - /* - real_t t = p_t; - real_t t2 = t*t; - real_t t3 = t2*t; - - real_t a = 2.0*t3- 3.0*t2 + 1; - real_t b = -2.0*t3+ 3.0*t2; - real_t c = t3- 2.0*t2 + t; - real_t d = t3- t2; - - Vector2 p_a=*this; - - return Vector2( - (a * p_a.x) + (b *p_b.x) + (c * p_pre_a.x) + (d * p_post_b.x), - (a * p_a.y) + (b *p_b.y) + (c * p_pre_a.y) + (d * p_post_b.y) - ); -*/ } // slide returns the component of the vector along the given plane, specified by its normal vector. diff --git a/core/math/math_2d.h b/core/math/math_2d.h index d788318f5e..60351445c0 100644 --- a/core/math/math_2d.h +++ b/core/math/math_2d.h @@ -382,6 +382,11 @@ struct Rect2 { size = end - begin; } + inline Rect2 abs() const { + + return Rect2(Point2(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0)), size.abs()); + } + operator String() const { return String(position) + ", " + String(size); } Rect2() {} diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 991573e8d7..f66cce85c9 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -360,6 +360,7 @@ struct _VariantCall { VCALL_LOCALMEM2R(Rect2, grow_margin); VCALL_LOCALMEM4R(Rect2, grow_individual); VCALL_LOCALMEM1R(Rect2, expand); + VCALL_LOCALMEM0R(Rect2, abs); VCALL_LOCALMEM0R(Vector3, min_axis); VCALL_LOCALMEM0R(Vector3, max_axis); @@ -1526,6 +1527,7 @@ void register_variant_methods() { ADDFUNC2R(RECT2, RECT2, Rect2, grow_margin, INT, "margin", REAL, "by", varray()); ADDFUNC4R(RECT2, RECT2, Rect2, grow_individual, REAL, "left", REAL, "top", REAL, "right", REAL, " bottom", varray()); ADDFUNC1R(RECT2, RECT2, Rect2, expand, VECTOR2, "to", varray()); + ADDFUNC0R(RECT2, RECT2, Rect2, abs, varray()); ADDFUNC0R(VECTOR3, INT, Vector3, min_axis, varray()); ADDFUNC0R(VECTOR3, INT, Vector3, max_axis, varray()); diff --git a/doc/classes/Texture.xml b/doc/classes/Texture.xml index 855a8f12de..52972177bf 100644 --- a/doc/classes/Texture.xml +++ b/doc/classes/Texture.xml @@ -117,22 +117,26 @@ </methods> <constants> <constant name="FLAG_MIPMAPS" value="1" enum="Flags"> - Generate mipmaps, to enable smooth zooming out of the texture. + Generate mipmaps, which are smaller versions of the same texture to use when zoomed out, keeping the aspect ratio. </constant> <constant name="FLAG_REPEAT" value="2" enum="Flags"> - Repeat (instead of clamp to edge). + Repeats texture (instead of clamp to edge). </constant> <constant name="FLAG_FILTER" value="4" enum="Flags"> - Turn on magnifying filter, to enable smooth zooming in of the texture. + Magnifying filter, to enable smooth zooming in of the texture. </constant> <constant name="FLAGS_DEFAULT" value="7" enum="Flags"> Default flags. Generate mipmaps, repeat, and filter are enabled. </constant> <constant name="FLAG_ANISOTROPIC_FILTER" value="8" enum="Flags"> + Anisotropic mipmap filtering. Generates smaller versions of the same texture with different aspect ratios. + More effective on planes often shown going to the horrizon as those textures (Walls or Ground for example) get squashed in the viewport to different aspect ratios and regular mipmaps keep the aspect ratio so they don't optimize storage that well in those cases. </constant> <constant name="FLAG_CONVERT_TO_LINEAR" value="16" enum="Flags"> + Converts texture to SRGB color space. </constant> <constant name="FLAG_MIRRORED_REPEAT" value="32" enum="Flags"> + Repeats texture with alternate sections mirrored. </constant> <constant name="FLAG_VIDEO_SURFACE" value="4096" enum="Flags"> Texture is a video surface. diff --git a/doc/classes/VisualServer.xml b/doc/classes/VisualServer.xml index 479c0606f2..6627ba15d5 100644 --- a/doc/classes/VisualServer.xml +++ b/doc/classes/VisualServer.xml @@ -24,6 +24,7 @@ <argument index="3" name="bottom" type="RID"> </argument> <description> + Sets images to be rendered in the window margin. </description> </method> <method name="black_bars_set_margins"> @@ -38,12 +39,14 @@ <argument index="3" name="bottom" type="int"> </argument> <description> + Sets margin size, where black bars (or images, if [method black_bars_set_images] was used) are rendered. </description> </method> <method name="canvas_create"> <return type="RID"> </return> <description> + Creates a canvas and returns the assigned [RID]. </description> </method> <method name="canvas_item_add_circle"> @@ -58,6 +61,7 @@ <argument index="3" name="color" type="Color"> </argument> <description> + Adds a circle command to the [CanvasItem]'s draw commands. </description> </method> <method name="canvas_item_add_clip_ignore"> @@ -68,6 +72,7 @@ <argument index="1" name="ignore" type="bool"> </argument> <description> + If ignore is [code]true[/code], the VisualServer does not perform clipping. </description> </method> <method name="canvas_item_add_line"> @@ -86,6 +91,7 @@ <argument index="5" name="antialiased" type="bool" default="false"> </argument> <description> + Adds a line command to the [CanvasItem]'s draw commands. </description> </method> <method name="canvas_item_add_mesh"> @@ -98,6 +104,7 @@ <argument index="2" name="skeleton" type="RID"> </argument> <description> + Adds a [Mesh] to the [CanvasItem]'s draw commands. Only affects its aabb at the moment. </description> </method> <method name="canvas_item_add_multimesh"> @@ -110,6 +117,7 @@ <argument index="2" name="skeleton" type="RID"> </argument> <description> + Adds a [MultiMesh] to the [CanvasItem]'s draw commands. Only affects its aabb at the moment. </description> </method> <method name="canvas_item_add_nine_patch"> @@ -138,6 +146,8 @@ <argument index="10" name="normal_map" type="RID"> </argument> <description> + Adds a nine patch image to the [CanvasItem]'s draw commands. + See [NinePatchRect] for more explanation. </description> </method> <method name="canvas_item_add_particles"> @@ -156,6 +166,7 @@ <argument index="5" name="v_frames" type="int"> </argument> <description> + Adds a particles system to the [CanvasItem]'s draw commands. </description> </method> <method name="canvas_item_add_polygon"> @@ -176,6 +187,7 @@ <argument index="6" name="antialiased" type="bool" default="false"> </argument> <description> + Adds a polygon to the [CanvasItem]'s draw commands. </description> </method> <method name="canvas_item_add_polyline"> @@ -192,6 +204,7 @@ <argument index="4" name="antialiased" type="bool" default="false"> </argument> <description> + Adds a polyline, which is a line from mutliple points with a width, to the [CanvasItem]'s draw commands. </description> </method> <method name="canvas_item_add_primitive"> @@ -212,6 +225,7 @@ <argument index="6" name="normal_map" type="RID"> </argument> <description> + Adds a primitive to the [CanvasItem]'s draw commands. </description> </method> <method name="canvas_item_add_rect"> @@ -224,6 +238,7 @@ <argument index="2" name="color" type="Color"> </argument> <description> + Adds a rectangle to the [CanvasItem]'s draw commands. </description> </method> <method name="canvas_item_add_set_transform"> @@ -234,6 +249,8 @@ <argument index="1" name="transform" type="Transform2D"> </argument> <description> + Adds a [Transform2D] command to the [CanvasItem]'s draw commands. + This sets the extra_matrix uniform when executed. This affects the later command's of the canvas item. </description> </method> <method name="canvas_item_add_texture_rect"> @@ -254,6 +271,7 @@ <argument index="6" name="normal_map" type="RID"> </argument> <description> + Adds a textured rect to the [CanvasItem]'s draw commands. </description> </method> <method name="canvas_item_add_texture_rect_region"> @@ -276,6 +294,7 @@ <argument index="7" name="clip_uv" type="bool" default="true"> </argument> <description> + Adds a texture rect with region setting to the [CanvasItem]'s draw commands. </description> </method> <method name="canvas_item_add_triangle_array"> @@ -298,6 +317,7 @@ <argument index="7" name="normal_map" type="RID"> </argument> <description> + Adds a triangle array to the [CanvasItem]'s draw commands. </description> </method> <method name="canvas_item_clear"> @@ -306,12 +326,14 @@ <argument index="0" name="item" type="RID"> </argument> <description> + Clears the [CanvasItem] and removes all commands in it. </description> </method> <method name="canvas_item_create"> <return type="RID"> </return> <description> + Creates a new [CanvasItem] and returns its [RID]. </description> </method> <method name="canvas_item_set_clip"> @@ -322,6 +344,7 @@ <argument index="1" name="clip" type="bool"> </argument> <description> + Sets clipping for the [CanvasItem]. </description> </method> <method name="canvas_item_set_copy_to_backbuffer"> @@ -334,6 +357,7 @@ <argument index="2" name="rect" type="Rect2"> </argument> <description> + Sets the [CanvasItem] to copy a rect to the backbuffer. </description> </method> <method name="canvas_item_set_custom_rect"> @@ -346,6 +370,7 @@ <argument index="2" name="rect" type="Rect2" default="Rect2( 0, 0, 0, 0 )"> </argument> <description> + Defines a custom drawing rectangle for the [CanvasItem]. </description> </method> <method name="canvas_item_set_distance_field_mode"> @@ -366,6 +391,7 @@ <argument index="1" name="enabled" type="bool"> </argument> <description> + Sets [CanvasItem] to be drawn behind its parent. </description> </method> <method name="canvas_item_set_draw_index"> @@ -376,6 +402,7 @@ <argument index="1" name="index" type="int"> </argument> <description> + Sets the index for the [CanvasItem]. </description> </method> <method name="canvas_item_set_light_mask"> @@ -386,6 +413,7 @@ <argument index="1" name="mask" type="int"> </argument> <description> + The light mask. See [LightOccluder2D] for more information on light masks. </description> </method> <method name="canvas_item_set_material"> @@ -396,6 +424,7 @@ <argument index="1" name="material" type="RID"> </argument> <description> + Sets a new material to the [CanvasItem]. </description> </method> <method name="canvas_item_set_modulate"> @@ -406,6 +435,7 @@ <argument index="1" name="color" type="Color"> </argument> <description> + Sets the color that modulates the [CanvasItem] and its children. </description> </method> <method name="canvas_item_set_parent"> @@ -416,6 +446,7 @@ <argument index="1" name="parent" type="RID"> </argument> <description> + Sets the parent for the [CanvasItem]. </description> </method> <method name="canvas_item_set_self_modulate"> @@ -426,6 +457,7 @@ <argument index="1" name="color" type="Color"> </argument> <description> + Sets the color that modulates the [CanvasItem] without children. </description> </method> <method name="canvas_item_set_sort_children_by_y"> @@ -436,6 +468,7 @@ <argument index="1" name="enabled" type="bool"> </argument> <description> + Sets if [CanvasItem]'s children should be sorted by y-position. </description> </method> <method name="canvas_item_set_transform"> @@ -446,6 +479,7 @@ <argument index="1" name="transform" type="Transform2D"> </argument> <description> + Sets the [CanvasItem]'s [Transform2D]. </description> </method> <method name="canvas_item_set_use_parent_material"> @@ -456,6 +490,7 @@ <argument index="1" name="enabled" type="bool"> </argument> <description> + Sets if the [CanvasItem] uses its parent's material. </description> </method> <method name="canvas_item_set_visible"> @@ -466,6 +501,7 @@ <argument index="1" name="visible" type="bool"> </argument> <description> + Sets if the canvas item (including its children) is visible. </description> </method> <method name="canvas_item_set_z"> @@ -476,6 +512,7 @@ <argument index="1" name="z" type="int"> </argument> <description> + Sets the [CanvasItem]'s z order position. </description> </method> <method name="canvas_item_set_z_as_relative_to_parent"> @@ -486,6 +523,7 @@ <argument index="1" name="enabled" type="bool"> </argument> <description> + If this is enabled, the z-position of the parent will be added to the childrens z-position. </description> </method> <method name="canvas_light_attach_to_canvas"> @@ -496,12 +534,14 @@ <argument index="1" name="canvas" type="RID"> </argument> <description> + Attaches the canvas light to the canvas. Removes it from its previous canvas. </description> </method> <method name="canvas_light_create"> <return type="RID"> </return> <description> + Creates a canvas light. </description> </method> <method name="canvas_light_occluder_attach_to_canvas"> @@ -512,12 +552,14 @@ <argument index="1" name="canvas" type="RID"> </argument> <description> + Attaches a light occluder to the canvas. Removes it from its previous canvas. </description> </method> <method name="canvas_light_occluder_create"> <return type="RID"> </return> <description> + Creates a light occluder. </description> </method> <method name="canvas_light_occluder_set_enabled"> @@ -528,6 +570,7 @@ <argument index="1" name="enabled" type="bool"> </argument> <description> + Enables or disables light occluder. </description> </method> <method name="canvas_light_occluder_set_light_mask"> @@ -538,6 +581,7 @@ <argument index="1" name="mask" type="int"> </argument> <description> + The light mask. See [LightOccluder2D] for more information on light masks </description> </method> <method name="canvas_light_occluder_set_polygon"> @@ -548,6 +592,7 @@ <argument index="1" name="polygon" type="RID"> </argument> <description> + Sets a light occluder's polygon. </description> </method> <method name="canvas_light_occluder_set_transform"> @@ -558,6 +603,7 @@ <argument index="1" name="transform" type="Transform2D"> </argument> <description> + Sets a light occluder's [Transform2D]. </description> </method> <method name="canvas_light_set_color"> @@ -568,6 +614,7 @@ <argument index="1" name="color" type="Color"> </argument> <description> + Sets the color for a light. </description> </method> <method name="canvas_light_set_enabled"> @@ -578,6 +625,7 @@ <argument index="1" name="enabled" type="bool"> </argument> <description> + Enables or disables a canvas light. </description> </method> <method name="canvas_light_set_energy"> @@ -588,6 +636,7 @@ <argument index="1" name="energy" type="float"> </argument> <description> + Sets a canvas light's energy. </description> </method> <method name="canvas_light_set_height"> @@ -598,6 +647,7 @@ <argument index="1" name="height" type="float"> </argument> <description> + Sets a canvas light's height. </description> </method> <method name="canvas_light_set_item_cull_mask"> @@ -608,6 +658,7 @@ <argument index="1" name="mask" type="int"> </argument> <description> + The light mask. See [LightOccluder2D] for more information on light masks </description> </method> <method name="canvas_light_set_item_shadow_cull_mask"> @@ -618,6 +669,7 @@ <argument index="1" name="mask" type="int"> </argument> <description> + The shadow mask. binary about wich layers this canvas light affects wich canvas item's shadows. See [LightOccluder2D] for more information on light masks. </description> </method> <method name="canvas_light_set_layer_range"> @@ -630,6 +682,7 @@ <argument index="2" name="max_layer" type="int"> </argument> <description> + The layer range that gets rendered with this light. </description> </method> <method name="canvas_light_set_mode"> @@ -640,6 +693,7 @@ <argument index="1" name="mode" type="int" enum="VisualServer.CanvasLightMode"> </argument> <description> + The mode of the light, see CANVAS_LIGHT_MODE_* constants. </description> </method> <method name="canvas_light_set_scale"> @@ -660,6 +714,7 @@ <argument index="1" name="size" type="int"> </argument> <description> + Sets the width of the shadow buffer, size gets scaled to the next power of two for this. </description> </method> <method name="canvas_light_set_shadow_color"> @@ -670,6 +725,7 @@ <argument index="1" name="color" type="Color"> </argument> <description> + Sets the color of the canvas light's shadow. </description> </method> <method name="canvas_light_set_shadow_enabled"> @@ -680,6 +736,7 @@ <argument index="1" name="enabled" type="bool"> </argument> <description> + Enables or disables the canvas light's shadow. </description> </method> <method name="canvas_light_set_shadow_filter"> @@ -690,6 +747,7 @@ <argument index="1" name="filter" type="int" enum="VisualServer.CanvasLightShadowFilter"> </argument> <description> + Sets the canvas light's shadow's filter, see CANVAS_LIGHT_SHADOW_FILTER_* constants. </description> </method> <method name="canvas_light_set_shadow_gradient_length"> @@ -700,6 +758,7 @@ <argument index="1" name="length" type="float"> </argument> <description> + Sets the length of the shadow's gradient. </description> </method> <method name="canvas_light_set_shadow_smooth"> @@ -710,6 +769,7 @@ <argument index="1" name="smooth" type="float"> </argument> <description> + Smoothens the shadow. The lower, the more smooth. </description> </method> <method name="canvas_light_set_texture"> @@ -740,6 +800,7 @@ <argument index="1" name="transform" type="Transform2D"> </argument> <description> + Sets the canvas light's [Transform2D]. </description> </method> <method name="canvas_light_set_z_range"> @@ -758,6 +819,7 @@ <return type="RID"> </return> <description> + Creates a new light occluder polygon. </description> </method> <method name="canvas_occluder_polygon_set_cull_mode"> @@ -768,6 +830,7 @@ <argument index="1" name="mode" type="int" enum="VisualServer.CanvasOccluderPolygonCullMode"> </argument> <description> + Sets an occluder polygons cull mode. See CANVAS_OCCLUDER_POLYGON_CULL_MODE_* constants. </description> </method> <method name="canvas_occluder_polygon_set_shape"> @@ -780,6 +843,7 @@ <argument index="2" name="closed" type="bool"> </argument> <description> + Sets the shape of the occluder polygon. </description> </method> <method name="canvas_occluder_polygon_set_shape_as_lines"> @@ -790,6 +854,7 @@ <argument index="1" name="shape" type="PoolVector2Array"> </argument> <description> + Sets the shape of the occluder polygon as lines. </description> </method> <method name="canvas_set_item_mirroring"> @@ -802,6 +867,7 @@ <argument index="2" name="mirroring" type="Vector2"> </argument> <description> + A copy of the canvas item will be drawn with a local offset of the mirroring [Vector2]. </description> </method> <method name="canvas_set_modulate"> @@ -812,6 +878,7 @@ <argument index="1" name="color" type="Color"> </argument> <description> + Modulates all colors in the given canvas. </description> </method> <method name="draw"> @@ -820,12 +887,14 @@ <argument index="0" name="swap_buffers" type="bool" default="true"> </argument> <description> + Draws a frame. </description> </method> <method name="finish"> <return type="void"> </return> <description> + Removes buffers and clears testcubes. </description> </method> <method name="force_draw"> @@ -834,12 +903,14 @@ <argument index="0" name="swap_buffers" type="bool" default="true"> </argument> <description> + Draws a frame. Same as [method draw]. </description> </method> <method name="force_sync"> <return type="void"> </return> <description> + Syncronizes threads. </description> </method> <method name="free"> @@ -848,6 +919,7 @@ <argument index="0" name="rid" type="RID"> </argument> <description> + Tries to free an object in the VisualServer. </description> </method> <method name="get_render_info"> @@ -856,30 +928,35 @@ <argument index="0" name="info" type="int" enum="VisualServer.RenderInfo"> </argument> <description> + Returns a certain information, see RENDER_INFO_* for options. </description> </method> <method name="get_test_cube"> <return type="RID"> </return> <description> + Returns the id of the test cube. Creates one if none exists. </description> </method> <method name="get_test_texture"> <return type="RID"> </return> <description> + Returns the id of the test texture. Creates one if none exists. </description> </method> <method name="get_white_texture"> <return type="RID"> </return> <description> + Returns the id of a white texture. Creates one if none exists. </description> </method> <method name="has_changed" qualifiers="const"> <return type="bool"> </return> <description> + Returns [code]true[/code] if changes have been made to the VisualServer's data. [method draw] is usually called if this happens. </description> </method> <method name="has_feature" qualifiers="const"> @@ -896,12 +973,14 @@ <argument index="0" name="feature" type="String"> </argument> <description> + Returns true, if the OS supports a certain feature. Features might be s3tc, etc, etc2 and pvrtc, </description> </method> <method name="init"> <return type="void"> </return> <description> + Initializes the visual server. </description> </method> <method name="make_sphere_mesh"> @@ -914,12 +993,14 @@ <argument index="2" name="radius" type="float"> </argument> <description> + Returns a mesh of a sphere with the given amount of horizontal and vertical subdivisions. </description> </method> <method name="material_create"> <return type="RID"> </return> <description> + Returns an empty material. </description> </method> <method name="material_get_param" qualifiers="const"> @@ -930,6 +1011,7 @@ <argument index="1" name="parameter" type="String"> </argument> <description> + Returns the value of a certain material's parameter. </description> </method> <method name="material_get_shader" qualifiers="const"> @@ -938,6 +1020,7 @@ <argument index="0" name="shader_material" type="RID"> </argument> <description> + Returns the shader of a certain material's shader. Returns an empty RID if the material doesn't have a shader. </description> </method> <method name="material_set_line_width"> @@ -948,6 +1031,7 @@ <argument index="1" name="width" type="float"> </argument> <description> + Sets a materials line width. </description> </method> <method name="material_set_next_pass"> @@ -958,6 +1042,7 @@ <argument index="1" name="next_material" type="RID"> </argument> <description> + Sets an objects next material. </description> </method> <method name="material_set_param"> @@ -970,6 +1055,7 @@ <argument index="2" name="value" type="Variant"> </argument> <description> + Sets a materials parameter. </description> </method> <method name="material_set_render_priority"> @@ -980,6 +1066,7 @@ <argument index="1" name="priority" type="int"> </argument> <description> + Sets a material's render priority. </description> </method> <method name="material_set_shader"> @@ -990,6 +1077,7 @@ <argument index="1" name="shader" type="RID"> </argument> <description> + Sets a shader material's shader. </description> </method> <method name="mesh_add_surface_from_arrays"> @@ -1006,6 +1094,7 @@ <argument index="4" name="compress_format" type="int" default="97792"> </argument> <description> + Adds a surface generated from the Arrays to a mesh. See PRIMITIVE_TYPE_* constants for types. </description> </method> <method name="mesh_clear"> @@ -1014,12 +1103,14 @@ <argument index="0" name="mesh" type="RID"> </argument> <description> + Removes all surfaces from a mesh. </description> </method> <method name="mesh_create"> <return type="RID"> </return> <description> + Creates a new mesh. </description> </method> <method name="mesh_get_blend_shape_count" qualifiers="const"> @@ -1028,6 +1119,7 @@ <argument index="0" name="mesh" type="RID"> </argument> <description> + Returns a mesh's blend shape count. </description> </method> <method name="mesh_get_blend_shape_mode" qualifiers="const"> @@ -1036,6 +1128,7 @@ <argument index="0" name="mesh" type="RID"> </argument> <description> + Returns a mesh's blend shape mode. </description> </method> <method name="mesh_get_custom_aabb" qualifiers="const"> @@ -1044,6 +1137,7 @@ <argument index="0" name="mesh" type="RID"> </argument> <description> + Returns a mesh's custom aabb. </description> </method> <method name="mesh_get_surface_count" qualifiers="const"> @@ -1052,6 +1146,7 @@ <argument index="0" name="mesh" type="RID"> </argument> <description> + Returns a mesh's number of surfaces. </description> </method> <method name="mesh_remove_surface"> @@ -1062,6 +1157,7 @@ <argument index="1" name="index" type="int"> </argument> <description> + Removes a mesh's surface. </description> </method> <method name="mesh_set_blend_shape_count"> @@ -1072,6 +1168,7 @@ <argument index="1" name="amount" type="int"> </argument> <description> + Sets a mesh's blend shape count. </description> </method> <method name="mesh_set_blend_shape_mode"> @@ -1082,6 +1179,7 @@ <argument index="1" name="mode" type="int" enum="VisualServer.BlendShapeMode"> </argument> <description> + Sets a mesh's blend shape mode. </description> </method> <method name="mesh_set_custom_aabb"> @@ -1092,6 +1190,7 @@ <argument index="1" name="aabb" type="AABB"> </argument> <description> + Sets a mesh's custom aabb. </description> </method> <method name="mesh_surface_get_aabb" qualifiers="const"> @@ -1102,6 +1201,7 @@ <argument index="1" name="surface" type="int"> </argument> <description> + Returns a mesh's surface's aabb. </description> </method> <method name="mesh_surface_get_array" qualifiers="const"> @@ -1112,6 +1212,7 @@ <argument index="1" name="surface" type="int"> </argument> <description> + Returns a mesh's surface's vertex buffer. </description> </method> <method name="mesh_surface_get_array_index_len" qualifiers="const"> @@ -1122,6 +1223,7 @@ <argument index="1" name="surface" type="int"> </argument> <description> + Returns a mesh's surface's amount of indices. </description> </method> <method name="mesh_surface_get_array_len" qualifiers="const"> @@ -1132,6 +1234,7 @@ <argument index="1" name="surface" type="int"> </argument> <description> + Returns a mesh's surface's amount of vertices. </description> </method> <method name="mesh_surface_get_arrays" qualifiers="const"> @@ -1142,6 +1245,7 @@ <argument index="1" name="surface" type="int"> </argument> <description> + Returns a mesh's surface's buffer arrays. </description> </method> <method name="mesh_surface_get_blend_shape_arrays" qualifiers="const"> @@ -1152,6 +1256,7 @@ <argument index="1" name="surface" type="int"> </argument> <description> + Returns a mesh's surface's arrays for blend shapes </description> </method> <method name="mesh_surface_get_format" qualifiers="const"> @@ -1162,6 +1267,7 @@ <argument index="1" name="surface" type="int"> </argument> <description> + Returns the format of a mesh's surface. </description> </method> <method name="mesh_surface_get_index_array" qualifiers="const"> @@ -1172,6 +1278,7 @@ <argument index="1" name="surface" type="int"> </argument> <description> + Returns a mesh's surface's index buffer. </description> </method> <method name="mesh_surface_get_material" qualifiers="const"> @@ -1182,6 +1289,7 @@ <argument index="1" name="surface" type="int"> </argument> <description> + Returns a mesh's surface's material. </description> </method> <method name="mesh_surface_get_primitive_type" qualifiers="const"> @@ -1192,6 +1300,7 @@ <argument index="1" name="surface" type="int"> </argument> <description> + Returns the primitive type of a mesh's surface. </description> </method> <method name="mesh_surface_get_skeleton_aabb" qualifiers="const"> @@ -1202,6 +1311,7 @@ <argument index="1" name="surface" type="int"> </argument> <description> + Returns the aabb of a mesh's surface's skeleton. </description> </method> <method name="mesh_surface_set_material"> @@ -1214,6 +1324,7 @@ <argument index="2" name="material" type="RID"> </argument> <description> + Sets a mesh's surface's material. </description> </method> <method name="request_frame_drawn_callback"> @@ -1240,6 +1351,7 @@ <argument index="2" name="scale" type="bool"> </argument> <description> + Sets a boot image. The color defines the background color and if scale is [code]true[/code], the image will be scaled to fit the screen size. </description> </method> <method name="set_debug_generate_wireframes"> @@ -1262,6 +1374,7 @@ <return type="RID"> </return> <description> + Creates an empty shader. </description> </method> <method name="shader_get_code" qualifiers="const"> @@ -1270,6 +1383,7 @@ <argument index="0" name="shader" type="RID"> </argument> <description> + Returns a shader's code. </description> </method> <method name="shader_get_default_texture_param" qualifiers="const"> @@ -1280,6 +1394,7 @@ <argument index="1" name="name" type="String"> </argument> <description> + Returns a default texture from a shader searched by name. </description> </method> <method name="shader_get_param_list" qualifiers="const"> @@ -1288,6 +1403,7 @@ <argument index="0" name="shader" type="RID"> </argument> <description> + Returns the parameters of a shader. </description> </method> <method name="shader_set_code"> @@ -1298,6 +1414,7 @@ <argument index="1" name="code" type="String"> </argument> <description> + Sets a shader's code. </description> </method> <method name="shader_set_default_texture_param"> @@ -1310,12 +1427,14 @@ <argument index="2" name="texture" type="RID"> </argument> <description> + Sets a shader's default texture. Overwrites the texture given by name. </description> </method> <method name="sky_create"> <return type="RID"> </return> <description> + Creates an empty sky. </description> </method> <method name="sky_set_texture"> @@ -1328,6 +1447,7 @@ <argument index="2" name="radiance_size" type="int"> </argument> <description> + Sets a sky's texture. </description> </method> <method name="sync"> @@ -1350,12 +1470,14 @@ <argument index="4" name="flags" type="int" default="7"> </argument> <description> + Allocates space for a texture's image or video. </description> </method> <method name="texture_create"> <return type="RID"> </return> <description> + Creates an empty texture. </description> </method> <method name="texture_create_from_image"> @@ -1366,12 +1488,14 @@ <argument index="1" name="flags" type="int" default="7"> </argument> <description> + Creates a texture, allocates the space for an image, and fills in the image. </description> </method> <method name="texture_debug_usage"> <return type="Array"> </return> <description> + Returns a list of all the textures and their information. </description> </method> <method name="texture_get_data" qualifiers="const"> @@ -1382,6 +1506,7 @@ <argument index="1" name="cube_side" type="int" enum="VisualServer.CubeMapSide" default="0"> </argument> <description> + Returns a copy of a texture's image unless it's a CubeMap, in wich case it returns the [RID] of the image at one of the cubes sides. </description> </method> <method name="texture_get_flags" qualifiers="const"> @@ -1390,6 +1515,7 @@ <argument index="0" name="texture" type="RID"> </argument> <description> + Returns the flags of a texture. </description> </method> <method name="texture_get_format" qualifiers="const"> @@ -1398,6 +1524,7 @@ <argument index="0" name="texture" type="RID"> </argument> <description> + Returns the format of the texture's image. </description> </method> <method name="texture_get_height" qualifiers="const"> @@ -1406,6 +1533,7 @@ <argument index="0" name="texture" type="RID"> </argument> <description> + Returns the texture's height. </description> </method> <method name="texture_get_path" qualifiers="const"> @@ -1414,6 +1542,7 @@ <argument index="0" name="texture" type="RID"> </argument> <description> + Returns the texture's path. </description> </method> <method name="texture_get_texid" qualifiers="const"> @@ -1422,6 +1551,7 @@ <argument index="0" name="texture" type="RID"> </argument> <description> + Returns the opengl id of the texture's image. </description> </method> <method name="texture_get_width" qualifiers="const"> @@ -1430,6 +1560,7 @@ <argument index="0" name="texture" type="RID"> </argument> <description> + Returns the texture's width. </description> </method> <method name="texture_set_data"> @@ -1442,6 +1573,7 @@ <argument index="2" name="cube_side" type="int" enum="VisualServer.CubeMapSide" default="0"> </argument> <description> + Sets the texture's image data. If it's a CubeMap, it sets the image data at a cube side. </description> </method> <method name="texture_set_flags"> @@ -1452,6 +1584,7 @@ <argument index="1" name="flags" type="int"> </argument> <description> + Sets the texture's flags. See [enum TextureFlags] for options </description> </method> <method name="texture_set_path"> @@ -1462,6 +1595,7 @@ <argument index="1" name="path" type="String"> </argument> <description> + Sets the texture's path. </description> </method> <method name="texture_set_shrink_all_x2_on_set_data"> @@ -1470,6 +1604,7 @@ <argument index="0" name="shrink" type="bool"> </argument> <description> + If [code]true[/code], sets internal processes to shrink all image data to half the size. </description> </method> <method name="texture_set_size_override"> @@ -1482,6 +1617,7 @@ <argument index="2" name="height" type="int"> </argument> <description> + Overwrites the texture's width and height. </description> </method> <method name="textures_keep_original"> @@ -1490,6 +1626,7 @@ <argument index="0" name="enable" type="bool"> </argument> <description> + If [code]true[/code], the image will be stored in the texture's images array if overwritten. </description> </method> <method name="viewport_attach_camera"> @@ -1500,6 +1637,7 @@ <argument index="1" name="camera" type="RID"> </argument> <description> + Sets a viewport's camera. </description> </method> <method name="viewport_attach_canvas"> @@ -1510,6 +1648,7 @@ <argument index="1" name="canvas" type="RID"> </argument> <description> + Sets a viewport's canvas. </description> </method> <method name="viewport_attach_to_screen"> @@ -1522,12 +1661,14 @@ <argument index="2" name="screen" type="int" default="0"> </argument> <description> + Attaches a viewport to a screen. </description> </method> <method name="viewport_create"> <return type="RID"> </return> <description> + Creates an empty viewport. </description> </method> <method name="viewport_detach"> @@ -1536,6 +1677,7 @@ <argument index="0" name="viewport" type="RID"> </argument> <description> + Detaches the viewport from the screen. </description> </method> <method name="viewport_get_render_info"> @@ -1546,6 +1688,7 @@ <argument index="1" name="info" type="int" enum="VisualServer.ViewportRenderInfo"> </argument> <description> + Returns a viewport's render info. for options see VIEWPORT_RENDER_INFO* constants. </description> </method> <method name="viewport_get_texture" qualifiers="const"> @@ -1554,6 +1697,7 @@ <argument index="0" name="viewport" type="RID"> </argument> <description> + Returns the viewport's last rendered frame. </description> </method> <method name="viewport_remove_canvas"> @@ -1564,6 +1708,7 @@ <argument index="1" name="canvas" type="RID"> </argument> <description> + Detaches a viewport from a canvas and vice versa. </description> </method> <method name="viewport_set_active"> @@ -1574,6 +1719,7 @@ <argument index="1" name="active" type="bool"> </argument> <description> + If [code]true[/code], sets the viewport active, else sets it inactive. </description> </method> <method name="viewport_set_canvas_layer"> @@ -1586,6 +1732,7 @@ <argument index="2" name="layer" type="int"> </argument> <description> + Sets the renderlayer for a viewport's canvas. </description> </method> <method name="viewport_set_canvas_transform"> @@ -1598,6 +1745,7 @@ <argument index="2" name="offset" type="Transform2D"> </argument> <description> + Sets the transformation of a viewport's canvas. </description> </method> <method name="viewport_set_clear_mode"> @@ -1608,6 +1756,7 @@ <argument index="1" name="clear_mode" type="int" enum="VisualServer.ViewportClearMode"> </argument> <description> + Sets the clear mode of a viewport. See VIEWPORT_CLEAR_MODE_* constants for options. </description> </method> <method name="viewport_set_debug_draw"> @@ -1618,6 +1767,7 @@ <argument index="1" name="draw" type="int" enum="VisualServer.ViewportDebugDraw"> </argument> <description> + Sets the debug draw mode of a viewport. See VIEWPORT_DEBUG_DRAW_* constants for options. </description> </method> <method name="viewport_set_disable_3d"> @@ -1628,6 +1778,7 @@ <argument index="1" name="disabled" type="bool"> </argument> <description> + If [code]true[/code] a viewport's 3D rendering should be disabled. </description> </method> <method name="viewport_set_disable_environment"> @@ -1638,6 +1789,7 @@ <argument index="1" name="disabled" type="bool"> </argument> <description> + If [code]true[/code] rendering of a viewport's environment should be disabled. </description> </method> <method name="viewport_set_global_canvas_transform"> @@ -1648,6 +1800,7 @@ <argument index="1" name="transform" type="Transform2D"> </argument> <description> + Sets the viewport's global transformation matrix. </description> </method> <method name="viewport_set_hdr"> @@ -1658,6 +1811,7 @@ <argument index="1" name="enabled" type="bool"> </argument> <description> + If [code]true[/code] the viewport should render to hdr. </description> </method> <method name="viewport_set_hide_canvas"> @@ -1668,6 +1822,7 @@ <argument index="1" name="hidden" type="bool"> </argument> <description> + If [code]true[/code] the viewport's canvas should not be rendered. </description> </method> <method name="viewport_set_hide_scenario"> @@ -1688,6 +1843,7 @@ <argument index="1" name="msaa" type="int" enum="VisualServer.ViewportMSAA"> </argument> <description> + Sets the anti-aliasing mode. see [enum ViewportMSAA] for options. </description> </method> <method name="viewport_set_parent_viewport"> @@ -1698,6 +1854,7 @@ <argument index="1" name="parent_viewport" type="RID"> </argument> <description> + Sets the viewport's parent to another viewport. </description> </method> <method name="viewport_set_scenario"> @@ -1708,6 +1865,8 @@ <argument index="1" name="scenario" type="RID"> </argument> <description> + Sets a viewport's scenario. + The scenario contains information about the [enum ScenarioDebugMode], environment information, reflection atlas etc. </description> </method> <method name="viewport_set_shadow_atlas_quadrant_subdivision"> @@ -1720,6 +1879,7 @@ <argument index="2" name="subdivision" type="int"> </argument> <description> + Sets the shadow atlas quadrant's subdivision. </description> </method> <method name="viewport_set_shadow_atlas_size"> @@ -1730,6 +1890,7 @@ <argument index="1" name="size" type="int"> </argument> <description> + Sets the size of the shadow atlas's images. </description> </method> <method name="viewport_set_size"> @@ -1742,6 +1903,7 @@ <argument index="2" name="height" type="int"> </argument> <description> + Sets the viewport's width and height. </description> </method> <method name="viewport_set_transparent_background"> @@ -1752,6 +1914,7 @@ <argument index="1" name="enabled" type="bool"> </argument> <description> + If [code]true[/code] the viewport should render its background as transparent. </description> </method> <method name="viewport_set_update_mode"> @@ -1762,6 +1925,7 @@ <argument index="1" name="update_mode" type="int" enum="VisualServer.ViewportUpdateMode"> </argument> <description> + Sets when the viewport should be updated. See VIEWPORT_UPDATE_MODE_* constants for options. </description> </method> <method name="viewport_set_usage"> @@ -1772,6 +1936,7 @@ <argument index="1" name="usage" type="int" enum="VisualServer.ViewportUsage"> </argument> <description> + Sets what should be rendered in the viewport. See VIEWPORT_USAGE_* constants for options. </description> </method> <method name="viewport_set_use_arvr"> @@ -1782,6 +1947,7 @@ <argument index="1" name="use_arvr" type="bool"> </argument> <description> + If [code]true[/code] the viewport should use augmented or virtual reality technologies. See [ARVRInterface]. </description> </method> <method name="viewport_set_vflip"> @@ -1792,6 +1958,7 @@ <argument index="1" name="enabled" type="bool"> </argument> <description> + If [code]true[/code] the viewport's rendering should be flipped vertically. </description> </method> </methods> @@ -1803,160 +1970,232 @@ </signals> <constants> <constant name="NO_INDEX_ARRAY" value="-1"> + Marks an error that shows that the index array is empty. </constant> <constant name="ARRAY_WEIGHTS_SIZE" value="4"> </constant> <constant name="CANVAS_ITEM_Z_MIN" value="-4096"> + The minimum Z-layer for canvas items. </constant> <constant name="CANVAS_ITEM_Z_MAX" value="4096"> + The maximum Z-layer for canvas items. </constant> <constant name="MAX_GLOW_LEVELS" value="7"> </constant> <constant name="MAX_CURSORS" value="8"> </constant> <constant name="MATERIAL_RENDER_PRIORITY_MIN" value="-128"> + The minimum renderpriority of all materials. </constant> <constant name="MATERIAL_RENDER_PRIORITY_MAX" value="127"> + The maximum renderpriority of all materials. </constant> <constant name="CUBEMAP_LEFT" value="0" enum="CubeMapSide"> + Marks the left side of a cubemap. </constant> <constant name="CUBEMAP_RIGHT" value="1" enum="CubeMapSide"> + Marks the right side of a cubemap. </constant> <constant name="CUBEMAP_BOTTOM" value="2" enum="CubeMapSide"> + Marks the bottom side of a cubemap. </constant> <constant name="CUBEMAP_TOP" value="3" enum="CubeMapSide"> + Marks the top side of a cubemap. </constant> <constant name="CUBEMAP_FRONT" value="4" enum="CubeMapSide"> + Marks the front side of a cubemap. </constant> <constant name="CUBEMAP_BACK" value="5" enum="CubeMapSide"> + Marks the back side of a cubemap. </constant> <constant name="TEXTURE_FLAG_MIPMAPS" value="1" enum="TextureFlags"> + Generate mipmaps, which are smaller versions of the same texture to use when zoomed out, keeping the aspect ratio. </constant> <constant name="TEXTURE_FLAG_REPEAT" value="2" enum="TextureFlags"> + Repeat (instead of clamp to edge). </constant> <constant name="TEXTURE_FLAG_FILTER" value="4" enum="TextureFlags"> + Turn on magnifying filter, to enable smooth zooming in of the texture. </constant> <constant name="TEXTURE_FLAG_ANISOTROPIC_FILTER" value="8" enum="TextureFlags"> + Anisotropic mipmap filtering. Generates smaller versions of the same texture with different aspect ratios. + More effective on planes often shown going to the horrizon as those textures (Walls or Ground for example) get squashed in the viewport to different aspect ratios and regular mipmaps keep the aspect ratio so they don't optimize storage that well in those cases. </constant> <constant name="TEXTURE_FLAG_CONVERT_TO_LINEAR" value="16" enum="TextureFlags"> + Converts texture to SRGB color space. </constant> <constant name="TEXTURE_FLAG_MIRRORED_REPEAT" value="32" enum="TextureFlags"> + Repeat texture with alternate sections mirrored. </constant> <constant name="TEXTURE_FLAG_CUBEMAP" value="2048" enum="TextureFlags"> + Texture is a cubemap. </constant> <constant name="TEXTURE_FLAG_USED_FOR_STREAMING" value="4096" enum="TextureFlags"> + Texture is a video surface. </constant> <constant name="TEXTURE_FLAGS_DEFAULT" value="7" enum="TextureFlags"> + Default flags. Generate mipmaps, repeat, and filter are enabled. </constant> <constant name="SHADER_SPATIAL" value="0" enum="ShaderMode"> + Shader is a 3D shader. </constant> <constant name="SHADER_CANVAS_ITEM" value="1" enum="ShaderMode"> + Shader is a 2D shader. </constant> <constant name="SHADER_PARTICLES" value="2" enum="ShaderMode"> + Shader is a particle shader. </constant> <constant name="SHADER_MAX" value="3" enum="ShaderMode"> + Marks maximum of the shader types array. used internally. </constant> <constant name="ARRAY_VERTEX" value="0" enum="ArrayType"> + Array is a vertex array. </constant> <constant name="ARRAY_NORMAL" value="1" enum="ArrayType"> + Array is a normal array. </constant> <constant name="ARRAY_TANGENT" value="2" enum="ArrayType"> + Array is a tangent array. </constant> <constant name="ARRAY_COLOR" value="3" enum="ArrayType"> + Array is a color array. </constant> <constant name="ARRAY_TEX_UV" value="4" enum="ArrayType"> + Array is a uv coordinates array. </constant> <constant name="ARRAY_TEX_UV2" value="5" enum="ArrayType"> + Array is a uv coordinates array for the second uv coordinates. </constant> <constant name="ARRAY_BONES" value="6" enum="ArrayType"> + Array contains bone information. </constant> <constant name="ARRAY_WEIGHTS" value="7" enum="ArrayType"> + Array is weight information. </constant> <constant name="ARRAY_INDEX" value="8" enum="ArrayType"> + Array is index array. </constant> <constant name="ARRAY_MAX" value="9" enum="ArrayType"> + Marks the maximum of the array types. Used internally. </constant> <constant name="ARRAY_FORMAT_VERTEX" value="1" enum="ArrayFormat"> + Flag used to mark a vertex array. </constant> <constant name="ARRAY_FORMAT_NORMAL" value="2" enum="ArrayFormat"> + Flag used to mark a normal array. </constant> <constant name="ARRAY_FORMAT_TANGENT" value="4" enum="ArrayFormat"> + Flag used to mark a tangent array. </constant> <constant name="ARRAY_FORMAT_COLOR" value="8" enum="ArrayFormat"> + Flag used to mark a color array. </constant> <constant name="ARRAY_FORMAT_TEX_UV" value="16" enum="ArrayFormat"> + Flag used to mark a uv coordinates array. </constant> <constant name="ARRAY_FORMAT_TEX_UV2" value="32" enum="ArrayFormat"> + Flag used to mark a uv coordinates array for the second uv coordinates. </constant> <constant name="ARRAY_FORMAT_BONES" value="64" enum="ArrayFormat"> + Flag used to mark a bone information array. </constant> <constant name="ARRAY_FORMAT_WEIGHTS" value="128" enum="ArrayFormat"> + Flag used to mark a weights array. </constant> <constant name="ARRAY_FORMAT_INDEX" value="256" enum="ArrayFormat"> + Flag used to mark a index array. </constant> <constant name="ARRAY_COMPRESS_VERTEX" value="512" enum="ArrayFormat"> + Flag used to mark a compressed (half float) vertex array. </constant> <constant name="ARRAY_COMPRESS_NORMAL" value="1024" enum="ArrayFormat"> + Flag used to mark a compressed (half float) normal array. </constant> <constant name="ARRAY_COMPRESS_TANGENT" value="2048" enum="ArrayFormat"> + Flag used to mark a compressed (half float) tangent array. </constant> <constant name="ARRAY_COMPRESS_COLOR" value="4096" enum="ArrayFormat"> + Flag used to mark a compressed (half float) color array. </constant> <constant name="ARRAY_COMPRESS_TEX_UV" value="8192" enum="ArrayFormat"> + Flag used to mark a compressed (half float) uv coordinates array. </constant> <constant name="ARRAY_COMPRESS_TEX_UV2" value="16384" enum="ArrayFormat"> + Flag used to mark a compressed (half float) uv coordinates array for the second uv coordinates. </constant> <constant name="ARRAY_COMPRESS_BONES" value="32768" enum="ArrayFormat"> </constant> <constant name="ARRAY_COMPRESS_WEIGHTS" value="65536" enum="ArrayFormat"> + Flag used to mark a compressed (half float) weight array. </constant> <constant name="ARRAY_COMPRESS_INDEX" value="131072" enum="ArrayFormat"> </constant> <constant name="ARRAY_FLAG_USE_2D_VERTICES" value="262144" enum="ArrayFormat"> + Flag used to mark that the array contains 2D vertices. </constant> <constant name="ARRAY_FLAG_USE_16_BIT_BONES" value="524288" enum="ArrayFormat"> + Flag used to mark that the array uses 16 bit bones instead of 8 bit. </constant> <constant name="ARRAY_COMPRESS_DEFAULT" value="97792" enum="ArrayFormat"> + Used to set flags ARRAY_COMPRESS_VERTEX, ARRAY_COMPRESS_NORMAL, ARRAY_COMPRESS_TANGENT, ARRAY_COMPRESS_COLOR, ARRAY_COMPRESS_TEX_UV, ARRAY_COMPRESS_TEX_UV2 and ARRAY_COMPRESS_WEIGHTS quickly. </constant> <constant name="PRIMITIVE_POINTS" value="0" enum="PrimitiveType"> + Primitive to draw consists of points. </constant> <constant name="PRIMITIVE_LINES" value="1" enum="PrimitiveType"> + Primitive to draw consists of lines. </constant> <constant name="PRIMITIVE_LINE_STRIP" value="2" enum="PrimitiveType"> + Primitive to draw consists of a line strip from start to end. </constant> <constant name="PRIMITIVE_LINE_LOOP" value="3" enum="PrimitiveType"> + Primitive to draw consists of a line loop (a line strip with a line between the last and the first vertex). </constant> <constant name="PRIMITIVE_TRIANGLES" value="4" enum="PrimitiveType"> + Primitive to draw consists of triangles. </constant> <constant name="PRIMITIVE_TRIANGLE_STRIP" value="5" enum="PrimitiveType"> + Primitive to draw consists of a triangle strip (the last 3 verticies are always combined to make a triangle). </constant> <constant name="PRIMITIVE_TRIANGLE_FAN" value="6" enum="PrimitiveType"> + Primitive to draw consists of a triangle strip (the last 2 verticies are always combined with the first to make a triangle). </constant> <constant name="PRIMITIVE_MAX" value="7" enum="PrimitiveType"> + Marks the primitive types endpoint. used internally. </constant> <constant name="BLEND_SHAPE_MODE_NORMALIZED" value="0" enum="BlendShapeMode"> </constant> <constant name="BLEND_SHAPE_MODE_RELATIVE" value="1" enum="BlendShapeMode"> </constant> <constant name="LIGHT_DIRECTIONAL" value="0" enum="LightType"> + Is a directional (sun) light. </constant> <constant name="LIGHT_OMNI" value="1" enum="LightType"> + is an omni light. </constant> <constant name="LIGHT_SPOT" value="2" enum="LightType"> + is an spot light. </constant> <constant name="LIGHT_PARAM_ENERGY" value="0" enum="LightParam"> + The light's energy. </constant> <constant name="LIGHT_PARAM_SPECULAR" value="2" enum="LightParam"> + The light's influence on specularity. </constant> <constant name="LIGHT_PARAM_RANGE" value="3" enum="LightParam"> + The light's range. </constant> <constant name="LIGHT_PARAM_ATTENUATION" value="4" enum="LightParam"> + The light's attenuation. </constant> <constant name="LIGHT_PARAM_SPOT_ANGLE" value="5" enum="LightParam"> + The spotlight's angle. </constant> <constant name="LIGHT_PARAM_SPOT_ATTENUATION" value="6" enum="LightParam"> + The spotlight's attenuation. </constant> <constant name="LIGHT_PARAM_CONTACT_SHADOW_SIZE" value="7" enum="LightParam"> + Scales the shadow color. </constant> <constant name="LIGHT_PARAM_SHADOW_MAX_DISTANCE" value="8" enum="LightParam"> </constant> @@ -1973,6 +2212,7 @@ <constant name="LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE" value="14" enum="LightParam"> </constant> <constant name="LIGHT_PARAM_MAX" value="15" enum="LightParam"> + The light parameters endpoint. Used internally. </constant> <constant name="VIEWPORT_UPDATE_DISABLED" value="0" enum="ViewportUpdateMode"> </constant> @@ -1983,28 +2223,40 @@ <constant name="VIEWPORT_UPDATE_ALWAYS" value="3" enum="ViewportUpdateMode"> </constant> <constant name="VIEWPORT_CLEAR_ALWAYS" value="0" enum="ViewportClearMode"> + The viewport is always cleared before drawing. </constant> <constant name="VIEWPORT_CLEAR_NEVER" value="1" enum="ViewportClearMode"> + The viewport is never cleared before drawing. </constant> <constant name="VIEWPORT_CLEAR_ONLY_NEXT_FRAME" value="2" enum="ViewportClearMode"> + The viewport is cleared once, then the clear mode is set to [VIEWPORT_CLEAR_NEVER]. </constant> <constant name="VIEWPORT_MSAA_DISABLED" value="0" enum="ViewportMSAA"> + Multisample antialiasing is disabled. </constant> <constant name="VIEWPORT_MSAA_2X" value="1" enum="ViewportMSAA"> + Multisample antialiasing is set to 2X. </constant> <constant name="VIEWPORT_MSAA_4X" value="2" enum="ViewportMSAA"> + Multisample antialiasing is set to 4X. </constant> <constant name="VIEWPORT_MSAA_8X" value="3" enum="ViewportMSAA"> + Multisample antialiasing is set to 8X. </constant> <constant name="VIEWPORT_MSAA_16X" value="4" enum="ViewportMSAA"> + Multisample antialiasing is set to 16X. </constant> <constant name="VIEWPORT_USAGE_2D" value="0" enum="ViewportUsage"> + The Viewport does not render 3D but samples. </constant> <constant name="VIEWPORT_USAGE_2D_NO_SAMPLING" value="1" enum="ViewportUsage"> + The Viewport does not render 3D and does not sample. </constant> <constant name="VIEWPORT_USAGE_3D" value="2" enum="ViewportUsage"> + The Viewport renders 3D with effects. </constant> <constant name="VIEWPORT_USAGE_3D_NO_EFFECTS" value="3" enum="ViewportUsage"> + The Viewport renders 3D but without effects. </constant> <constant name="VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME" value="0" enum="ViewportRenderInfo"> </constant> @@ -2019,14 +2271,19 @@ <constant name="VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME" value="5" enum="ViewportRenderInfo"> </constant> <constant name="VIEWPORT_RENDER_INFO_MAX" value="6" enum="ViewportRenderInfo"> + Marks end of VIEWPORT_RENDER_INFO* constants. Used internally. </constant> <constant name="VIEWPORT_DEBUG_DRAW_DISABLED" value="0" enum="ViewportDebugDraw"> + Debug draw is disabled. Default setting. </constant> <constant name="VIEWPORT_DEBUG_DRAW_UNSHADED" value="1" enum="ViewportDebugDraw"> + Debug draw sets objects to unshaded. </constant> <constant name="VIEWPORT_DEBUG_DRAW_OVERDRAW" value="2" enum="ViewportDebugDraw"> + Overwrites clear color to [code](0,0,0,0)[/code]. </constant> <constant name="VIEWPORT_DEBUG_DRAW_WIREFRAME" value="3" enum="ViewportDebugDraw"> + Debug draw draws objects in wireframe. </constant> <constant name="SCENARIO_DEBUG_DISABLED" value="0" enum="ScenarioDebugMode"> </constant> @@ -2037,38 +2294,53 @@ <constant name="SCENARIO_DEBUG_SHADELESS" value="3" enum="ScenarioDebugMode"> </constant> <constant name="INSTANCE_NONE" value="0" enum="InstanceType"> + The instance does not have a type. </constant> <constant name="INSTANCE_MESH" value="1" enum="InstanceType"> + The instance is a mesh. </constant> <constant name="INSTANCE_MULTIMESH" value="2" enum="InstanceType"> + The instance is a multimesh. </constant> <constant name="INSTANCE_IMMEDIATE" value="3" enum="InstanceType"> + The instance is an immediate geometry. </constant> <constant name="INSTANCE_PARTICLES" value="4" enum="InstanceType"> + The instance is a particle emitter. </constant> <constant name="INSTANCE_LIGHT" value="5" enum="InstanceType"> + The instance is a light. </constant> <constant name="INSTANCE_REFLECTION_PROBE" value="6" enum="InstanceType"> </constant> <constant name="INSTANCE_GI_PROBE" value="7" enum="InstanceType"> </constant> <constant name="INSTANCE_MAX" value="8" enum="InstanceType"> + The max value for INSTANCE_* constants, used internally. </constant> <constant name="INSTANCE_GEOMETRY_MASK" value="30" enum="InstanceType"> + A combination of the flags of geometry instances (mesh, multimesh, immediate and particles). </constant> <constant name="NINE_PATCH_STRETCH" value="0" enum="NinePatchAxisMode"> + The nine patch gets stretched where needed. </constant> <constant name="NINE_PATCH_TILE" value="1" enum="NinePatchAxisMode"> + The nine patch gets filled with tiles where needed. </constant> <constant name="NINE_PATCH_TILE_FIT" value="2" enum="NinePatchAxisMode"> + The nine patch gets filled with tiles where needed and stretches them a bit if needed. </constant> <constant name="CANVAS_LIGHT_MODE_ADD" value="0" enum="CanvasLightMode"> + Adds light color additive to the canvas. </constant> <constant name="CANVAS_LIGHT_MODE_SUB" value="1" enum="CanvasLightMode"> + Adds light color subtractive to the canvas. </constant> <constant name="CANVAS_LIGHT_MODE_MIX" value="2" enum="CanvasLightMode"> + The light adds color depending on transparency. </constant> <constant name="CANVAS_LIGHT_MODE_MASK" value="3" enum="CanvasLightMode"> + The light adds color depending on mask. </constant> <constant name="CANVAS_LIGHT_FILTER_NONE" value="0" enum="CanvasLightShadowFilter"> </constant> @@ -2083,34 +2355,46 @@ <constant name="CANVAS_LIGHT_FILTER_PCF13" value="5" enum="CanvasLightShadowFilter"> </constant> <constant name="CANVAS_OCCLUDER_POLYGON_CULL_DISABLED" value="0" enum="CanvasOccluderPolygonCullMode"> + Culling of the canvas occluder is disabled. </constant> <constant name="CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE" value="1" enum="CanvasOccluderPolygonCullMode"> + Culling of the canvas occluder is clockwise. </constant> <constant name="CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE" value="2" enum="CanvasOccluderPolygonCullMode"> + Culling of the canvas occluder is counterclockwise. </constant> <constant name="INFO_OBJECTS_IN_FRAME" value="0" enum="RenderInfo"> + The amount of objects in the frame. </constant> <constant name="INFO_VERTICES_IN_FRAME" value="1" enum="RenderInfo"> + The amount of vertices in the frame. </constant> <constant name="INFO_MATERIAL_CHANGES_IN_FRAME" value="2" enum="RenderInfo"> + The amount of modified materials in the frame. </constant> <constant name="INFO_SHADER_CHANGES_IN_FRAME" value="3" enum="RenderInfo"> + The amount of shader rebinds in the frame. </constant> <constant name="INFO_SURFACE_CHANGES_IN_FRAME" value="4" enum="RenderInfo"> + The amount of surface changes in the frame. </constant> <constant name="INFO_DRAW_CALLS_IN_FRAME" value="5" enum="RenderInfo"> + The amount of draw calls in frame. </constant> <constant name="INFO_USAGE_VIDEO_MEM_TOTAL" value="6" enum="RenderInfo"> </constant> <constant name="INFO_VIDEO_MEM_USED" value="7" enum="RenderInfo"> + The amount of vertex memory and texture memory used. </constant> <constant name="INFO_TEXTURE_MEM_USED" value="8" enum="RenderInfo"> + The amount of texture memory used. </constant> <constant name="INFO_VERTEX_MEM_USED" value="9" enum="RenderInfo"> + The amount of vertex memory used. </constant> <constant name="FEATURE_SHADERS" value="0" enum="Features"> </constant> <constant name="FEATURE_MULTITHREADED" value="1" enum="Features"> </constant> </constants> -</class> +</class>
\ No newline at end of file diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 0839f930c9..309497c938 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -527,7 +527,9 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur _draw_generic(GL_TRIANGLE_STRIP, pline->triangles.size(), pline->triangles.ptr(), NULL, pline->triangle_colors.ptr(), pline->triangle_colors.size() == 1); #ifdef GLES_OVER_GL glEnable(GL_LINE_SMOOTH); - if (pline->lines.size()) { + if (pline->multiline) { + //needs to be different + } else { _draw_generic(GL_LINE_LOOP, pline->lines.size(), pline->lines.ptr(), NULL, pline->line_colors.ptr(), pline->line_colors.size() == 1); } glDisable(GL_LINE_SMOOTH); @@ -538,7 +540,23 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur if (pline->antialiased) glEnable(GL_LINE_SMOOTH); #endif - _draw_generic(GL_LINE_STRIP, pline->lines.size(), pline->lines.ptr(), NULL, pline->line_colors.ptr(), pline->line_colors.size() == 1); + + if (pline->multiline) { + int todo = pline->lines.size() / 2; + int max_per_call = data.polygon_buffer_size / (sizeof(real_t) * 4); + int offset = 0; + + while (todo) { + int to_draw = MIN(max_per_call, todo); + _draw_generic(GL_LINES, to_draw * 2, &pline->lines.ptr()[offset], NULL, pline->line_colors.size() == 1 ? pline->line_colors.ptr() : &pline->line_colors.ptr()[offset], pline->line_colors.size() == 1); + todo -= to_draw; + offset += to_draw * 2; + } + + } else { + + _draw_generic(GL_LINES, pline->lines.size(), pline->lines.ptr(), NULL, pline->line_colors.ptr(), pline->line_colors.size() == 1); + } #ifdef GLES_OVER_GL if (pline->antialiased) @@ -1705,6 +1723,7 @@ void RasterizerCanvasGLES3::initialize() { glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); glBufferData(GL_ARRAY_BUFFER, poly_size, NULL, GL_DYNAMIC_DRAW); //allocate max size glBindBuffer(GL_ARRAY_BUFFER, 0); + data.polygon_buffer_size = poly_size; //quad arrays for (int i = 0; i < 4; i++) { diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index 325df8e4f1..05381da9b9 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -81,6 +81,16 @@ static int _get_datatype_size(SL::DataType p_type) { ERR_FAIL_V(0); } +static String _interpstr(SL::DataInterpolation p_interp) { + + switch (p_interp) { + case SL::INTERPOLATION_FLAT: return "flat "; + case SL::INTERPOLATION_NO_PERSPECTIVE: return "noperspective "; + case SL::INTERPOLATION_SMOOTH: return "smooth "; + } + return ""; +} + static String _prestr(SL::DataPrecision p_pres) { switch (p_pres) { @@ -383,12 +393,13 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener for (Map<StringName, SL::ShaderNode::Varying>::Element *E = pnode->varyings.front(); E; E = E->next()) { String vcode; + String interp_mode = _interpstr(E->get().interpolation); vcode += _prestr(E->get().precission); vcode += _typestr(E->get().type); vcode += " " + _mkid(E->key()); vcode += ";\n"; - r_gen_code.vertex_global += "out " + vcode; - r_gen_code.fragment_global += "in " + vcode; + r_gen_code.vertex_global += interp_mode + "out " + vcode; + r_gen_code.fragment_global += interp_mode + "in " + vcode; } Map<StringName, String> function_code; diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index a39e4d6efb..5c4c2b694f 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -565,12 +565,12 @@ void EditorPlugin::save_global_state() {} void EditorPlugin::add_import_plugin(const Ref<EditorImportPlugin> &p_importer) { ResourceFormatImporter::get_singleton()->add_importer(p_importer); - EditorFileSystem::get_singleton()->scan(); + EditorFileSystem::get_singleton()->call_deferred("scan"); } void EditorPlugin::remove_import_plugin(const Ref<EditorImportPlugin> &p_importer) { ResourceFormatImporter::get_singleton()->remove_importer(p_importer); - EditorFileSystem::get_singleton()->scan(); + EditorFileSystem::get_singleton()->call_deferred("scan"); } void EditorPlugin::add_export_plugin(const Ref<EditorExportPlugin> &p_exporter) { @@ -587,7 +587,6 @@ void EditorPlugin::add_scene_import_plugin(const Ref<EditorSceneImporter> &p_imp void EditorPlugin::remove_scene_import_plugin(const Ref<EditorSceneImporter> &p_importer) { ResourceImporterScene::get_singleton()->remove_importer(p_importer); - } void EditorPlugin::set_window_layout(Ref<ConfigFile> p_layout) { diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 4ef8ec48a0..08d2897250 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -47,8 +47,6 @@ #include "scene/resources/ray_shape.h" #include "scene/resources/sphere_shape.h" - - uint32_t EditorSceneImporter::get_import_flags() const { if (get_script_instance()) { @@ -60,80 +58,73 @@ uint32_t EditorSceneImporter::get_import_flags() const { void EditorSceneImporter::get_extensions(List<String> *r_extensions) const { if (get_script_instance()) { - Array arr= get_script_instance()->call("_get_extensions"); - for(int i=0;i<arr.size();i++) { + Array arr = get_script_instance()->call("_get_extensions"); + for (int i = 0; i < arr.size(); i++) { r_extensions->push_back(arr[i]); } return; } ERR_FAIL(); - } Node *EditorSceneImporter::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) { if (get_script_instance()) { - return get_script_instance()->call("_import_scene",p_path,p_flags,p_bake_fps); + return get_script_instance()->call("_import_scene", p_path, p_flags, p_bake_fps); } ERR_FAIL_V(NULL); - } -Ref<Animation> EditorSceneImporter::import_animation(const String &p_path, uint32_t p_flags,int p_bake_fps) { +Ref<Animation> EditorSceneImporter::import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) { if (get_script_instance()) { - return get_script_instance()->call("_import_animation",p_path,p_flags); + return get_script_instance()->call("_import_animation", p_path, p_flags); } ERR_FAIL_V(NULL); - } //for documenters, these functions are useful when an importer calls an external conversion helper (like, fbx2gltf), //and you want to load the resulting file -Node* EditorSceneImporter::import_scene_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps) { - - return ResourceImporterScene::get_singleton()->import_scene_from_other_importer(this,p_path,p_flags,p_bake_fps); +Node *EditorSceneImporter::import_scene_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps) { + return ResourceImporterScene::get_singleton()->import_scene_from_other_importer(this, p_path, p_flags, p_bake_fps); } Ref<Animation> EditorSceneImporter::import_animation_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps) { - return ResourceImporterScene::get_singleton()->import_animation_from_other_importer(this,p_path,p_flags,p_bake_fps); - + return ResourceImporterScene::get_singleton()->import_animation_from_other_importer(this, p_path, p_flags, p_bake_fps); } void EditorSceneImporter::_bind_methods() { - ClassDB::bind_method(D_METHOD("import_scene_from_other_importer","path","flags","bake_fps"),&EditorSceneImporter::import_scene_from_other_importer); - ClassDB::bind_method(D_METHOD("import_animation_from_other_importer","path","flags","bake_fps"),&EditorSceneImporter::import_animation_from_other_importer); + ClassDB::bind_method(D_METHOD("import_scene_from_other_importer", "path", "flags", "bake_fps"), &EditorSceneImporter::import_scene_from_other_importer); + ClassDB::bind_method(D_METHOD("import_animation_from_other_importer", "path", "flags", "bake_fps"), &EditorSceneImporter::import_animation_from_other_importer); BIND_VMETHOD(MethodInfo(Variant::INT, "_get_import_flags")); BIND_VMETHOD(MethodInfo(Variant::ARRAY, "_get_extensions")); - MethodInfo mi = MethodInfo(Variant::OBJECT, "_import_scene",PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::INT, "flags"), PropertyInfo(Variant::INT, "bake_fps")); - mi.return_val.class_name="Node"; + MethodInfo mi = MethodInfo(Variant::OBJECT, "_import_scene", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::INT, "flags"), PropertyInfo(Variant::INT, "bake_fps")); + mi.return_val.class_name = "Node"; BIND_VMETHOD(mi); - mi = MethodInfo(Variant::OBJECT, "_import_animation",PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::INT, "flags"), PropertyInfo(Variant::INT, "bake_fps")); - mi.return_val.class_name="Animation"; + mi = MethodInfo(Variant::OBJECT, "_import_animation", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::INT, "flags"), PropertyInfo(Variant::INT, "bake_fps")); + mi.return_val.class_name = "Animation"; BIND_VMETHOD(mi); - BIND_CONSTANT( IMPORT_SCENE ); - BIND_CONSTANT( IMPORT_ANIMATION ); - BIND_CONSTANT( IMPORT_ANIMATION_DETECT_LOOP ); - BIND_CONSTANT( IMPORT_ANIMATION_OPTIMIZE ); - BIND_CONSTANT( IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS ); - BIND_CONSTANT( IMPORT_ANIMATION_KEEP_VALUE_TRACKS ); - BIND_CONSTANT( IMPORT_GENERATE_TANGENT_ARRAYS ); - BIND_CONSTANT( IMPORT_FAIL_ON_MISSING_DEPENDENCIES ); - BIND_CONSTANT( IMPORT_MATERIALS_IN_INSTANCES ); - BIND_CONSTANT( IMPORT_USE_COMPRESSION ); - + BIND_CONSTANT(IMPORT_SCENE); + BIND_CONSTANT(IMPORT_ANIMATION); + BIND_CONSTANT(IMPORT_ANIMATION_DETECT_LOOP); + BIND_CONSTANT(IMPORT_ANIMATION_OPTIMIZE); + BIND_CONSTANT(IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS); + BIND_CONSTANT(IMPORT_ANIMATION_KEEP_VALUE_TRACKS); + BIND_CONSTANT(IMPORT_GENERATE_TANGENT_ARRAYS); + BIND_CONSTANT(IMPORT_FAIL_ON_MISSING_DEPENDENCIES); + BIND_CONSTANT(IMPORT_MATERIALS_IN_INSTANCES); + BIND_CONSTANT(IMPORT_USE_COMPRESSION); } - ///////////////////////////////// void EditorScenePostImport::_bind_methods() { @@ -201,6 +192,10 @@ bool ResourceImporterScene::get_option_visibility(const String &p_option, const return false; } + if (p_option == "meshes/lightmap_texel_size" && int(p_options["meshes/light_baking"]) < 2) { + return false; + } + return true; } @@ -961,6 +956,36 @@ static String _make_extname(const String &p_str) { return ext_name; } +void ResourceImporterScene::_find_meshes(Node *p_node, Map<Ref<ArrayMesh>, Transform> &meshes) { + + List<PropertyInfo> pi; + p_node->get_property_list(&pi); + + MeshInstance *mi = Object::cast_to<MeshInstance>(p_node); + + if (mi) { + + Ref<ArrayMesh> mesh = mi->get_mesh(); + + if (mesh.is_valid() && !meshes.has(mesh)) { + Spatial *s = mi; + while (s->get_parent_spatial()) { + s = s->get_parent_spatial(); + } + + if (s == mi) { + meshes[mesh] = s->get_transform(); + } else { + meshes[mesh] = s->get_transform() * mi->get_relative_transform(s); + } + } + } + for (int i = 0; i < p_node->get_child_count(); i++) { + + _find_meshes(p_node->get_child(i), meshes); + } +} + void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_keep_animations, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Animation>, Ref<Animation> > &p_animations, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes) { List<PropertyInfo> pi; @@ -1140,7 +1165,8 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/compress"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/ensure_tangents"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/storage", PROPERTY_HINT_ENUM, "Built-In,Files"), meshes_out ? 1 : 0)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/light_baking", PROPERTY_HINT_ENUM, "Disabled,Enable"), 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/light_baking", PROPERTY_HINT_ENUM, "Disabled,Enable,Gen Lightmaps"), 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "meshes/lightmap_texel_size", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 0.05)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "external_files/store_in_subdir"), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 15)); @@ -1171,17 +1197,16 @@ void ResourceImporterScene::_replace_owner(Node *p_node, Node *p_scene, Node *p_ Node *n = p_node->get_child(i); _replace_owner(n, p_scene, p_new_owner); } - } -Node* ResourceImporterScene::import_scene_from_other_importer(EditorSceneImporter *p_exception,const String &p_path, uint32_t p_flags, int p_bake_fps) { +Node *ResourceImporterScene::import_scene_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps) { Ref<EditorSceneImporter> importer; String ext = p_path.get_extension().to_lower(); for (Set<Ref<EditorSceneImporter> >::Element *E = importers.front(); E; E = E->next()) { - if (E->get().ptr()==p_exception) + if (E->get().ptr() == p_exception) continue; List<String> extensions; E->get()->get_extensions(&extensions); @@ -1199,42 +1224,41 @@ Node* ResourceImporterScene::import_scene_from_other_importer(EditorSceneImporte break; } - ERR_FAIL_COND_V(!importer.is_valid(),NULL); + ERR_FAIL_COND_V(!importer.is_valid(), NULL); List<String> missing; Error err; - return importer->import_scene(p_path,p_flags,p_bake_fps,&missing,&err); + return importer->import_scene(p_path, p_flags, p_bake_fps, &missing, &err); } -Ref<Animation> ResourceImporterScene::import_animation_from_other_importer(EditorSceneImporter *p_exception,const String &p_path, uint32_t p_flags, int p_bake_fps) { - +Ref<Animation> ResourceImporterScene::import_animation_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps) { - Ref<EditorSceneImporter> importer; - String ext = p_path.get_extension().to_lower(); + Ref<EditorSceneImporter> importer; + String ext = p_path.get_extension().to_lower(); - for (Set<Ref<EditorSceneImporter> >::Element *E = importers.front(); E; E = E->next()) { + for (Set<Ref<EditorSceneImporter> >::Element *E = importers.front(); E; E = E->next()) { - if (E->get().ptr()==p_exception) - continue; - List<String> extensions; - E->get()->get_extensions(&extensions); + if (E->get().ptr() == p_exception) + continue; + List<String> extensions; + E->get()->get_extensions(&extensions); - for (List<String>::Element *F = extensions.front(); F; F = F->next()) { + for (List<String>::Element *F = extensions.front(); F; F = F->next()) { - if (F->get().to_lower() == ext) { + if (F->get().to_lower() == ext) { - importer = E->get(); - break; - } - } + importer = E->get(); + break; + } + } - if (importer.is_valid()) - break; - } + if (importer.is_valid()) + break; + } - ERR_FAIL_COND_V(!importer.is_valid(),NULL); + ERR_FAIL_COND_V(!importer.is_valid(), NULL); - return importer->import_animation(p_path,p_flags,p_bake_fps); + return importer->import_animation(p_path, p_flags, p_bake_fps); } Error ResourceImporterScene::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { @@ -1371,6 +1395,37 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p } } + if (light_bake_mode == 2 /* || generate LOD */) { + + Map<Ref<ArrayMesh>, Transform> meshes; + _find_meshes(scene, meshes); + + if (light_bake_mode == 2) { + + float texel_size = p_options["meshes/lightmap_texel_size"]; + texel_size = MAX(0.001, texel_size); + + EditorProgress progress("gen_lightmaps", TTR("Generating Lightmaps"), meshes.size()); + int step = 0; + for (Map<Ref<ArrayMesh>, Transform>::Element *E = meshes.front(); E; E = E->next()) { + + Ref<ArrayMesh> mesh = E->key(); + String name = mesh->get_name(); + if (name == "") { //should not happen but.. + name = "Mesh " + itos(step); + } + + progress.step(TTR("Generating for Mesh: ") + name + " (" + itos(step) + "/" + itos(meshes.size()) + ")", step); + + Error err = mesh->lightmap_unwrap(E->get(), texel_size); + if (err != OK) { + EditorNode::add_io_error("Mesh '" + name + "' failed lightmap generation. Please fix geometry."); + } + step++; + } + } + } + if (external_animations || external_materials || external_meshes) { Map<Ref<Animation>, Ref<Animation> > anim_map; Map<Ref<Material>, Ref<Material> > mat_map; diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index fc6ce05fa4..933585a48c 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -40,13 +40,13 @@ class Material; class EditorSceneImporter : public Reference { GDCLASS(EditorSceneImporter, Reference); -protected: +protected: static void _bind_methods(); - - Node* import_scene_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps); + Node *import_scene_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps); Ref<Animation> import_animation_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps); + public: enum ImportFlags { IMPORT_SCENE = 1, @@ -62,11 +62,10 @@ public: }; - virtual uint32_t get_import_flags() const; virtual void get_extensions(List<String> *r_extensions) const; virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = NULL); - virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags,int p_bake_fps); + virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps); EditorSceneImporter() {} }; @@ -136,6 +135,8 @@ public: virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; virtual int get_import_order() const { return 100; } //after everything + void _find_meshes(Node *p_node, Map<Ref<ArrayMesh>, Transform> &meshes); + void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_keep_animations, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Animation>, Ref<Animation> > &p_animations, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes); Node *_fix_node(Node *p_node, Node *p_root, Map<Ref<ArrayMesh>, Ref<Shape> > &collision_map, LightBakeMode p_light_bake_mode); @@ -147,8 +148,8 @@ public: virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL); - Node* import_scene_from_other_importer(EditorSceneImporter *p_exception,const String &p_path, uint32_t p_flags, int p_bake_fps); - Ref<Animation> import_animation_from_other_importer(EditorSceneImporter *p_exception,const String &p_path, uint32_t p_flags, int p_bake_fps); + Node *import_scene_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps); + Ref<Animation> import_animation_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps); ResourceImporterScene(); }; diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 213f293bea..e63bc3ad9f 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -4342,6 +4342,9 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { drag = DRAG_NONE; bone_last_frame = 0; additive_selection = false; + + // Update the menus checkboxes + set_state(get_state()); } CanvasItemEditor *CanvasItemEditor::singleton = NULL; diff --git a/editor/plugins/mesh_instance_editor_plugin.cpp b/editor/plugins/mesh_instance_editor_plugin.cpp index 84fc0cecf2..9d116349c0 100644 --- a/editor/plugins/mesh_instance_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_editor_plugin.cpp @@ -195,7 +195,139 @@ void MeshInstanceEditor::_menu_option(int p_option) { outline_dialog->popup_centered(Vector2(200, 90)); } break; + case MENU_OPTION_CREATE_UV2: { + + Ref<ArrayMesh> mesh = node->get_mesh(); + if (!mesh.is_valid()) { + err_dialog->set_text(TTR("Contained Mesh is not of type ArrayMesh.")); + err_dialog->popup_centered_minsize(); + return; + } + + Error err = mesh->lightmap_unwrap(node->get_global_transform()); + if (err != OK) { + err_dialog->set_text(TTR("UV Unwrap failed, mesh may not be manifold?")); + err_dialog->popup_centered_minsize(); + return; + } + + } break; + case MENU_OPTION_DEBUG_UV1: { + Ref<Mesh> mesh = node->get_mesh(); + if (!mesh.is_valid()) { + err_dialog->set_text(TTR("No mesh to debug.")); + err_dialog->popup_centered_minsize(); + return; + } + _create_uv_lines(0); + } break; + case MENU_OPTION_DEBUG_UV2: { + Ref<Mesh> mesh = node->get_mesh(); + if (!mesh.is_valid()) { + err_dialog->set_text(TTR("No mesh to debug.")); + err_dialog->popup_centered_minsize(); + return; + } + _create_uv_lines(1); + } break; + } +} + +struct MeshInstanceEditorEdgeSort { + + Vector2 a; + Vector2 b; + + bool operator<(const MeshInstanceEditorEdgeSort &p_b) const { + if (a == p_b.a) + return b < p_b.b; + else + return a < p_b.a; + } + + MeshInstanceEditorEdgeSort() {} + MeshInstanceEditorEdgeSort(const Vector2 &p_a, const Vector2 &p_b) { + if (p_a < p_b) { + a = p_a; + b = p_b; + } else { + b = p_a; + a = p_b; + } + } +}; + +void MeshInstanceEditor::_create_uv_lines(int p_layer) { + + Ref<Mesh> mesh = node->get_mesh(); + ERR_FAIL_COND(!mesh.is_valid()); + + Set<MeshInstanceEditorEdgeSort> edges; + uv_lines.clear(); + for (int i = 0; i < mesh->get_surface_count(); i++) { + if (mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) + continue; + Array a = mesh->surface_get_arrays(i); + + PoolVector<Vector2> uv = a[p_layer == 0 ? Mesh::ARRAY_TEX_UV : Mesh::ARRAY_TEX_UV2]; + if (uv.size() == 0) { + err_dialog->set_text(TTR("Model has no UV in this layer")); + err_dialog->popup_centered_minsize(); + return; + } + + PoolVector<Vector2>::Read r = uv.read(); + + PoolVector<int> indices = a[Mesh::ARRAY_INDEX]; + PoolVector<int>::Read ri; + + int ic; + bool use_indices; + + if (indices.size()) { + ic = indices.size(); + ri = indices.read(); + use_indices = true; + } else { + ic = uv.size(); + use_indices = false; + } + + for (int j = 0; j < ic; j += 3) { + + for (int k = 0; k < 3; k++) { + + MeshInstanceEditorEdgeSort edge; + if (use_indices) { + edge.a = r[ri[j + k]]; + edge.b = r[ri[j + ((k + 1) % 3)]]; + } else { + edge.a = r[j + k]; + edge.b = r[j + ((k + 1) % 3)]; + } + + if (edges.has(edge)) + continue; + + uv_lines.push_back(edge.a); + uv_lines.push_back(edge.b); + edges.insert(edge); + } + } } + + debug_uv_dialog->popup_centered_minsize(); +} + +void MeshInstanceEditor::_debug_uv_draw() { + + if (uv_lines.size() == 0) + return; + + debug_uv->set_clip_contents(true); + debug_uv->draw_rect(Rect2(Vector2(), debug_uv->get_size()), Color(0.2, 0.2, 0.0)); + debug_uv->draw_set_transform(Vector2(), 0, debug_uv->get_size()); + debug_uv->draw_multiline(uv_lines, Color(1.0, 0.8, 0.7)); } void MeshInstanceEditor::_create_outline_mesh() { @@ -244,6 +376,7 @@ void MeshInstanceEditor::_bind_methods() { ClassDB::bind_method("_menu_option", &MeshInstanceEditor::_menu_option); ClassDB::bind_method("_create_outline_mesh", &MeshInstanceEditor::_create_outline_mesh); + ClassDB::bind_method("_debug_uv_draw", &MeshInstanceEditor::_debug_uv_draw); } MeshInstanceEditor::MeshInstanceEditor() { @@ -263,6 +396,10 @@ MeshInstanceEditor::MeshInstanceEditor() { options->get_popup()->add_item(TTR("Create Navigation Mesh"), MENU_OPTION_CREATE_NAVMESH); options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Create Outline Mesh.."), MENU_OPTION_CREATE_OUTLINE_MESH); + options->get_popup()->add_separator(); + options->get_popup()->add_item(TTR("View UV1"), MENU_OPTION_DEBUG_UV1); + options->get_popup()->add_item(TTR("View UV2"), MENU_OPTION_DEBUG_UV2); + options->get_popup()->add_item(TTR("Unwrap UV2 for Lightmap/AO"), MENU_OPTION_CREATE_UV2); options->get_popup()->connect("id_pressed", this, "_menu_option"); @@ -286,6 +423,14 @@ MeshInstanceEditor::MeshInstanceEditor() { err_dialog = memnew(AcceptDialog); add_child(err_dialog); + + debug_uv_dialog = memnew(AcceptDialog); + debug_uv_dialog->set_title("UV Channel Debug"); + add_child(debug_uv_dialog); + debug_uv = memnew(Control); + debug_uv->set_custom_minimum_size(Size2(600, 600) * EDSCALE); + debug_uv->connect("draw", this, "_debug_uv_draw"); + debug_uv_dialog->add_child(debug_uv); } void MeshInstanceEditorPlugin::edit(Object *p_object) { diff --git a/editor/plugins/mesh_instance_editor_plugin.h b/editor/plugins/mesh_instance_editor_plugin.h index fa851458ce..68c149f98a 100644 --- a/editor/plugins/mesh_instance_editor_plugin.h +++ b/editor/plugins/mesh_instance_editor_plugin.h @@ -47,6 +47,9 @@ class MeshInstanceEditor : public Node { MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE, MENU_OPTION_CREATE_NAVMESH, MENU_OPTION_CREATE_OUTLINE_MESH, + MENU_OPTION_CREATE_UV2, + MENU_OPTION_DEBUG_UV1, + MENU_OPTION_DEBUG_UV2, }; MeshInstance *node; @@ -58,11 +61,18 @@ class MeshInstanceEditor : public Node { AcceptDialog *err_dialog; + AcceptDialog *debug_uv_dialog; + Control *debug_uv; + Vector<Vector2> uv_lines; + void _menu_option(int p_option); void _create_outline_mesh(); + void _create_uv_lines(int p_layer); friend class MeshInstanceEditorPlugin; + void _debug_uv_draw(); + protected: void _node_removed(Node *p_node); static void _bind_methods(); diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index eed1efaf9c..446a0ea35d 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -430,24 +430,19 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: } else if (hint == PROPERTY_HINT_LAYERS_2D_PHYSICS || hint == PROPERTY_HINT_LAYERS_2D_RENDER || hint == PROPERTY_HINT_LAYERS_3D_PHYSICS || hint == PROPERTY_HINT_LAYERS_3D_RENDER) { - String title; String basename; switch (hint) { case PROPERTY_HINT_LAYERS_2D_RENDER: basename = "layer_names/2d_render"; - title = "2D Render Layers"; break; case PROPERTY_HINT_LAYERS_2D_PHYSICS: basename = "layer_names/2d_physics"; - title = "2D Physics Layers"; break; case PROPERTY_HINT_LAYERS_3D_RENDER: basename = "layer_names/3d_render"; - title = "3D Render Layers"; break; case PROPERTY_HINT_LAYERS_3D_PHYSICS: basename = "layer_names/3d_physics"; - title = "3D Physics Layers"; break; } @@ -469,11 +464,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: show(); - value_label[0]->set_text(title); - value_label[0]->show(); - value_label[0]->set_position(Vector2(4, 4) * EDSCALE); - - checks20gc->set_position(Vector2(4, 4) * EDSCALE + Vector2(0, value_label[0]->get_size().height + 4 * EDSCALE)); + checks20gc->set_position(Vector2(4, 4) * EDSCALE); checks20gc->set_size(checks20gc->get_minimum_size()); set_size(Vector2(4, 4) * EDSCALE + checks20gc->get_position() + checks20gc->get_size()); diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index e48b03968b..599f204184 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -3389,6 +3389,10 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { _set_error("Can't export null type."); return; } + if (type == Variant::OBJECT) { + _set_error("Can't export raw object type."); + return; + } current_export.type = type; current_export.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE; tokenizer->advance(); diff --git a/modules/thekla_unwrap/SCsub b/modules/thekla_unwrap/SCsub index 2b1349a15f..1d4b086848 100644 --- a/modules/thekla_unwrap/SCsub +++ b/modules/thekla_unwrap/SCsub @@ -47,7 +47,8 @@ if env['builtin_thekla_atlas']: "nvmesh/param/SingleFaceMap.cpp", "nvmesh/param/Util.cpp", "nvmesh/weld/VertexWeld.cpp", - "nvmesh/weld/Snap.cpp" + "nvmesh/weld/Snap.cpp", + "thekla/thekla_atlas.cpp" ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] diff --git a/modules/thekla_unwrap/register_types.cpp b/modules/thekla_unwrap/register_types.cpp index 8a9f8341e8..01b834f8cb 100644 --- a/modules/thekla_unwrap/register_types.cpp +++ b/modules/thekla_unwrap/register_types.cpp @@ -28,7 +28,88 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "register_types.h" +#include "thirdparty/thekla_atlas/thekla/thekla_atlas.h" +#include <stdio.h> +#include <stdlib.h> +extern bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, const int *p_face_materials, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y); -void register_thekla_unwrap_types() {} +bool thekla_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, const int *p_face_materials, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y) { -void unregister_thekla_unwrap_types() {} + //set up input mesh + Thekla::Atlas_Input_Mesh input_mesh; + input_mesh.face_array = new Thekla::Atlas_Input_Face[p_index_count / 3]; + for (int i = 0; i < p_index_count / 3; i++) { + input_mesh.face_array[i].vertex_index[0] = p_indices[i * 3 + 0]; + input_mesh.face_array[i].vertex_index[1] = p_indices[i * 3 + 1]; + input_mesh.face_array[i].vertex_index[2] = p_indices[i * 3 + 2]; + printf("face %i - %i, %i, %i - mat %i\n", i, input_mesh.face_array[i].vertex_index[0], input_mesh.face_array[i].vertex_index[1], input_mesh.face_array[i].vertex_index[2], p_face_materials[i]); + input_mesh.face_array[i].material_index = p_face_materials[i]; + } + input_mesh.vertex_array = new Thekla::Atlas_Input_Vertex[p_vertex_count]; + for (int i = 0; i < p_vertex_count; i++) { + input_mesh.vertex_array[i].first_colocal = i; //wtf + for (int j = 0; j < 3; j++) { + input_mesh.vertex_array[i].position[j] = p_vertices[i * 3 + j]; + input_mesh.vertex_array[i].normal[j] = p_normals[i * 3 + j]; + } + input_mesh.vertex_array[i].uv[0] = 0; + input_mesh.vertex_array[i].uv[1] = 0; + printf("vertex %i - %f, %f, %f\n", i, input_mesh.vertex_array[i].position[0], input_mesh.vertex_array[i].position[1], input_mesh.vertex_array[i].position[2]); + printf("normal %i - %f, %f, %f\n", i, input_mesh.vertex_array[i].normal[0], input_mesh.vertex_array[i].normal[1], input_mesh.vertex_array[i].normal[2]); + } + input_mesh.face_count = p_index_count / 3; + input_mesh.vertex_count = p_vertex_count; + + //set up options + Thekla::Atlas_Options options; + Thekla::atlas_set_default_options(&options); + options.packer_options.witness.packing_quality = 1; + options.packer_options.witness.texel_area = 1.0 / p_texel_size; + + //generate + Thekla::Atlas_Error err; + Thekla::Atlas_Output_Mesh *output = atlas_generate(&input_mesh, &options, &err); + + delete[] input_mesh.face_array; + delete[] input_mesh.vertex_array; + + if (err != Thekla::Atlas_Error_Success) { + printf("error with atlas\n"); + } else { + *r_vertex = (int *)malloc(sizeof(int) * output->vertex_count); + *r_uv = (float *)malloc(sizeof(float) * output->vertex_count * 3); + *r_index = (int *)malloc(sizeof(int) * output->index_count); + + // printf("w: %i, h: %i\n", output->atlas_width, output->atlas_height); + for (int i = 0; i < output->vertex_count; i++) { + (*r_vertex)[i] = output->vertex_array[i].xref; + (*r_uv)[i * 2 + 0] = output->vertex_array[i].uv[0] / output->atlas_width; + (*r_uv)[i * 2 + 1] = output->vertex_array[i].uv[1] / output->atlas_height; + // printf("uv: %f,%f\n", (*r_uv)[i * 2 + 0], (*r_uv)[i * 2 + 1]); + } + *r_vertex_count = output->vertex_count; + + for (int i = 0; i < output->index_count; i++) { + (*r_index)[i] = output->index_array[i]; + } + + *r_index_count = output->index_count; + + *r_size_hint_x = output->atlas_height; + *r_size_hint_y = output->atlas_width; + } + + if (output) { + atlas_free(output); + } + + return err == Thekla::Atlas_Error_Success; +} + +void register_thekla_unwrap_types() { + + array_mesh_lightmap_unwrap_callback = thekla_mesh_lightmap_unwrap_callback; +} + +void unregister_thekla_unwrap_types() { +} diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 768d5185d7..82123d12ac 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -623,6 +623,29 @@ void CanvasItem::draw_polyline_colors(const Vector<Point2> &p_points, const Vect VisualServer::get_singleton()->canvas_item_add_polyline(canvas_item, p_points, p_colors, p_width, p_antialiased); } + +void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width, bool p_antialiased) { + + if (!drawing) { + ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); + ERR_FAIL(); + } + + Vector<Color> colors; + colors.push_back(p_color); + VisualServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, colors, p_width, p_antialiased); +} + +void CanvasItem::draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width, bool p_antialiased) { + + if (!drawing) { + ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); + ERR_FAIL(); + } + + VisualServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, p_colors, p_width, p_antialiased); +} + void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled) { if (!drawing) { @@ -979,6 +1002,8 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("draw_line", "from", "to", "color", "width", "antialiased"), &CanvasItem::draw_line, DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_polyline", "points", "color", "width", "antialiased"), &CanvasItem::draw_polyline, DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_polyline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_polyline_colors, DEFVAL(1.0), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("draw_multiline", "points", "color", "width", "antialiased"), &CanvasItem::draw_multiline, DEFVAL(1.0), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("draw_multiline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_multiline_colors, DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color", "filled"), &CanvasItem::draw_rect, DEFVAL(true)); ClassDB::bind_method(D_METHOD("draw_circle", "position", "radius", "color"), &CanvasItem::draw_circle); ClassDB::bind_method(D_METHOD("draw_texture", "texture", "position", "modulate", "normal_map"), &CanvasItem::draw_texture, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(Variant())); diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index ccbb528d6f..2384c0f370 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -268,6 +268,8 @@ public: void draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0, bool p_antialiased = false); void draw_polyline(const Vector<Point2> &p_points, const Color &p_color, float p_width = 1.0, bool p_antialiased = false); void draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false); + void draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width = 1.0, bool p_antialiased = false); + void draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false); void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true); void draw_circle(const Point2 &p_pos, float p_radius, const Color &p_color); void draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1, 1), const Ref<Texture> &p_normal_map = Ref<Texture>()); diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 609419cd44..5a32a3d0f0 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -965,14 +965,14 @@ void TileMap::_set_tile_data(const PoolVector<int> &p_data) { int c = p_data.size(); PoolVector<int>::Read r = p_data.read(); - int offset = (format == FORMAT_2_1_5) ? 3 : 2; + int offset = (format == FORMAT_2) ? 3 : 2; clear(); for (int i = 0; i < c; i += offset) { const uint8_t *ptr = (const uint8_t *)&r[i]; uint8_t local[12]; - for (int j = 0; j < ((format == FORMAT_2_1_5) ? 12 : 8); j++) + for (int j = 0; j < ((format == FORMAT_2) ? 12 : 8); j++) local[j] = ptr[j]; #ifdef BIG_ENDIAN_ENABLED @@ -982,7 +982,7 @@ void TileMap::_set_tile_data(const PoolVector<int> &p_data) { SWAP(local[4], local[7]); SWAP(local[5], local[6]); //TODO: ask someone to check this... - if (FORMAT == FORMAT_2_1_5) { + if (FORMAT == FORMAT_2) { SWAP(local[8], local[11]); SWAP(local[9], local[10]); } @@ -997,7 +997,7 @@ void TileMap::_set_tile_data(const PoolVector<int> &p_data) { v &= (1 << 29) - 1; int16_t coord_x; int16_t coord_y; - if (format == FORMAT_2_1_5) { + if (format == FORMAT_2) { coord_x = decode_uint16(&local[8]); coord_y = decode_uint16(&local[10]); } @@ -1015,6 +1015,8 @@ PoolVector<int> TileMap::_get_tile_data() const { data.resize(tile_map.size() * 3); PoolVector<int>::Write w = data.write(); + format = FORMAT_2; + int idx = 0; for (const Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) { uint8_t *ptr = (uint8_t *)&w[idx]; @@ -1295,7 +1297,7 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) { bool TileMap::_get(const StringName &p_name, Variant &r_ret) const { if (p_name == "format") { - r_ret = FORMAT_2_1_5; + r_ret = FORMAT_2; return true; } else if (p_name == "tile_data") { r_ret = _get_tile_data(); @@ -1591,7 +1593,7 @@ TileMap::TileMap() { y_sort_mode = false; occluder_light_mask = 1; clip_uv = false; - format = FORMAT_2_1_4; //Always initialize with the lowest format + format = FORMAT_1; //Always initialize with the lowest format fp_adjust = 0.00001; tile_origin = TILE_ORIGIN_TOP_LEFT; diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index edc9de0543..11d9915cb6 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -61,8 +61,8 @@ public: private: enum DataFormat { - FORMAT_2_1_4 = 0, - FORMAT_2_1_5 + FORMAT_1 = 0, + FORMAT_2 }; Ref<TileSet> tile_set; @@ -178,7 +178,7 @@ private: float bounce; uint32_t collision_layer; uint32_t collision_mask; - DataFormat format; + mutable DataFormat format; TileOrigin tile_origin; diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp index 8e2f87738a..ff5cb41135 100644 --- a/scene/3d/gi_probe.cpp +++ b/scene/3d/gi_probe.cpp @@ -1284,8 +1284,11 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) { _create_debug_mesh(&baker); } else { - Ref<GIProbeData> probe_data; - probe_data.instance(); + Ref<GIProbeData> probe_data = get_probe_data(); + + if(probe_data.is_null()) + probe_data.instance(); + probe_data->set_bounds(AABB(-extents, extents * 2.0)); probe_data->set_cell_size(baker.po2_bounds.size[longest_axis] / baker.axis_cell_size[longest_axis]); probe_data->set_dynamic_data(data); diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 0a886c25b1..842af20ac8 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -28,10 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "mesh.h" +#include "pair.h" #include "scene/resources/concave_polygon_shape.h" #include "scene/resources/convex_polygon_shape.h" #include "surface_tool.h" - void Mesh::_clear_triangle_mesh() const { triangle_mesh.unref(); @@ -413,8 +413,21 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const { return newmesh; } +void Mesh::set_lightmap_size_hint(const Vector2 &p_size) { + lightmap_size_hint = p_size; +} + +Size2 Mesh::get_lightmap_size_hint() const { + return lightmap_size_hint; +} + void Mesh::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_lightmap_size_hint", "size"), &Mesh::set_lightmap_size_hint); + ClassDB::bind_method(D_METHOD("get_lightmap_size_hint"), &Mesh::get_lightmap_size_hint); + + ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "lightmap_size_hint"), "set_lightmap_size_hint", "get_lightmap_size_hint"); + BIND_ENUM_CONSTANT(PRIMITIVE_POINTS); BIND_ENUM_CONSTANT(PRIMITIVE_LINES); BIND_ENUM_CONSTANT(PRIMITIVE_LINE_STRIP); @@ -1035,6 +1048,200 @@ void ArrayMesh::regen_normalmaps() { } } +//dirty hack +bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, const int *p_face_materials, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y) = NULL; + +struct ArrayMeshLightmapSurface { + + Ref<Material> material; + Vector<SurfaceTool::Vertex> vertices; + Mesh::PrimitiveType primitive; + uint32_t format; +}; + +Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texel_size) { + + ERR_FAIL_COND_V(!array_mesh_lightmap_unwrap_callback, ERR_UNCONFIGURED); + ERR_EXPLAIN("Can't unwrap mesh with blend shapes"); + ERR_FAIL_COND_V(blend_shapes.size() != 0, ERR_UNAVAILABLE); + + Vector<float> vertices; + Vector<float> normals; + Vector<int> indices; + Vector<int> face_materials; + Vector<float> uv; + Vector<Pair<int, int> > uv_index; + + Vector<ArrayMeshLightmapSurface> surfaces; + for (int i = 0; i < get_surface_count(); i++) { + ArrayMeshLightmapSurface s; + s.primitive = surface_get_primitive_type(i); + + if (s.primitive != Mesh::PRIMITIVE_TRIANGLES) { + ERR_EXPLAIN("Only triangles are supported for lightmap unwrap"); + ERR_FAIL_V(ERR_UNAVAILABLE); + } + s.format = surface_get_format(i); + if (!(s.format & ARRAY_FORMAT_NORMAL)) { + ERR_EXPLAIN("Normals are required for lightmap unwrap"); + ERR_FAIL_V(ERR_UNAVAILABLE); + } + + Array arrays = surface_get_arrays(i); + s.material = surface_get_material(i); + s.vertices = SurfaceTool::create_vertex_array_from_triangle_arrays(arrays); + + PoolVector<Vector3> rvertices = arrays[Mesh::ARRAY_VERTEX]; + int vc = rvertices.size(); + PoolVector<Vector3>::Read r = rvertices.read(); + + PoolVector<Vector3> rnormals = arrays[Mesh::ARRAY_NORMAL]; + PoolVector<Vector3>::Read rn = rnormals.read(); + + int vertex_ofs = vertices.size() / 3; + + vertices.resize((vertex_ofs + vc) * 3); + normals.resize((vertex_ofs + vc) * 3); + uv_index.resize(vertex_ofs + vc); + + for (int j = 0; j < vc; j++) { + + Vector3 v = p_base_transform.xform(r[j]); + + vertices[(j + vertex_ofs) * 3 + 0] = v.x; + vertices[(j + vertex_ofs) * 3 + 1] = v.y; + vertices[(j + vertex_ofs) * 3 + 2] = v.z; + normals[(j + vertex_ofs) * 3 + 0] = rn[j].x; + normals[(j + vertex_ofs) * 3 + 1] = rn[j].y; + normals[(j + vertex_ofs) * 3 + 2] = rn[j].z; + uv_index[j + vertex_ofs] = Pair<int, int>(i, j); + } + + PoolVector<int> rindices = arrays[Mesh::ARRAY_INDEX]; + int ic = rindices.size(); + int index_ofs = indices.size(); + + if (ic == 0) { + indices.resize(index_ofs + vc); + face_materials.resize((index_ofs + vc) / 3); + for (int j = 0; j < vc; j++) { + indices[index_ofs + j] = vertex_ofs + j; + } + for (int j = 0; j < vc / 3; j++) { + face_materials[(index_ofs / 3) + j] = i; + } + + } else { + PoolVector<int>::Read ri = rindices.read(); + indices.resize(index_ofs + ic); + face_materials.resize((index_ofs + ic) / 3); + for (int j = 0; j < ic; j++) { + indices[index_ofs + j] = vertex_ofs + ri[j]; + } + for (int j = 0; j < ic / 3; j++) { + face_materials[(index_ofs / 3) + j] = i; + } + } + + surfaces.push_back(s); + } + + //unwrap + + float *gen_uvs; + int *gen_vertices; + int *gen_indices; + int gen_vertex_count; + int gen_index_count; + int size_x; + int size_y; + + bool ok = array_mesh_lightmap_unwrap_callback(p_texel_size, vertices.ptr(), normals.ptr(), vertices.size() / 3, indices.ptr(), face_materials.ptr(), indices.size(), &gen_uvs, &gen_vertices, &gen_vertex_count, &gen_indices, &gen_index_count, &size_x, &size_y); + + if (!ok) { + return ERR_CANT_CREATE; + } + + //remove surfaces + while (get_surface_count()) { + surface_remove(0); + } + + //create surfacetools for each surface.. + Vector<Ref<SurfaceTool> > surfaces_tools; + + for (int i = 0; i < surfaces.size(); i++) { + Ref<SurfaceTool> st; + st.instance(); + st->begin(Mesh::PRIMITIVE_TRIANGLES); + st->set_material(surfaces[i].material); + surfaces_tools.push_back(st); //stay there + } + + print_line("gen indices: " + itos(gen_index_count)); + //go through all indices + for (int i = 0; i < gen_index_count; i += 3) { + + ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 0]], uv_index.size(), ERR_BUG); + ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 1]], uv_index.size(), ERR_BUG); + ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 2]], uv_index.size(), ERR_BUG); + + ERR_FAIL_COND_V(uv_index[gen_vertices[gen_indices[i + 0]]].first != uv_index[gen_vertices[gen_indices[i + 1]]].first || uv_index[gen_vertices[gen_indices[i + 0]]].first != uv_index[gen_vertices[gen_indices[i + 2]]].first, ERR_BUG); + + int surface = uv_index[gen_vertices[gen_indices[i + 0]]].first; + + for (int j = 0; j < 3; j++) { + + int vertex_idx = gen_vertices[gen_indices[i + j]]; + + SurfaceTool::Vertex v = surfaces[surface].vertices[uv_index[gen_vertices[gen_indices[i + j]]].second]; + + if (surfaces[surface].format & ARRAY_FORMAT_COLOR) { + surfaces_tools[surface]->add_color(v.color); + } + if (surfaces[surface].format & ARRAY_FORMAT_TEX_UV) { + surfaces_tools[surface]->add_uv(v.uv); + } + if (surfaces[surface].format & ARRAY_FORMAT_NORMAL) { + surfaces_tools[surface]->add_normal(v.normal); + } + if (surfaces[surface].format & ARRAY_FORMAT_TANGENT) { + Plane t; + t.normal = v.tangent; + t.d = v.binormal.dot(v.normal.cross(v.tangent)) < 0 ? -1 : 1; + surfaces_tools[surface]->add_tangent(t); + } + if (surfaces[surface].format & ARRAY_FORMAT_BONES) { + surfaces_tools[surface]->add_bones(v.bones); + } + if (surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) { + surfaces_tools[surface]->add_weights(v.weights); + } + + Vector2 uv2(gen_uvs[gen_indices[i + j] * 2 + 0], gen_uvs[gen_indices[i + j] * 2 + 1]); + surfaces_tools[surface]->add_uv2(uv2); + + surfaces_tools[surface]->add_vertex(v.vertex); + } + } + + //free stuff + ::free(gen_vertices); + ::free(gen_indices); + ::free(gen_uvs); + + //generate surfaces + + for (int i = 0; i < surfaces_tools.size(); i++) { + surfaces_tools[i]->index(); + surfaces_tools[i]->commit(Ref<ArrayMesh>((ArrayMesh *)this), surfaces[i].format); + } + + set_lightmap_size_hint(Size2(size_x, size_y)); + + return OK; +} + void ArrayMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("add_blend_shape", "name"), &ArrayMesh::add_blend_shape); diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index b85a6a84af..ea38ebf2ff 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -43,6 +43,8 @@ class Mesh : public Resource { GDCLASS(Mesh, Resource); mutable Ref<TriangleMesh> triangle_mesh; //cached + Size2 lightmap_size_hint; + protected: void _clear_triangle_mesh() const; @@ -138,6 +140,9 @@ public: virtual AABB get_aabb() const = 0; + void set_lightmap_size_hint(const Vector2 &p_size); + Size2 get_lightmap_size_hint() const; + Mesh(); }; @@ -216,6 +221,8 @@ public: void center_geometry(); void regen_normalmaps(); + Error lightmap_unwrap(const Transform &p_base_transform = Transform(), float p_texel_size = 0.05); + virtual void reload_from_file(); ArrayMesh(); diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index bf89e704bc..352418e65c 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -101,6 +101,7 @@ void SurfaceTool::add_vertex(const Vector3 &p_vertex) { vtx.color = last_color; vtx.normal = last_normal; vtx.uv = last_uv; + vtx.uv2 = last_uv2; vtx.weights = last_weights; vtx.bones = last_bones; vtx.tangent = last_tangent.normal; @@ -401,7 +402,7 @@ Array SurfaceTool::commit_to_arrays() { return a; } -Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing) { +Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing, uint32_t p_flags) { Ref<ArrayMesh> mesh; if (p_existing.is_valid()) @@ -418,7 +419,7 @@ Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing) { Array a = commit_to_arrays(); - mesh->add_surface_from_arrays(primitive, a); + mesh->add_surface_from_arrays(primitive, a, Array(), p_flags); if (material.is_valid()) mesh->surface_set_material(surface, material); @@ -482,6 +483,113 @@ void SurfaceTool::_create_list(const Ref<Mesh> &p_existing, int p_surface, List< _create_list_from_arrays(arr, r_vertex, r_index, lformat); } +Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_arrays(const Array &p_arrays) { + + Vector<SurfaceTool::Vertex> ret; + + PoolVector<Vector3> varr = p_arrays[VS::ARRAY_VERTEX]; + PoolVector<Vector3> narr = p_arrays[VS::ARRAY_NORMAL]; + PoolVector<float> tarr = p_arrays[VS::ARRAY_TANGENT]; + PoolVector<Color> carr = p_arrays[VS::ARRAY_COLOR]; + PoolVector<Vector2> uvarr = p_arrays[VS::ARRAY_TEX_UV]; + PoolVector<Vector2> uv2arr = p_arrays[VS::ARRAY_TEX_UV2]; + PoolVector<int> barr = p_arrays[VS::ARRAY_BONES]; + PoolVector<float> warr = p_arrays[VS::ARRAY_WEIGHTS]; + + int vc = varr.size(); + + if (vc == 0) + return ret; + int lformat = 0; + + PoolVector<Vector3>::Read rv; + if (varr.size()) { + lformat |= VS::ARRAY_FORMAT_VERTEX; + rv = varr.read(); + } + PoolVector<Vector3>::Read rn; + if (narr.size()) { + lformat |= VS::ARRAY_FORMAT_NORMAL; + rn = narr.read(); + } + PoolVector<float>::Read rt; + if (tarr.size()) { + lformat |= VS::ARRAY_FORMAT_TANGENT; + rt = tarr.read(); + } + PoolVector<Color>::Read rc; + if (carr.size()) { + lformat |= VS::ARRAY_FORMAT_COLOR; + rc = carr.read(); + } + + PoolVector<Vector2>::Read ruv; + if (uvarr.size()) { + lformat |= VS::ARRAY_FORMAT_TEX_UV; + ruv = uvarr.read(); + } + + PoolVector<Vector2>::Read ruv2; + if (uv2arr.size()) { + lformat |= VS::ARRAY_FORMAT_TEX_UV2; + ruv2 = uv2arr.read(); + } + + PoolVector<int>::Read rb; + if (barr.size()) { + lformat |= VS::ARRAY_FORMAT_BONES; + rb = barr.read(); + } + + PoolVector<float>::Read rw; + if (warr.size()) { + lformat |= VS::ARRAY_FORMAT_WEIGHTS; + rw = warr.read(); + } + + for (int i = 0; i < vc; i++) { + + Vertex v; + if (lformat & VS::ARRAY_FORMAT_VERTEX) + v.vertex = varr[i]; + if (lformat & VS::ARRAY_FORMAT_NORMAL) + v.normal = narr[i]; + if (lformat & VS::ARRAY_FORMAT_TANGENT) { + Plane p(tarr[i * 4 + 0], tarr[i * 4 + 1], tarr[i * 4 + 2], tarr[i * 4 + 3]); + v.tangent = p.normal; + v.binormal = p.normal.cross(v.tangent).normalized() * p.d; + } + if (lformat & VS::ARRAY_FORMAT_COLOR) + v.color = carr[i]; + if (lformat & VS::ARRAY_FORMAT_TEX_UV) + v.uv = uvarr[i]; + if (lformat & VS::ARRAY_FORMAT_TEX_UV2) + v.uv2 = uv2arr[i]; + if (lformat & VS::ARRAY_FORMAT_BONES) { + Vector<int> b; + b.resize(4); + b[0] = barr[i * 4 + 0]; + b[1] = barr[i * 4 + 1]; + b[2] = barr[i * 4 + 2]; + b[3] = barr[i * 4 + 3]; + v.bones = b; + } + if (lformat & VS::ARRAY_FORMAT_WEIGHTS) { + Vector<float> w; + w.resize(4); + w[0] = warr[i * 4 + 0]; + w[1] = warr[i * 4 + 1]; + w[2] = warr[i * 4 + 2]; + w[3] = warr[i * 4 + 3]; + v.weights = w; + } + + ret.push_back(v); + } + + return ret; +} + void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, int &lformat) { PoolVector<Vector3> varr = arr[VS::ARRAY_VERTEX]; @@ -882,7 +990,7 @@ void SurfaceTool::_bind_methods() { ClassDB::bind_method(D_METHOD("create_from", "existing", "surface"), &SurfaceTool::create_from); ClassDB::bind_method(D_METHOD("append_from", "existing", "surface", "transform"), &SurfaceTool::append_from); - ClassDB::bind_method(D_METHOD("commit", "existing"), &SurfaceTool::commit, DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("commit", "existing"), &SurfaceTool::commit, DEFVAL(Variant()), DEFVAL(Mesh::ARRAY_COMPRESS_DEFAULT)); } SurfaceTool::SurfaceTool() { diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index cdaac643de..b180ffe260 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -127,10 +127,11 @@ public: List<Vertex> &get_vertex_array() { return vertex_array; } void create_from_triangle_arrays(const Array &p_arrays); + static Vector<Vertex> create_vertex_array_from_triangle_arrays(const Array &p_arrays); Array commit_to_arrays(); void create_from(const Ref<Mesh> &p_existing, int p_surface); void append_from(const Ref<Mesh> &p_existing, int p_surface, const Transform &p_xform); - Ref<ArrayMesh> commit(const Ref<ArrayMesh> &p_existing = Ref<ArrayMesh>()); + Ref<ArrayMesh> commit(const Ref<ArrayMesh> &p_existing = Ref<ArrayMesh>(), uint32_t p_flags = Mesh::ARRAY_COMPRESS_DEFAULT); SurfaceTool(); }; diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 0ee70878dc..df41c3b5ce 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -636,6 +636,7 @@ public: struct CommandPolyLine : public Command { bool antialiased; + bool multiline; Vector<Point2> triangles; Vector<Color> triangle_colors; Vector<Point2> lines; @@ -643,6 +644,7 @@ public: CommandPolyLine() { type = TYPE_POLYLINE; antialiased = false; + multiline = false; } }; diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 4de902af58..e10a57c571 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -254,6 +254,9 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = { { TK_TYPE_ISAMPLER2D, "isampler2D" }, { TK_TYPE_USAMPLER2D, "usampler2D" }, { TK_TYPE_SAMPLERCUBE, "samplerCube" }, + { TK_INTERPOLATION_FLAT, "flat" }, + { TK_INTERPOLATION_NO_PERSPECTIVE, "noperspective" }, + { TK_INTERPOLATION_SMOOTH, "smooth" }, { TK_PRECISION_LOW, "lowp" }, { TK_PRECISION_MID, "mediump" }, { TK_PRECISION_HIGH, "highp" }, @@ -658,6 +661,24 @@ ShaderLanguage::DataType ShaderLanguage::get_token_datatype(TokenType p_type) { return DataType(p_type - TK_TYPE_VOID); } +bool ShaderLanguage::is_token_interpolation(TokenType p_type) { + + return ( + p_type == TK_INTERPOLATION_FLAT || + p_type == TK_INTERPOLATION_NO_PERSPECTIVE || + p_type == TK_INTERPOLATION_SMOOTH); +} + +ShaderLanguage::DataInterpolation ShaderLanguage::get_token_interpolation(TokenType p_type) { + + if (p_type == TK_INTERPOLATION_FLAT) + return INTERPOLATION_FLAT; + else if (p_type == TK_INTERPOLATION_NO_PERSPECTIVE) + return INTERPOLATION_NO_PERSPECTIVE; + else + return INTERPOLATION_SMOOTH; +} + bool ShaderLanguage::is_token_precision(TokenType p_type) { return ( @@ -3576,10 +3597,16 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct bool uniform = tk.type == TK_UNIFORM; DataPrecision precision = PRECISION_DEFAULT; + DataInterpolation interpolation = INTERPOLATION_SMOOTH; DataType type; StringName name; tk = _get_token(); + if (is_token_interpolation(tk.type)) { + interpolation = get_token_interpolation(tk.type); + tk = _get_token(); + } + if (is_token_precision(tk.type)) { precision = get_token_precision(tk.type); tk = _get_token(); @@ -3777,6 +3804,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct ShaderNode::Varying varying; varying.type = type; varying.precission = precision; + varying.interpolation = interpolation; shader->varyings[name] = varying; tk = _get_token(); diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h index 7a7f6dd71c..e092bf931f 100644 --- a/servers/visual/shader_language.h +++ b/servers/visual/shader_language.h @@ -72,6 +72,9 @@ public: TK_TYPE_ISAMPLER2D, TK_TYPE_USAMPLER2D, TK_TYPE_SAMPLERCUBE, + TK_INTERPOLATION_FLAT, + TK_INTERPOLATION_NO_PERSPECTIVE, + TK_INTERPOLATION_SMOOTH, TK_PRECISION_LOW, TK_PRECISION_MID, TK_PRECISION_HIGH, @@ -192,6 +195,12 @@ public: PRECISION_DEFAULT, }; + enum DataInterpolation { + INTERPOLATION_FLAT, + INTERPOLATION_NO_PERSPECTIVE, + INTERPOLATION_SMOOTH, + }; + enum Operator { OP_EQUAL, OP_NOT_EQUAL, @@ -431,6 +440,7 @@ public: struct Varying { DataType type; + DataInterpolation interpolation; DataPrecision precission; }; @@ -511,6 +521,8 @@ public: static bool is_token_datatype(TokenType p_type); static DataType get_token_datatype(TokenType p_type); + static bool is_token_interpolation(TokenType p_type); + static DataInterpolation get_token_interpolation(TokenType p_type); static bool is_token_precision(TokenType p_type); static DataPrecision get_token_precision(TokenType p_type); static String get_datatype_name(DataType p_type); diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp index 31c09dc23d..0fed9cc961 100644 --- a/servers/visual/visual_server_canvas.cpp +++ b/servers/visual/visual_server_canvas.cpp @@ -416,6 +416,7 @@ void VisualServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Point ERR_FAIL_COND(!pline); pline->antialiased = p_antialiased; + pline->multiline = false; if (p_width <= 1) { pline->lines = p_points; @@ -486,6 +487,90 @@ void VisualServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Point canvas_item->commands.push_back(pline); } +void VisualServerCanvas::canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width, bool p_antialiased) { + + ERR_FAIL_COND(p_points.size() < 2); + Item *canvas_item = canvas_item_owner.getornull(p_item); + ERR_FAIL_COND(!canvas_item); + + Item::CommandPolyLine *pline = memnew(Item::CommandPolyLine); + ERR_FAIL_COND(!pline); + + pline->antialiased = false; //todo + pline->multiline = true; + + // if (p_width <= 1) { + pline->lines = p_points; + pline->line_colors = p_colors; + if (pline->line_colors.size() == 0) { + pline->line_colors.push_back(Color(1, 1, 1, 1)); + } else if (pline->line_colors.size() > 1 && pline->line_colors.size() != pline->lines.size()) { + pline->line_colors.resize(1); + } +#if 0 +//width not yet + } else { + //make a trianglestrip for drawing the line... + Vector2 prev_t; + pline->triangles.resize(p_points.size() * 2); + if (p_antialiased) { + pline->lines.resize(p_points.size() * 2); + } + + if (p_colors.size() == 0) { + pline->triangle_colors.push_back(Color(1, 1, 1, 1)); + if (p_antialiased) { + pline->line_colors.push_back(Color(1, 1, 1, 1)); + } + } + if (p_colors.size() == 1) { + pline->triangle_colors = p_colors; + pline->line_colors = p_colors; + } else { + pline->triangle_colors.resize(pline->triangles.size()); + pline->line_colors.resize(pline->lines.size()); + } + + for (int i = 0; i < p_points.size(); i++) { + + Vector2 t; + if (i == p_points.size() - 1) { + t = prev_t; + } else { + t = (p_points[i + 1] - p_points[i]).normalized().tangent(); + if (i == 0) { + prev_t = t; + } + } + + Vector2 tangent = ((t + prev_t).normalized()) * p_width * 0.5; + + if (p_antialiased) { + pline->lines[i] = p_points[i] + tangent; + pline->lines[p_points.size() * 2 - i - 1] = p_points[i] - tangent; + if (pline->line_colors.size() > 1) { + pline->line_colors[i] = p_colors[i]; + pline->line_colors[p_points.size() * 2 - i - 1] = p_colors[i]; + } + } + + pline->triangles[i * 2 + 0] = p_points[i] + tangent; + pline->triangles[i * 2 + 1] = p_points[i] - tangent; + + if (pline->triangle_colors.size() > 1) { + + pline->triangle_colors[i * 2 + 0] = p_colors[i]; + pline->triangle_colors[i * 2 + 1] = p_colors[i]; + } + + prev_t = t; + } + } +#endif + canvas_item->rect_dirty = true; + canvas_item->commands.push_back(pline); +} + void VisualServerCanvas::canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color) { Item *canvas_item = canvas_item_owner.getornull(p_item); diff --git a/servers/visual/visual_server_canvas.h b/servers/visual/visual_server_canvas.h index a92370f1f0..3143ac847f 100644 --- a/servers/visual/visual_server_canvas.h +++ b/servers/visual/visual_server_canvas.h @@ -172,6 +172,7 @@ public: void canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0, bool p_antialiased = false); void canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false); + void canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false); void canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color); void canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color); void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID()); diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 9223d81e32..d843c443a2 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -551,6 +551,7 @@ public: BIND6(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float, bool) BIND5(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool) + BIND5(canvas_item_add_multiline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool) BIND3(canvas_item_add_rect, RID, const Rect2 &, const Color &) BIND4(canvas_item_add_circle, RID, const Point2 &, float, const Color &) BIND7(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool, RID) diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index b58b1d917e..94f450c024 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -467,6 +467,7 @@ public: FUNC6(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float, bool) FUNC5(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool) + FUNC5(canvas_item_add_multiline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool) FUNC3(canvas_item_add_rect, RID, const Rect2 &, const Color &) FUNC4(canvas_item_add_circle, RID, const Point2 &, float, const Color &) FUNC7(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool, RID) diff --git a/servers/visual_server.h b/servers/visual_server.h index 350097c1b5..de5ef7da0a 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -815,6 +815,7 @@ public: virtual void canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0, bool p_antialiased = false) = 0; virtual void canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false) = 0; + virtual void canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false) = 0; virtual void canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color) = 0; virtual void canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color) = 0; virtual void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID()) = 0; diff --git a/thirdparty/thekla_atlas/nvmesh/param/Atlas.cpp b/thirdparty/thekla_atlas/nvmesh/param/Atlas.cpp index 4e41e76695..98f92cef96 100644 --- a/thirdparty/thekla_atlas/nvmesh/param/Atlas.cpp +++ b/thirdparty/thekla_atlas/nvmesh/param/Atlas.cpp @@ -38,6 +38,7 @@ using namespace nv; /// Ctor. Atlas::Atlas() { + failed=false; } // Dtor. @@ -100,6 +101,7 @@ void Atlas::extractCharts(const HalfEdge::Mesh * mesh) void Atlas::computeCharts(const HalfEdge::Mesh * mesh, const SegmentationSettings & settings, const Array<uint> & unchartedMaterialArray) { + failed=false; MeshCharts * meshCharts = new MeshCharts(mesh); meshCharts->computeCharts(settings, unchartedMaterialArray); addMeshCharts(meshCharts); @@ -235,6 +237,8 @@ float Atlas::packCharts(int quality, float texelsPerUnit, bool blockAlign, bool { AtlasPacker packer(this); packer.packCharts(quality, texelsPerUnit, blockAlign, conservative); + if (hasFailed()) + return 0; return packer.computeAtlasUtilization(); } diff --git a/thirdparty/thekla_atlas/nvmesh/param/Atlas.h b/thirdparty/thekla_atlas/nvmesh/param/Atlas.h index 8b478207e3..41cfaea9cb 100644 --- a/thirdparty/thekla_atlas/nvmesh/param/Atlas.h +++ b/thirdparty/thekla_atlas/nvmesh/param/Atlas.h @@ -64,9 +64,12 @@ namespace nv // Pack charts in the smallest possible rectangle. float packCharts(int quality, float texelArea, bool blockAlign, bool conservative); + void setFailed() { failed = true; } + bool hasFailed() const { return failed; } private: + bool failed; Array<MeshCharts *> m_meshChartsArray; }; diff --git a/thirdparty/thekla_atlas/nvmesh/param/AtlasPacker.cpp b/thirdparty/thekla_atlas/nvmesh/param/AtlasPacker.cpp index f2156899ae..5ce452cb9e 100644 --- a/thirdparty/thekla_atlas/nvmesh/param/AtlasPacker.cpp +++ b/thirdparty/thekla_atlas/nvmesh/param/AtlasPacker.cpp @@ -152,7 +152,7 @@ AtlasPacker::~AtlasPacker() } // This should compute convex hull and use rotating calipers to find the best box. Currently it uses a brute force method. -static void computeBoundingBox(Chart * chart, Vector2 * majorAxis, Vector2 * minorAxis, Vector2 * minCorner, Vector2 * maxCorner) +static bool computeBoundingBox(Chart * chart, Vector2 * majorAxis, Vector2 * minorAxis, Vector2 * minCorner, Vector2 * maxCorner) { // Compute list of boundary points. Array<Vector2> points(16); @@ -184,6 +184,9 @@ static void computeBoundingBox(Chart * chart, Vector2 * majorAxis, Vector2 * min #if 1 Array<Vector2> hull; + if (points.size()==0) { + return false; + } convexHull(points, hull, 0.00001f); @@ -373,6 +376,8 @@ static void computeBoundingBox(Chart * chart, Vector2 * majorAxis, Vector2 * min } }*/ #endif + + return true; } @@ -431,7 +436,10 @@ void AtlasPacker::packCharts(int quality, float texelsPerUnit, bool blockAligned // Compute bounding box of chart. Vector2 majorAxis, minorAxis, origin, end; - computeBoundingBox(chart, &majorAxis, &minorAxis, &origin, &end); + if (!computeBoundingBox(chart, &majorAxis, &minorAxis, &origin, &end)) { + m_atlas->setFailed(); + return; + } nvCheck(isFinite(majorAxis) && isFinite(minorAxis) && isFinite(origin)); diff --git a/thirdparty/thekla_atlas/thekla/thekla_atlas.cpp b/thirdparty/thekla_atlas/thekla/thekla_atlas.cpp new file mode 100644 index 0000000000..d6f0accf54 --- /dev/null +++ b/thirdparty/thekla_atlas/thekla/thekla_atlas.cpp @@ -0,0 +1,271 @@ + +#include "thekla_atlas.h" + +#include <cfloat> + +#include "nvmesh/halfedge/Edge.h" +#include "nvmesh/halfedge/Mesh.h" +#include "nvmesh/halfedge/Face.h" +#include "nvmesh/halfedge/Vertex.h" +#include "nvmesh/param/Atlas.h" + +#include "nvmath/Vector.inl" +#include "nvmath/ftoi.h" + +#include "nvcore/Array.inl" + + +using namespace Thekla; +using namespace nv; + + +inline Atlas_Output_Mesh * set_error(Atlas_Error * error, Atlas_Error code) { + if (error) *error = code; + return NULL; +} + + + +static void input_to_mesh(const Atlas_Input_Mesh * input, HalfEdge::Mesh * mesh, Atlas_Error * error) { + + Array<uint> canonicalMap; + canonicalMap.reserve(input->vertex_count); + + for (int i = 0; i < input->vertex_count; i++) { + const Atlas_Input_Vertex & input_vertex = input->vertex_array[i]; + const float * pos = input_vertex.position; + const float * nor = input_vertex.normal; + const float * tex = input_vertex.uv; + + HalfEdge::Vertex * vertex = mesh->addVertex(Vector3(pos[0], pos[1], pos[2])); + vertex->nor.set(nor[0], nor[1], nor[2]); + vertex->tex.set(tex[0], tex[1]); + + canonicalMap.append(input_vertex.first_colocal); + } + + mesh->linkColocalsWithCanonicalMap(canonicalMap); + + + const int face_count = input->face_count; + + int non_manifold_faces = 0; + for (int i = 0; i < face_count; i++) { + const Atlas_Input_Face & input_face = input->face_array[i]; + + int v0 = input_face.vertex_index[0]; + int v1 = input_face.vertex_index[1]; + int v2 = input_face.vertex_index[2]; + + HalfEdge::Face * face = mesh->addFace(v0, v1, v2); + if (face != NULL) { + face->material = input_face.material_index; + } + else { + non_manifold_faces++; + } + } + + mesh->linkBoundary(); + + if (non_manifold_faces != 0 && error != NULL) { + *error = Atlas_Error_Invalid_Mesh_Non_Manifold; + } +} + +static Atlas_Output_Mesh * mesh_atlas_to_output(const HalfEdge::Mesh * mesh, const Atlas & atlas, Atlas_Error * error) { + + Atlas_Output_Mesh * output = new Atlas_Output_Mesh; + + const MeshCharts * charts = atlas.meshAt(0); + + // Allocate vertices. + const int vertex_count = charts->vertexCount(); + output->vertex_count = vertex_count; + output->vertex_array = new Atlas_Output_Vertex[vertex_count]; + + int w = 0; + int h = 0; + + // Output vertices. + const int chart_count = charts->chartCount(); + for (int i = 0; i < chart_count; i++) { + const Chart * chart = charts->chartAt(i); + uint vertexOffset = charts->vertexCountBeforeChartAt(i); + + const uint chart_vertex_count = chart->vertexCount(); + for (uint v = 0; v < chart_vertex_count; v++) { + Atlas_Output_Vertex & output_vertex = output->vertex_array[vertexOffset + v]; + + uint original_vertex = chart->mapChartVertexToOriginalVertex(v); + output_vertex.xref = original_vertex; + + Vector2 uv = chart->chartMesh()->vertexAt(v)->tex; + output_vertex.uv[0] = uv.x; + output_vertex.uv[1] = uv.y; + w = max(w, ftoi_ceil(uv.x)); + h = max(h, ftoi_ceil(uv.y)); + } + } + + const int face_count = mesh->faceCount(); + output->index_count = face_count * 3; + output->index_array = new int[face_count * 3]; + + // Set face indices. + for (int f = 0; f < face_count; f++) { + uint c = charts->faceChartAt(f); + uint i = charts->faceIndexWithinChartAt(f); + uint vertexOffset = charts->vertexCountBeforeChartAt(c); + + const Chart * chart = charts->chartAt(c); + nvDebugCheck(chart->faceAt(i) == f); + + const HalfEdge::Face * face = chart->chartMesh()->faceAt(i); + const HalfEdge::Edge * edge = face->edge; + + output->index_array[3*f+0] = vertexOffset + edge->vertex->id; + output->index_array[3*f+1] = vertexOffset + edge->next->vertex->id; + output->index_array[3*f+2] = vertexOffset + edge->next->next->vertex->id; + } + + *error = Atlas_Error_Success; + output->atlas_width = w; + output->atlas_height = h; + + return output; +} + + +void Thekla::atlas_set_default_options(Atlas_Options * options) { + if (options != NULL) { + // These are the default values we use on The Witness. + + options->charter = Atlas_Charter_Default; + options->charter_options.witness.proxy_fit_metric_weight = 2.0f; + options->charter_options.witness.roundness_metric_weight = 0.01f; + options->charter_options.witness.straightness_metric_weight = 6.0f; + options->charter_options.witness.normal_seam_metric_weight = 4.0f; + options->charter_options.witness.texture_seam_metric_weight = 0.5f; + options->charter_options.witness.max_chart_area = FLT_MAX; + options->charter_options.witness.max_boundary_length = FLT_MAX; + + options->mapper = Atlas_Mapper_Default; + + options->packer = Atlas_Packer_Default; + options->packer_options.witness.packing_quality = 0; + options->packer_options.witness.texel_area = 8; + options->packer_options.witness.block_align = true; + options->packer_options.witness.conservative = false; + } +} + + +Atlas_Output_Mesh * Thekla::atlas_generate(const Atlas_Input_Mesh * input, const Atlas_Options * options, Atlas_Error * error) { + // Validate args. + if (input == NULL || options == NULL || error == NULL) return set_error(error, Atlas_Error_Invalid_Args); + + // Validate options. + if (options->charter != Atlas_Charter_Witness) { + return set_error(error, Atlas_Error_Invalid_Options); + } + if (options->charter == Atlas_Charter_Witness) { + // @@ Validate input options! + } + + if (options->mapper != Atlas_Mapper_LSCM) { + return set_error(error, Atlas_Error_Invalid_Options); + } + if (options->mapper == Atlas_Mapper_LSCM) { + // No options. + } + + if (options->packer != Atlas_Packer_Witness) { + return set_error(error, Atlas_Error_Invalid_Options); + } + if (options->packer == Atlas_Packer_Witness) { + // @@ Validate input options! + } + + // Validate input mesh. + for (int i = 0; i < input->face_count; i++) { + int v0 = input->face_array[i].vertex_index[0]; + int v1 = input->face_array[i].vertex_index[1]; + int v2 = input->face_array[i].vertex_index[2]; + + if (v0 < 0 || v0 >= input->vertex_count || + v1 < 0 || v1 >= input->vertex_count || + v2 < 0 || v2 >= input->vertex_count) + { + return set_error(error, Atlas_Error_Invalid_Mesh); + } + } + + + // Build half edge mesh. + AutoPtr<HalfEdge::Mesh> mesh(new HalfEdge::Mesh); + + input_to_mesh(input, mesh.ptr(), error); + + if (*error == Atlas_Error_Invalid_Mesh) { + return NULL; + } + + Atlas atlas; + + // Charter. + if (options->charter == Atlas_Charter_Extract) { + return set_error(error, Atlas_Error_Not_Implemented); + } + else if (options->charter == Atlas_Charter_Witness) { + SegmentationSettings segmentation_settings; + segmentation_settings.proxyFitMetricWeight = options->charter_options.witness.proxy_fit_metric_weight; + segmentation_settings.roundnessMetricWeight = options->charter_options.witness.roundness_metric_weight; + segmentation_settings.straightnessMetricWeight = options->charter_options.witness.straightness_metric_weight; + segmentation_settings.normalSeamMetricWeight = options->charter_options.witness.normal_seam_metric_weight; + segmentation_settings.textureSeamMetricWeight = options->charter_options.witness.texture_seam_metric_weight; + segmentation_settings.maxChartArea = options->charter_options.witness.max_chart_area; + segmentation_settings.maxBoundaryLength = options->charter_options.witness.max_boundary_length; + + Array<uint> uncharted_materials; + atlas.computeCharts(mesh.ptr(), segmentation_settings, uncharted_materials); + } + + if (atlas.hasFailed()) + return NULL; + + // Mapper. + if (options->mapper == Atlas_Mapper_LSCM) { + atlas.parameterizeCharts(); + } + + if (atlas.hasFailed()) + return NULL; + + // Packer. + if (options->packer == Atlas_Packer_Witness) { + int packing_quality = options->packer_options.witness.packing_quality; + float texel_area = options->packer_options.witness.texel_area; + int block_align = options->packer_options.witness.block_align; + int conservative = options->packer_options.witness.conservative; + + /*float utilization =*/ atlas.packCharts(packing_quality, texel_area, block_align, conservative); + } + + if (atlas.hasFailed()) + return NULL; + + + // Build output mesh. + return mesh_atlas_to_output(mesh.ptr(), atlas, error); +} + + +void Thekla::atlas_free(Atlas_Output_Mesh * output) { + if (output != NULL) { + delete [] output->vertex_array; + delete [] output->index_array; + delete output; + } +} + diff --git a/thirdparty/thekla_atlas/thekla/thekla_atlas.h b/thirdparty/thekla_atlas/thekla/thekla_atlas.h new file mode 100644 index 0000000000..1d0716e781 --- /dev/null +++ b/thirdparty/thekla_atlas/thekla/thekla_atlas.h @@ -0,0 +1,116 @@ + +// Thekla Atlas Generator + +namespace Thekla { + +enum Atlas_Charter { + Atlas_Charter_Witness, // Options: threshold + Atlas_Charter_Extract, // Options: --- + Atlas_Charter_Default = Atlas_Charter_Witness +}; + +enum Atlas_Mapper { + Atlas_Mapper_LSCM, // Options: --- + Atlas_Mapper_Default = Atlas_Mapper_LSCM +}; + +enum Atlas_Packer { + Atlas_Packer_Witness, // Options: texel_area + Atlas_Packer_Default = Atlas_Packer_Witness +}; + +struct Atlas_Options { + Atlas_Charter charter; + union { + struct { + float proxy_fit_metric_weight; + float roundness_metric_weight; + float straightness_metric_weight; + float normal_seam_metric_weight; + float texture_seam_metric_weight; + float max_chart_area; + float max_boundary_length; + } witness; + struct { + } extract; + } charter_options; + + Atlas_Mapper mapper; + union { + } mapper_options; + + Atlas_Packer packer; + union { + struct { + int packing_quality; + float texel_area; // This is not really texel area, but 1 / texel width? + bool block_align; // Align charts to 4x4 blocks. + bool conservative; // Pack charts with extra padding. + } witness; + } packer_options; +}; + +struct Atlas_Input_Vertex { + float position[3]; + float normal[3]; + float uv[2]; + int first_colocal; +}; + +struct Atlas_Input_Face { + int vertex_index[3]; + int material_index; +}; + +struct Atlas_Input_Mesh { + int vertex_count; + int face_count; + Atlas_Input_Vertex * vertex_array; + Atlas_Input_Face * face_array; +}; + +struct Atlas_Output_Vertex { + float uv[2]; + int xref; // Index of input vertex from which this output vertex originated. +}; + +struct Atlas_Output_Mesh { + int atlas_width; + int atlas_height; + int vertex_count; + int index_count; + Atlas_Output_Vertex * vertex_array; + int * index_array; +}; + +enum Atlas_Error { + Atlas_Error_Success, + Atlas_Error_Invalid_Args, + Atlas_Error_Invalid_Options, + Atlas_Error_Invalid_Mesh, + Atlas_Error_Invalid_Mesh_Non_Manifold, + Atlas_Error_Not_Implemented, +}; + +void atlas_set_default_options(Atlas_Options * options); + +Atlas_Output_Mesh * atlas_generate(const Atlas_Input_Mesh * input, const Atlas_Options * options, Atlas_Error * error); + +void atlas_free(Atlas_Output_Mesh * output); + + +/* + +Should we represent the input mesh with an opaque structure that simply holds pointers to the user data? That would allow us to avoid having to copy attributes to an intermediate representation. + +struct Atlas_Input_Mesh; + +void mesh_set_vertex_position(Atlas_Input_Mesh * mesh, float * ptr, int stride); +void mesh_set_vertex_normal(Atlas_Input_Mesh * mesh, float * ptr, int stride); +void mesh_set_vertex_uv(Mesh * mesh, float * ptr, int stride); + +void mesh_set_index(Mesh * mesh, int * ptr); +*/ + +} // Thekla namespace + |