Merge branch 'master' of https://github.com/okamstudio/godot
This commit is contained in:
commit
63033aa646
75 changed files with 3541 additions and 504 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -23,6 +23,9 @@ tools/editor/editor_icons.cpp
|
|||
make.bat
|
||||
log.txt
|
||||
|
||||
# Doxygen generated documentation
|
||||
doc/doxygen/*
|
||||
|
||||
# Javascript specific
|
||||
*.bc
|
||||
|
||||
|
|
6
Doxyfile
6
Doxyfile
|
@ -51,14 +51,14 @@ PROJECT_BRIEF = "Game Engine MIT"
|
|||
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
|
||||
# the logo to the output directory.
|
||||
|
||||
PROJECT_LOGO = E:/development/godot/logo_small.png
|
||||
PROJECT_LOGO = ./logo_small.png
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
|
||||
# into which the generated documentation will be written. If a relative path is
|
||||
# entered, it will be relative to the location where doxygen was started. If
|
||||
# left blank the current directory will be used.
|
||||
|
||||
OUTPUT_DIRECTORY = E:/development/godot/doxygen
|
||||
OUTPUT_DIRECTORY = ./doc/doxygen/
|
||||
|
||||
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
|
||||
# directories (in 2 levels) under the output directory of each output format and
|
||||
|
@ -768,7 +768,7 @@ WARN_LOGFILE =
|
|||
# spaces.
|
||||
# Note: If this tag is empty the current directory is searched.
|
||||
|
||||
INPUT = E:/development/godot
|
||||
INPUT = ./core/ ./main/ ./scene/
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||
|
|
|
@ -61,6 +61,7 @@ const char ** tests_get_names() {
|
|||
"gui",
|
||||
"io",
|
||||
"shaderlang",
|
||||
"physics",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
@ -31,8 +31,7 @@ void FuncRef::_bind_methods() {
|
|||
|
||||
{
|
||||
MethodInfo mi;
|
||||
mi.name="call";
|
||||
mi.arguments.push_back( PropertyInfo( Variant::STRING, "method"));
|
||||
mi.name="call_func";
|
||||
Vector<Variant> defargs;
|
||||
for(int i=0;i<10;i++) {
|
||||
mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i)));
|
||||
|
|
|
@ -299,10 +299,8 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *
|
|||
ERR_FAIL_COND_V(len<12,ERR_INVALID_DATA);
|
||||
Vector<StringName> names;
|
||||
Vector<StringName> subnames;
|
||||
bool absolute;
|
||||
StringName prop;
|
||||
|
||||
int i=0;
|
||||
uint32_t namecount=strlen&=0x7FFFFFFF;
|
||||
uint32_t subnamecount = decode_uint32(buf+4);
|
||||
uint32_t flags = decode_uint32(buf+8);
|
||||
|
@ -391,7 +389,6 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *
|
|||
|
||||
ie.type=decode_uint32(&buf[0]);
|
||||
ie.device=decode_uint32(&buf[4]);
|
||||
uint32_t len = decode_uint32(&buf[8])-12;
|
||||
|
||||
if (r_len)
|
||||
(*r_len)+=12;
|
||||
|
|
|
@ -231,14 +231,12 @@ Ref<ResourceImportMetadata> ResourceLoader::load_import_metadata(const String &p
|
|||
local_path = Globals::get_singleton()->localize_path(p_path);
|
||||
|
||||
String extension=p_path.extension();
|
||||
bool found=false;
|
||||
Ref<ResourceImportMetadata> ret;
|
||||
|
||||
for (int i=0;i<loader_count;i++) {
|
||||
|
||||
if (!loader[i]->recognize(extension))
|
||||
continue;
|
||||
found=true;
|
||||
|
||||
Error err = loader[i]->load_import_metadata(local_path,ret);
|
||||
if (err==OK)
|
||||
|
|
|
@ -1788,7 +1788,7 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
|
|||
return UNZ_PARAMERROR;
|
||||
|
||||
|
||||
if ((pfile_in_zip_read_info->read_buffer == NULL))
|
||||
if (pfile_in_zip_read_info->read_buffer==NULL)
|
||||
return UNZ_END_OF_LIST_OF_FILE;
|
||||
if (len==0)
|
||||
return 0;
|
||||
|
|
|
@ -1114,9 +1114,9 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename,
|
|||
zi->ci.flag = flagBase;
|
||||
if ((level==8) || (level==9))
|
||||
zi->ci.flag |= 2;
|
||||
if ((level==2))
|
||||
if (level==2)
|
||||
zi->ci.flag |= 4;
|
||||
if ((level==1))
|
||||
if (level==1)
|
||||
zi->ci.flag |= 6;
|
||||
if (password != NULL)
|
||||
zi->ci.flag |= 1;
|
||||
|
|
|
@ -516,6 +516,7 @@ OS::OS() {
|
|||
_target_fps=0;
|
||||
_render_thread_mode=RENDER_THREAD_SAFE;
|
||||
_time_scale=1.0;
|
||||
_pixel_snap=false;
|
||||
Math::seed(1234567);
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ class OS {
|
|||
float _fps;
|
||||
int _target_fps;
|
||||
float _time_scale;
|
||||
bool _pixel_snap;
|
||||
|
||||
char *last_error;
|
||||
|
||||
|
@ -393,7 +394,7 @@ public:
|
|||
void set_time_scale(float p_scale);
|
||||
float get_time_scale() const;
|
||||
|
||||
|
||||
_FORCE_INLINE_ bool get_use_pixel_snap() const { return _pixel_snap; }
|
||||
|
||||
OS();
|
||||
virtual ~OS();
|
||||
|
|
|
@ -286,6 +286,37 @@ NodePath::NodePath(const Vector<StringName>& p_path,const Vector<StringName>& p_
|
|||
data->property=p_property;
|
||||
}
|
||||
|
||||
|
||||
void NodePath::simplify() {
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
for(int i=0;i<data->path.size();i++) {
|
||||
if (data->path.size()==1)
|
||||
break;
|
||||
if (data->path[i].operator String()==".") {
|
||||
data->path.remove(i);
|
||||
i--;
|
||||
} else if (data->path[i].operator String()==".." && i>0 && data->path[i-1].operator String()!="." && data->path[i-1].operator String()!="..") {
|
||||
//remove both
|
||||
data->path.remove(i-1);
|
||||
data->path.remove(i-1);
|
||||
i-=2;
|
||||
if (data->path.size()==0) {
|
||||
data->path.push_back(".");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NodePath NodePath::simplified() const {
|
||||
|
||||
NodePath np=*this;
|
||||
np.simplify();
|
||||
return np;
|
||||
}
|
||||
|
||||
NodePath::NodePath(const String& p_path) {
|
||||
|
||||
data=NULL;
|
||||
|
|
|
@ -84,7 +84,10 @@ public:
|
|||
bool operator==(const NodePath& p_path) const;
|
||||
bool operator!=(const NodePath& p_path) const;
|
||||
void operator=(const NodePath& p_path);
|
||||
|
||||
|
||||
void simplify();
|
||||
NodePath simplified() const;
|
||||
|
||||
NodePath(const Vector<StringName>& p_path,bool p_absolute,const String& p_property="");
|
||||
NodePath(const Vector<StringName>& p_path,const Vector<StringName>& p_subpath,bool p_absolute,const String& p_property="");
|
||||
NodePath(const NodePath& p_path);
|
||||
|
|
|
@ -130,7 +130,7 @@ public:
|
|||
void set_name(const String& p_name);
|
||||
String get_name() const;
|
||||
|
||||
void set_path(const String& p_path,bool p_take_over=false);
|
||||
virtual void set_path(const String& p_path,bool p_take_over=false);
|
||||
String get_path() const;
|
||||
|
||||
void set_subindex(int p_sub_index);
|
||||
|
|
|
@ -3066,7 +3066,7 @@ String String::world_wrap(int p_chars_per_line) const {
|
|||
} else if (operator[](i)==' ' || operator[](i)=='\t') {
|
||||
last_space=i;
|
||||
} else if (operator[](i)=='\n') {
|
||||
ret+=substr(from,i-from);
|
||||
ret+=substr(from,i-from)+"\n";
|
||||
from=i+1;
|
||||
last_space=-1;
|
||||
}
|
||||
|
|
|
@ -18,3 +18,11 @@ func _ready():
|
|||
# Initalization here
|
||||
pass
|
||||
|
||||
|
||||
|
||||
func _on_coin_area_enter( area ):
|
||||
pass # replace with function body
|
||||
|
||||
|
||||
func _on_coin_area_enter_shape( area_id, area, area_shape, area_shape ):
|
||||
pass # replace with function body
|
||||
|
|
1
demos/2d/platformer/tiles_demo.png.flags
Normal file
1
demos/2d/platformer/tiles_demo.png.flags
Normal file
|
@ -0,0 +1 @@
|
|||
filter=false
|
|
@ -5905,7 +5905,7 @@
|
|||
<description>
|
||||
Base class of anything 2D. Canvas items are laid out in a tree and children inherit and extend the transform of their parent. CanvasItem is extended by [Control], for anything GUI related, and by [Node2D] for anything 2D engine related.
|
||||
Any CanvasItem can draw. For this, the "update" function must be called, then NOTIFICATION_DRAW will be received on idle time to request redraw. Because of this, canvas items don't need to be redraw on every frame, improving the performance significan'tly. Several functions for drawing on the CanvasItem are provided (see draw_* functions). They can only be used inside the notification, signal or _draw() overrided function, though.
|
||||
Canvas items are draw in tree order. By default, children are on top of their parents so a root CanvasItem will be drawn behind everything (this can be changed per item though).
|
||||
Canvas items are draw in tree order. By default, children are on top of their parents so a root CanvasItem will be drawn behind everything (this can be changed per item though).
|
||||
Canvas items can also be hidden (hiding also their subtree). They provide many means for changing standard parameters such as opacity (for it and the subtree) and self opacity, blend mode.
|
||||
Ultimately, a transform notification can be requested, which will notify the node that its global position changed in case the parent tree changed.
|
||||
</description>
|
||||
|
@ -11556,8 +11556,11 @@
|
|||
</class>
|
||||
<class name="GraphEdit" inherits="Control" category="Core">
|
||||
<brief_description>
|
||||
GraphEdit is an area capable of showing various GraphNodes. It manages connection events between them.
|
||||
</brief_description>
|
||||
<description>
|
||||
GraphEdit manages the showing of GraphNodes it contains, as well as connections an disconnections between them. Signals are sent for each of these two events. Disconnection between GraphNodes slots is disabled by default.
|
||||
It is greatly advised to enable low processor usage mode [OS.set_low_processor_usage_mode()] when using GraphEdits.
|
||||
</description>
|
||||
<methods>
|
||||
<method name="connect_node">
|
||||
|
@ -11572,6 +11575,7 @@
|
|||
<argument index="3" name="to_port" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Create a connection between 'from_port' slot of 'from' GraphNode and 'to_port' slot of 'to' GraphNode. If the connection already exists, no connection is created.
|
||||
</description>
|
||||
</method>
|
||||
<method name="is_node_connected">
|
||||
|
@ -11586,6 +11590,7 @@
|
|||
<argument index="3" name="to_port" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Return true if the 'from_port' slot of 'from' GraphNode is connected to the 'to_port' slot of 'to' GraphNode.
|
||||
</description>
|
||||
</method>
|
||||
<method name="disconnect_node">
|
||||
|
@ -11598,24 +11603,28 @@
|
|||
<argument index="3" name="to_port" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Remove the connection between 'from_port' slot of 'from' GraphNode and 'to_port' slot of 'to' GraphNode, if connection exists.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_connection_list" qualifiers="const">
|
||||
<return type="Array">
|
||||
</return>
|
||||
<description>
|
||||
Return an Array containing the list of connections. A connection consists in a structure of the form {from_slot: 0, from: "GraphNode name 0", to_slot: 1, to: "GraphNode name 1" }
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_right_disconnects">
|
||||
<argument index="0" name="enable" type="bool">
|
||||
</argument>
|
||||
<description>
|
||||
Enable the disconnection of existing connections in the visual GraphEdit by left-clicking a connection and releasing into the void.
|
||||
</description>
|
||||
</method>
|
||||
<method name="is_right_disconnects_enabled" qualifiers="const">
|
||||
<return type="bool">
|
||||
</return>
|
||||
<description>
|
||||
Return true is the disconnection of connections is enable in the visual GraphEdit. False otherwise.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
|
@ -11630,6 +11639,7 @@
|
|||
<argument index="3" name="to_slot" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Signal sent to the GraphEdit when the connection between 'from_slot' slot of 'from' GraphNode and 'to_slot' slot of 'to' GraphNode is attempted to be removed.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="connection_request">
|
||||
|
@ -11642,6 +11652,7 @@
|
|||
<argument index="3" name="to_slot" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Signal sent to the GraphEdit when the connection between 'from_slot' slot of 'from' GraphNode and 'to_slot' slot of 'to' GraphNode is attempted to be created.
|
||||
</description>
|
||||
</signal>
|
||||
</signals>
|
||||
|
@ -11650,20 +11661,24 @@
|
|||
</class>
|
||||
<class name="GraphNode" inherits="Container" category="Core">
|
||||
<brief_description>
|
||||
A GraphNode is a container with several input and output slots allowing connections between GraphNodes. Slots can have different, incompatible types.
|
||||
</brief_description>
|
||||
<description>
|
||||
A GraphNode is a container defined by a title. It can have 1 or more input and output slots, which can be enabled (shown) or disabled (not shown) and have different (incompatible) types. Colors can also be assigned to slots. A tuple of input and output slots is defined for each GUI element included in the GraphNode. Input and output connections are left and right slots, but only enabled slots are counted as connections.
|
||||
</description>
|
||||
<methods>
|
||||
<method name="set_title">
|
||||
<argument index="0" name="title" type="String">
|
||||
</argument>
|
||||
<description>
|
||||
Set the title of the GraphNode.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_title" qualifiers="const">
|
||||
<return type="String">
|
||||
</return>
|
||||
<description>
|
||||
Return the title of the GraphNode.
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_slot">
|
||||
|
@ -11682,16 +11697,19 @@
|
|||
<argument index="6" name="color_right" type="Color">
|
||||
</argument>
|
||||
<description>
|
||||
Set the tuple of input/output slots defined by 'idx' ID. 'left' slots are input, 'right' are output. 'type' is an integer defining the type of the slot. Refer to description for the compatibility between slot types.
|
||||
</description>
|
||||
</method>
|
||||
<method name="clear_slot">
|
||||
<argument index="0" name="idx" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Disable input and ouput slot whose index is 'idx'.
|
||||
</description>
|
||||
</method>
|
||||
<method name="clear_all_slots">
|
||||
<description>
|
||||
Disable all input and output slots of the GraphNode.
|
||||
</description>
|
||||
</method>
|
||||
<method name="is_slot_enabled_left" qualifiers="const">
|
||||
|
@ -11700,6 +11718,7 @@
|
|||
<argument index="0" name="idx" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Return true if left (input) slot 'idx' is enabled. False otherwise.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_slot_type_left" qualifiers="const">
|
||||
|
@ -11708,6 +11727,7 @@
|
|||
<argument index="0" name="idx" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Return the (integer) type of left (input) 'idx' slot.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_slot_color_left" qualifiers="const">
|
||||
|
@ -11716,6 +11736,7 @@
|
|||
<argument index="0" name="idx" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Return the color set to 'idx' left (input) slot.
|
||||
</description>
|
||||
</method>
|
||||
<method name="is_slot_enabled_right" qualifiers="const">
|
||||
|
@ -11724,6 +11745,7 @@
|
|||
<argument index="0" name="idx" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Return true if right (output) slot 'idx' is enabled. False otherwise.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_slot_type_right" qualifiers="const">
|
||||
|
@ -11732,6 +11754,7 @@
|
|||
<argument index="0" name="idx" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Return the (integer) type of right (output) 'idx' slot.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_slot_color_right" qualifiers="const">
|
||||
|
@ -11740,30 +11763,35 @@
|
|||
<argument index="0" name="idx" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Return the color set to 'idx' right (output) slot.
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_offset">
|
||||
<argument index="0" name="offset" type="Vector2">
|
||||
</argument>
|
||||
<description>
|
||||
Set the offset of the GraphNode.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_offset" qualifiers="const">
|
||||
<return type="Vector2">
|
||||
</return>
|
||||
<description>
|
||||
Return the offset of the GraphNode.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_connection_output_count">
|
||||
<return type="int">
|
||||
</return>
|
||||
<description>
|
||||
Return the number of enabled output slots (connections) of the GraphNode.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_connection_input_count">
|
||||
<return type="int">
|
||||
</return>
|
||||
<description>
|
||||
Return the number of enabled input slots (connections) to the GraphNode.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_connection_output_pos">
|
||||
|
@ -11772,6 +11800,7 @@
|
|||
<argument index="0" name="idx" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Return the position of the output connection 'idx'.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_connection_output_type">
|
||||
|
@ -11780,6 +11809,7 @@
|
|||
<argument index="0" name="idx" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Return the type of the output connection 'idx'.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_connection_output_color">
|
||||
|
@ -11788,6 +11818,7 @@
|
|||
<argument index="0" name="idx" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Return the color of the output connection 'idx'.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_connection_input_pos">
|
||||
|
@ -11796,6 +11827,7 @@
|
|||
<argument index="0" name="idx" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Return the position of the input connection 'idx'.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_connection_input_type">
|
||||
|
@ -11804,6 +11836,7 @@
|
|||
<argument index="0" name="idx" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Return the type of the input connection 'idx'.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_connection_input_color">
|
||||
|
@ -11812,28 +11845,33 @@
|
|||
<argument index="0" name="idx" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Return the color of the input connection 'idx'.
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_show_close_button">
|
||||
<argument index="0" name="show" type="bool">
|
||||
</argument>
|
||||
<description>
|
||||
Show the close button on the GraphNode if 'show' is true (disabled by default). If enabled, a connection on the signal close_request is needed for the close button to work.
|
||||
</description>
|
||||
</method>
|
||||
<method name="is_close_button_visible" qualifiers="const">
|
||||
<return type="bool">
|
||||
</return>
|
||||
<description>
|
||||
Returns true if the close button is shown. False otherwise.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
<signals>
|
||||
<signal name="raise_request">
|
||||
<description>
|
||||
Signal sent when the GraphNode is requested to be displayed over other ones. Happens on focusing (clicking into) the GraphNode.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="close_request">
|
||||
<description>
|
||||
Signal sent on closing the GraphNode.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="dragged">
|
||||
|
@ -11842,10 +11880,12 @@
|
|||
<argument index="1" name="to" type="Vector2">
|
||||
</argument>
|
||||
<description>
|
||||
Signal sent when the GraphNode is dragged.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="offset_changed">
|
||||
<description>
|
||||
Signal sent when the GraphNode is moved.
|
||||
</description>
|
||||
</signal>
|
||||
</signals>
|
||||
|
@ -17934,7 +17974,7 @@
|
|||
</brief_description>
|
||||
<description>
|
||||
Nodes can be set as children of other nodes, resulting in a tree arrangement. Any tree of nodes is called a "Scene".
|
||||
Scenes can be saved to disk, and then instanced into other scenes. This allows for very high flexibility in the architecture and data model of the projects.
|
||||
Scenes can be saved to disk, and then instanced into other scenes. This allows for very high flexibility in the architecture and data model of the projects.
|
||||
[SceneMainLoop] contains the "active" tree of nodes, and a node becomes active (receinving NOTIFICATION_ENTER_SCENE) when added to that tree.
|
||||
A node can contain any number of nodes as a children (but there is only one tree root) with the requirement that no two childrens with the same name can exist.
|
||||
Nodes can, optionally, be added to groups. This makes it easy to reach a number of nodes from the code (for example an "enemies" group).
|
||||
|
@ -18684,11 +18724,11 @@
|
|||
<description>
|
||||
Operating System functions. OS Wraps the most common functionality to communicate with the host Operating System, such as:
|
||||
-Mouse Grabbing
|
||||
-Mouse Cursors
|
||||
-Mouse Cursors
|
||||
-Clipboard
|
||||
-Video Mode
|
||||
-Date " Time
|
||||
-Timers
|
||||
-Timers
|
||||
-Environment Variables
|
||||
-Execution of Binaries
|
||||
-Command Line
|
||||
|
@ -27567,7 +27607,7 @@
|
|||
Rigid body 2D node.
|
||||
</brief_description>
|
||||
<description>
|
||||
Rigid body 2D node. This node is used for placing rigid bodies in the scene. It can contain a number of shapes, and also shift state between regular Rigid Body to Character or even Static.
|
||||
Rigid body 2D node. This node is used for placing rigid bodies in the scene. It can contain a number of shapes, and also shift state between regular Rigid Body to Character or even Static.
|
||||
Character mode forbids the node from being rotated. This node can have a custom force integrator function, for writing complex physics motion behavior per node.
|
||||
As a warning, don't change this node position every frame or very often. Sporadic changes work fine, but physics runs at a different granularity (fixed hz) than usual rendering (process callback) and maybe even in a separate thread, so changing this from a process loop will yield strange behavior.
|
||||
</description>
|
||||
|
@ -37719,6 +37759,18 @@
|
|||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_audio_track">
|
||||
<argument index="0" name="track" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_audio_track" qualifiers="const">
|
||||
<return type="int">
|
||||
</return>
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_stream_name" qualifiers="const">
|
||||
<return type="String">
|
||||
</return>
|
||||
|
@ -37755,6 +37807,18 @@
|
|||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_buffering_msec">
|
||||
<argument index="0" name="msec" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_buffering_msec" qualifiers="const">
|
||||
<return type="int">
|
||||
</return>
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
<constants>
|
||||
</constants>
|
||||
|
@ -37765,30 +37829,16 @@
|
|||
<description>
|
||||
</description>
|
||||
<methods>
|
||||
<method name="get_pending_frame_count" qualifiers="const">
|
||||
<return type="int">
|
||||
</return>
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="pop_frame">
|
||||
<argument index="0" name="arg0" type="Object">
|
||||
</argument>
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="peek_frame" qualifiers="const">
|
||||
<return type="Image">
|
||||
</return>
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_audio_track">
|
||||
<argument index="0" name="idx" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
<constants>
|
||||
</constants>
|
||||
</class>
|
||||
<class name="VideoStreamTheora" inherits="VideoStream" category="Core">
|
||||
<brief_description>
|
||||
</brief_description>
|
||||
<description>
|
||||
</description>
|
||||
<methods>
|
||||
</methods>
|
||||
<constants>
|
||||
</constants>
|
||||
|
|
|
@ -4145,7 +4145,7 @@ void RasterizerGLES2::begin_frame() {
|
|||
|
||||
//fragment_lighting=Globals::get_singleton()->get("rasterizer/use_fragment_lighting");
|
||||
#ifdef TOOLS_ENABLED
|
||||
canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP,GLOBAL_DEF("rasterizer/use_pixel_snap",false));
|
||||
canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP,GLOBAL_DEF("display/use_2d_pixel_snap",false));
|
||||
shadow_filter=ShadowFilterTechnique(int(Globals::get_singleton()->get("rasterizer/shadow_filter")));
|
||||
#endif
|
||||
|
||||
|
@ -10807,7 +10807,7 @@ void RasterizerGLES2::init() {
|
|||
copy_shader.set_conditional(CopyShaderGLES2::USE_8BIT_HDR,!use_fp16_fb);
|
||||
canvas_shader.set_conditional(CanvasShaderGLES2::USE_DEPTH_SHADOWS,read_depth_supported);
|
||||
|
||||
canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP,GLOBAL_DEF("rasterizer/use_pixel_snap",false));
|
||||
canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP,GLOBAL_DEF("display/use_2d_pixel_snap",false));
|
||||
|
||||
npo2_textures_available=true;
|
||||
//fragment_lighting=false;
|
||||
|
|
|
@ -29,7 +29,7 @@ extern "C" {
|
|||
#define WEBP_USE_SSE2
|
||||
#endif
|
||||
|
||||
#if defined(__ANDROID__) && defined(__ARM_ARCH_7A__)
|
||||
#if defined(__ANDROID__) && defined(__ARM_ARCH_7A__) && defined(__ARM_NEON__)
|
||||
#define WEBP_ANDROID_NEON // Android targets that might support NEON
|
||||
#endif
|
||||
|
||||
|
|
|
@ -701,6 +701,7 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
|
|||
GLOBAL_DEF("display/resizable",video_mode.resizable);
|
||||
GLOBAL_DEF("display/test_width",0);
|
||||
GLOBAL_DEF("display/test_height",0);
|
||||
OS::get_singleton()->_pixel_snap=GLOBAL_DEF("display/use_2d_pixel_snap",false);
|
||||
if (rtm==-1) {
|
||||
rtm=GLOBAL_DEF("render/thread_model",OS::RENDER_THREAD_SAFE);
|
||||
if (rtm>=1) //hack for now
|
||||
|
@ -1006,61 +1007,49 @@ bool Main::start() {
|
|||
bool export_debug=false;
|
||||
List<String> args = OS::get_singleton()->get_cmdline_args();
|
||||
for (int i=0;i<args.size();i++) {
|
||||
|
||||
|
||||
if (args[i]=="-doctool" && i <(args.size()-1)) {
|
||||
|
||||
doc_tool=args[i+1];
|
||||
//parameters that have an argument to the right
|
||||
if (i < (args.size()-1)) {
|
||||
if (args[i]=="-doctool") {
|
||||
doc_tool=args[i+1];
|
||||
} else if (args[i]=="-script" || args[i]=="-s") {
|
||||
script=args[i+1];
|
||||
} else if (args[i]=="-level" || args[i]=="-l") {
|
||||
OS::get_singleton()->_custom_level=args[i+1];
|
||||
} else if (args[i]=="-test") {
|
||||
test=args[i+1];
|
||||
} else if (args[i]=="-optimize") {
|
||||
optimize=args[i+1];
|
||||
} else if (args[i]=="-optimize_preset") {
|
||||
optimize_preset=args[i+1];
|
||||
} else if (args[i]=="-export") {
|
||||
editor=true; //needs editor
|
||||
_export_platform=args[i+1];
|
||||
} else if (args[i]=="-export_debug") {
|
||||
editor=true; //needs editor
|
||||
_export_platform=args[i+1];
|
||||
export_debug=true;
|
||||
} else if (args[i]=="-import") {
|
||||
editor=true; //needs editor
|
||||
_import=args[i+1];
|
||||
} else if (args[i]=="-import_script") {
|
||||
editor=true; //needs editor
|
||||
_import_script=args[i+1];
|
||||
} else if (args[i]=="-dumpstrings") {
|
||||
editor=true; //needs editor
|
||||
dumpstrings=args[i+1];
|
||||
}
|
||||
i++;
|
||||
}else if (args[i]=="-nodocbase") {
|
||||
|
||||
}
|
||||
//parameters that do not have an argument to the right
|
||||
if (args[i]=="-nodocbase") {
|
||||
doc_base=false;
|
||||
} else if ((args[i]=="-script" || args[i]=="-s") && i <(args.size()-1)) {
|
||||
|
||||
script=args[i+1];
|
||||
i++;
|
||||
} else if ((args[i]=="-level" || args[i]=="-l") && i <(args.size()-1)) {
|
||||
|
||||
OS::get_singleton()->_custom_level=args[i+1];
|
||||
i++;
|
||||
} else if (args[i]=="-test" && i <(args.size()-1)) {
|
||||
test=args[i+1];
|
||||
i++;
|
||||
} else if (args[i]=="-optimize" && i <(args.size()-1)) {
|
||||
optimize=args[i+1];
|
||||
i++;
|
||||
} else if (args[i]=="-optimize_preset" && i <(args.size()-1)) {
|
||||
optimize_preset=args[i+1];
|
||||
i++;
|
||||
} else if (args[i]=="-export" && i <(args.size()-1)) {
|
||||
editor=true; //needs editor
|
||||
_export_platform=args[i+1];
|
||||
i++;
|
||||
} else if (args[i]=="-export_debug" && i <(args.size()-1)) {
|
||||
editor=true; //needs editor
|
||||
_export_platform=args[i+1];
|
||||
export_debug=true;
|
||||
i++;
|
||||
} else if (args[i]=="-import" && i <(args.size()-1)) {
|
||||
editor=true; //needs editor
|
||||
_import=args[i+1];
|
||||
i++;
|
||||
} else if (args[i]=="-import_script" && i <(args.size()-1)) {
|
||||
editor=true; //needs editor
|
||||
_import_script=args[i+1];
|
||||
i++;
|
||||
} else if (args[i]=="-noquit" ) {
|
||||
} else if (args[i]=="-noquit") {
|
||||
noquit=true;
|
||||
} else if (args[i]=="-dumpstrings" && i <(args.size()-1)) {
|
||||
editor=true; //needs editor
|
||||
dumpstrings=args[i+1];
|
||||
i++;
|
||||
} else if (args[i]=="-editor" || args[i]=="-e") {
|
||||
editor=true;
|
||||
} else if (args[i]=="-convert_old") {
|
||||
convert_old=true;
|
||||
} else if (args[i]=="-editor" || args[i]=="-e") {
|
||||
editor=true;
|
||||
} else if (args[i].length() && args[i][0] != '-' && game_path == "") {
|
||||
|
||||
game_path=args[i];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -904,6 +904,15 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
|
|||
|
||||
r_ret = gdscr->_new(NULL,0,r_error);
|
||||
|
||||
GDInstance *ins = static_cast<GDInstance*>(static_cast<Object*>(r_ret)->get_script_instance());
|
||||
Ref<GDScript> gd_ref = ins->get_script();
|
||||
|
||||
for(Map<StringName,GDScript::MemberInfo>::Element *E = gd_ref->member_indices.front(); E; E = E->next()) {
|
||||
if(d.has(E->key())) {
|
||||
ins->members[E->get().index] = d[E->key()];
|
||||
}
|
||||
}
|
||||
|
||||
} break;
|
||||
case HASH: {
|
||||
|
||||
|
|
|
@ -2421,6 +2421,16 @@ void GDParser::_parse_class(ClassNode *p_class) {
|
|||
}; //fallthrough to use the same
|
||||
case Variant::REAL: {
|
||||
|
||||
if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier()=="EASE") {
|
||||
current_export.hint=PROPERTY_HINT_EXP_EASING;
|
||||
tokenizer->advance();
|
||||
if (tokenizer->get_token()!=GDTokenizer::TK_PARENTHESIS_CLOSE) {
|
||||
_set_error("Expected ')' in hint.");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
float sign=1.0;
|
||||
|
||||
if (tokenizer->get_token()==GDTokenizer::TK_OP_SUB) {
|
||||
|
@ -2571,6 +2581,17 @@ void GDParser::_parse_class(ClassNode *p_class) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier()=="MULTILINE") {
|
||||
|
||||
current_export.hint=PROPERTY_HINT_MULTILINE_TEXT;
|
||||
tokenizer->advance();
|
||||
if (tokenizer->get_token()!=GDTokenizer::TK_PARENTHESIS_CLOSE) {
|
||||
_set_error("Expected ')' in hint.");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
case Variant::COLOR: {
|
||||
|
||||
|
@ -2607,23 +2628,16 @@ void GDParser::_parse_class(ClassNode *p_class) {
|
|||
} else if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER) {
|
||||
|
||||
String identifier = tokenizer->get_token_identifier();
|
||||
if (identifier == "flag") {
|
||||
current_export.type=Variant::INT;
|
||||
current_export.hint=PROPERTY_HINT_ALL_FLAGS;
|
||||
}else if (identifier == "multiline"){
|
||||
current_export.type=Variant::STRING;
|
||||
current_export.hint=PROPERTY_HINT_MULTILINE_TEXT;
|
||||
} else {
|
||||
if (!ObjectTypeDB::is_type(identifier,"Resource")) {
|
||||
|
||||
current_export=PropertyInfo();
|
||||
_set_error("Export hint not a type or resource.");
|
||||
}
|
||||
|
||||
current_export.type=Variant::OBJECT;
|
||||
current_export.hint=PROPERTY_HINT_RESOURCE_TYPE;
|
||||
current_export.hint_string=identifier;
|
||||
if (!ObjectTypeDB::is_type(identifier,"Resource")) {
|
||||
|
||||
current_export=PropertyInfo();
|
||||
_set_error("Export hint not a type or resource.");
|
||||
}
|
||||
|
||||
current_export.type=Variant::OBJECT;
|
||||
current_export.hint=PROPERTY_HINT_RESOURCE_TYPE;
|
||||
current_export.hint_string=identifier;
|
||||
|
||||
tokenizer->advance();
|
||||
}
|
||||
|
||||
|
|
|
@ -236,13 +236,12 @@ void AudioDriverOpenSL::start(){
|
|||
|
||||
ERR_FAIL_COND( res !=SL_RESULT_SUCCESS );
|
||||
/* Initialize arrays required[] and iidArray[] */
|
||||
int i;
|
||||
SLboolean required[MAX_NUMBER_INTERFACES];
|
||||
SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
|
||||
|
||||
#if 0
|
||||
|
||||
for (i=0; i<MAX_NUMBER_INTERFACES; i++)
|
||||
for (int i=0; i<MAX_NUMBER_INTERFACES; i++)
|
||||
{
|
||||
required[i] = SL_BOOLEAN_FALSE;
|
||||
iidArray[i] = SL_IID_NULL;
|
||||
|
|
|
@ -127,7 +127,7 @@ static __inline__ void x86_cpuid(int func, int values[4])
|
|||
static int
|
||||
get_file_size(const char* pathname)
|
||||
{
|
||||
int fd, ret, result = 0;
|
||||
int fd, result = 0;
|
||||
char buffer[256];
|
||||
|
||||
fd = open(pathname, O_RDONLY);
|
||||
|
|
|
@ -20,15 +20,14 @@ def can_build():
|
|||
def get_opts():
|
||||
|
||||
return [
|
||||
('ANDROID_NDK_ROOT', 'the path to Android NDK', os.environ.get("ANDROID_NDK_ROOT", 0)),
|
||||
('NDK_TOOLCHAIN', 'toolchain to use for the NDK',"arm-eabi-4.4.0"),
|
||||
#android 2.3
|
||||
('ndk_platform', 'compile for platform: (2.2,2.3)',"2.2"),
|
||||
('NDK_TARGET', 'toolchain to use for the NDK',"arm-linux-androideabi-4.8"),
|
||||
('android_stl','enable STL support in android port (for modules)','no'),
|
||||
('armv6','compile for older phones running arm v6 (instead of v7+neon+smp)','no'),
|
||||
('x86','Xompile for Android-x86','no')
|
||||
|
||||
('ANDROID_NDK_ROOT', 'the path to Android NDK', os.environ.get("ANDROID_NDK_ROOT", 0)),
|
||||
('NDK_TOOLCHAIN', 'toolchain to use for the NDK',"arm-eabi-4.4.0"),
|
||||
('NDK_TARGET', 'toolchain to use for the NDK',"arm-linux-androideabi-4.8"),
|
||||
('NDK_TARGET_X86', 'toolchain to use for the NDK x86',"x86-4.8"),
|
||||
('ndk_platform', 'compile for platform: (android-<api> , example: android-15)',"android-15"),
|
||||
('android_arch', 'select compiler architecture: (armv7/armv6/x86)',"armv7"),
|
||||
('android_neon','enable neon (armv7 only)',"yes"),
|
||||
('android_stl','enable STL support in android port (for modules)',"no")
|
||||
]
|
||||
|
||||
def get_flags():
|
||||
|
@ -92,8 +91,13 @@ def configure(env):
|
|||
|
||||
env['SPAWN'] = mySpawn
|
||||
|
||||
if env['x86']=='yes':
|
||||
env['NDK_TARGET']='x86-4.8'
|
||||
ndk_platform=env['ndk_platform']
|
||||
|
||||
if env['android_arch'] not in ['armv7','armv6','x86']:
|
||||
env['android_arch']='armv7'
|
||||
|
||||
if env['android_arch']=='x86':
|
||||
env['NDK_TARGET']=env['NDK_TARGET_X86']
|
||||
|
||||
if env['PLATFORM'] == 'win32':
|
||||
import methods
|
||||
|
@ -101,22 +105,28 @@ def configure(env):
|
|||
#env['SPAWN'] = methods.win32_spawn
|
||||
env['SHLIBSUFFIX'] = '.so'
|
||||
|
||||
# env.android_source_modules.append("../libs/apk_expansion")
|
||||
#env.android_source_modules.append("../libs/apk_expansion")
|
||||
env.android_source_modules.append("../libs/google_play_services")
|
||||
env.android_source_modules.append("../libs/downloader_library")
|
||||
env.android_source_modules.append("../libs/play_licensing")
|
||||
|
||||
ndk_platform=""
|
||||
|
||||
ndk_platform="android-15"
|
||||
|
||||
print("Godot Android!!!!!")
|
||||
neon_text=""
|
||||
if env["android_arch"]=="armv7" and env['android_neon']=='yes':
|
||||
neon_text=" (with neon)"
|
||||
print("Godot Android!!!!! ("+env['android_arch']+")"+neon_text)
|
||||
|
||||
env.Append(CPPPATH=['#platform/android'])
|
||||
|
||||
if env['x86']=='yes':
|
||||
env.extra_suffix=".x86"
|
||||
|
||||
if env['android_arch']=='x86':
|
||||
env.extra_suffix=".x86"+env.extra_suffix
|
||||
elif env['android_arch']=='armv6':
|
||||
env.extra_suffix=".armv6"+env.extra_suffix
|
||||
elif env["android_arch"]=="armv7":
|
||||
if env['android_neon']=='yes':
|
||||
env.extra_suffix=".armv7.neon"+env.extra_suffix
|
||||
else:
|
||||
env.extra_suffix=".armv7"+env.extra_suffix
|
||||
|
||||
gcc_path=env["ANDROID_NDK_ROOT"]+"/toolchains/"+env["NDK_TARGET"]+"/prebuilt/";
|
||||
|
||||
import os
|
||||
|
@ -134,7 +144,7 @@ def configure(env):
|
|||
|
||||
|
||||
env['ENV']['PATH'] = gcc_path+":"+env['ENV']['PATH']
|
||||
if env['x86']=='yes':
|
||||
if env['android_arch']=='x86':
|
||||
env['CC'] = gcc_path+'/i686-linux-android-gcc'
|
||||
env['CXX'] = gcc_path+'/i686-linux-android-g++'
|
||||
env['AR'] = gcc_path+"/i686-linux-android-ar"
|
||||
|
@ -147,7 +157,7 @@ def configure(env):
|
|||
env['RANLIB'] = gcc_path+"/arm-linux-androideabi-ranlib"
|
||||
env['AS'] = gcc_path+"/arm-linux-androideabi-as"
|
||||
|
||||
if env['x86']=='yes':
|
||||
if env['android_arch']=='x86':
|
||||
env['ARCH'] = 'arch-x86'
|
||||
else:
|
||||
env['ARCH'] = 'arch-arm'
|
||||
|
@ -161,12 +171,18 @@ def configure(env):
|
|||
env.Append(CPPPATH=[gcc_include])
|
||||
# env['CCFLAGS'] = string.split('-DNO_THREADS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -fno-exceptions -mthumb -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED ')
|
||||
|
||||
if env['x86']=='yes':
|
||||
env['neon_enabled']=False
|
||||
if env['android_arch']=='x86':
|
||||
env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__GLIBC__ -Wno-psabi -ftree-vectorize -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED')
|
||||
elif env["armv6"]!="no":
|
||||
elif env["android_arch"]=="armv6":
|
||||
env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__ARM_ARCH_6__ -D__GLIBC__ -Wno-psabi -march=armv6 -mfpu=vfp -mfloat-abi=softfp -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED')
|
||||
else:
|
||||
env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__ARM_ARCH_7__ -D__GLIBC__ -Wno-psabi -march=armv6 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED')
|
||||
elif env["android_arch"]=="armv7":
|
||||
env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__ARM_ARCH_7__ -D__ARM_ARCH_7A__ -D__GLIBC__ -Wno-psabi -march=armv7-a -mfloat-abi=softfp -ftree-vectorize -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED')
|
||||
if env['android_neon']=='yes':
|
||||
env['neon_enabled']=True
|
||||
env.Append(CCFLAGS=['-mfpu=neon','-D__ARM_NEON__'])
|
||||
else:
|
||||
env.Append(CCFLAGS=['-mfpu=vfpv3-d16'])
|
||||
|
||||
env.Append(LDPATH=[ld_path])
|
||||
env.Append(LIBS=['OpenSLES'])
|
||||
|
@ -190,9 +206,6 @@ def configure(env):
|
|||
env.Append(CCFLAGS=['-D_DEBUG', '-g1', '-Wall', '-O0', '-DDEBUG_ENABLED'])
|
||||
env.Append(CPPFLAGS=['-DDEBUG_MEMORY_ALLOC'])
|
||||
|
||||
if env["armv6"] == "no" and env['x86'] != 'yes':
|
||||
env['neon_enabled']=True
|
||||
|
||||
env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED', '-DNO_FCNTL','-DMPC_FIXED_POINT'])
|
||||
# env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED','-DMPC_FIXED_POINT'])
|
||||
|
||||
|
@ -202,9 +215,17 @@ def configure(env):
|
|||
|
||||
if (env['android_stl']=='yes'):
|
||||
#env.Append(CCFLAGS=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/system/include"])
|
||||
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.4.3/include"])
|
||||
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.4.3/libs/armeabi/include"])
|
||||
env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.4.3/libs/armeabi"])
|
||||
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/include"])
|
||||
if env['android_arch']=='x86':
|
||||
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/x86/include"])
|
||||
env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/x86"])
|
||||
elif env['android_arch']=='armv6':
|
||||
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi/include"])
|
||||
env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi"])
|
||||
elif env["android_arch"]=="armv7":
|
||||
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include"])
|
||||
env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a"])
|
||||
|
||||
env.Append(LIBS=["gnustl_static","supc++"])
|
||||
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cpufeatures"])
|
||||
|
||||
|
@ -215,10 +236,12 @@ def configure(env):
|
|||
|
||||
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/include"])
|
||||
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cpufeatures"])
|
||||
if env['x86']=='yes':
|
||||
if env['android_arch']=='x86':
|
||||
env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/libs/x86"])
|
||||
else:
|
||||
elif env["android_arch"]=="armv6":
|
||||
env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/libs/armeabi"])
|
||||
elif env["android_arch"]=="armv7":
|
||||
env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/libs/armeabi-v7a"])
|
||||
env.Append(LIBS=['gabi++_static'])
|
||||
env.Append(CCFLAGS=["-fno-exceptions",'-DNO_SAFE_CAST'])
|
||||
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
/** Automatically generated file. DO NOT MODIFY */
|
||||
package com.android.vending.expansion.downloader;
|
||||
|
||||
public final class BuildConfig {
|
||||
public final static boolean DEBUG = false;
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
/* AUTO-GENERATED FILE. DO NOT MODIFY.
|
||||
*
|
||||
* This class was automatically generated by the
|
||||
* aapt tool from the resource data it found. It
|
||||
* should not be modified by hand.
|
||||
*/
|
||||
|
||||
package com.android.vending.expansion.downloader;
|
||||
|
||||
public final class R {
|
||||
public static final class attr {
|
||||
}
|
||||
public static final class drawable {
|
||||
public static int notify_panel_notification_icon_bg=0x7f020000;
|
||||
}
|
||||
public static final class id {
|
||||
public static int appIcon=0x7f060001;
|
||||
public static int description=0x7f060007;
|
||||
public static int notificationLayout=0x7f060000;
|
||||
public static int progress_bar=0x7f060006;
|
||||
public static int progress_bar_frame=0x7f060005;
|
||||
public static int progress_text=0x7f060002;
|
||||
public static int time_remaining=0x7f060004;
|
||||
public static int title=0x7f060003;
|
||||
}
|
||||
public static final class layout {
|
||||
public static int status_bar_ongoing_event_progress_bar=0x7f030000;
|
||||
}
|
||||
public static final class string {
|
||||
public static int kilobytes_per_second=0x7f040014;
|
||||
/** When a download completes, a notification is displayed, and this
|
||||
string is used to indicate that the download successfully completed.
|
||||
Note that such a download could have been initiated by a variety of
|
||||
applications, including (but not limited to) the browser, an email
|
||||
application, a content marketplace.
|
||||
*/
|
||||
public static int notification_download_complete=0x7f040000;
|
||||
/** When a download completes, a notification is displayed, and this
|
||||
string is used to indicate that the download failed.
|
||||
Note that such a download could have been initiated by a variety of
|
||||
applications, including (but not limited to) the browser, an email
|
||||
application, a content marketplace.
|
||||
*/
|
||||
public static int notification_download_failed=0x7f040001;
|
||||
public static int state_completed=0x7f040007;
|
||||
public static int state_connecting=0x7f040005;
|
||||
public static int state_downloading=0x7f040006;
|
||||
public static int state_failed=0x7f040013;
|
||||
public static int state_failed_cancelled=0x7f040012;
|
||||
public static int state_failed_fetching_url=0x7f040010;
|
||||
public static int state_failed_sdcard_full=0x7f040011;
|
||||
public static int state_failed_unlicensed=0x7f04000f;
|
||||
public static int state_fetching_url=0x7f040004;
|
||||
public static int state_idle=0x7f040003;
|
||||
public static int state_paused_by_request=0x7f04000a;
|
||||
public static int state_paused_network_setup_failure=0x7f040009;
|
||||
public static int state_paused_network_unavailable=0x7f040008;
|
||||
public static int state_paused_roaming=0x7f04000d;
|
||||
public static int state_paused_sdcard_unavailable=0x7f04000e;
|
||||
public static int state_paused_wifi_disabled=0x7f04000c;
|
||||
public static int state_paused_wifi_unavailable=0x7f04000b;
|
||||
public static int state_unknown=0x7f040002;
|
||||
public static int time_remaining=0x7f040015;
|
||||
public static int time_remaining_notification=0x7f040016;
|
||||
}
|
||||
public static final class style {
|
||||
public static int ButtonBackground=0x7f050003;
|
||||
public static int NotificationText=0x7f050000;
|
||||
public static int NotificationTextSecondary=0x7f050004;
|
||||
public static int NotificationTextShadow=0x7f050001;
|
||||
public static int NotificationTitle=0x7f050002;
|
||||
}
|
||||
}
|
|
@ -53,7 +53,6 @@ Error AudioDriverBB10::init(const char* p_name) {
|
|||
dev_name = (char *) p_name;
|
||||
}
|
||||
printf("******** reconnecting to device %s\n", dev_name);
|
||||
int card, dev;
|
||||
int ret = snd_pcm_open_name(&pcm_handle, dev_name, SND_PCM_OPEN_PLAYBACK);
|
||||
ERR_FAIL_COND_V(ret < 0, FAILED);
|
||||
pcm_open = true;
|
||||
|
|
|
@ -157,6 +157,8 @@ public:
|
|||
Error shell_open(String p_uri);
|
||||
void push_input(const InputEvent& p_event);
|
||||
|
||||
String get_locale() const;
|
||||
|
||||
virtual void set_video_mode(const VideoMode& p_video_mode,int p_screen=0);
|
||||
virtual VideoMode get_video_mode(int p_screen=0) const;
|
||||
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const;
|
||||
|
|
|
@ -1254,6 +1254,11 @@ Error OS_OSX::shell_open(String p_uri) {
|
|||
return OK;
|
||||
}
|
||||
|
||||
String OS_OSX::get_locale() const {
|
||||
NSString* preferredLang = [[NSLocale preferredLanguages] objectAtIndex:0];
|
||||
return [preferredLang UTF8String];
|
||||
}
|
||||
|
||||
void OS_OSX::swap_buffers() {
|
||||
|
||||
[context flushBuffer];
|
||||
|
|
|
@ -79,6 +79,13 @@ Error TCPServerWinsock::listen(uint16_t p_port,const List<String> *p_accepted_ho
|
|||
my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP TODO: use p_accepted_hosts
|
||||
memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero);
|
||||
|
||||
int reuse=1;
|
||||
if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0) {
|
||||
|
||||
printf("REUSEADDR failed!");
|
||||
}
|
||||
|
||||
|
||||
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof my_addr) != SOCKET_ERROR) {
|
||||
|
||||
if (::listen(sockfd, SOMAXCONN) == SOCKET_ERROR) {
|
||||
|
|
|
@ -892,7 +892,13 @@ void OS_X11::set_window_maximized(bool p_enabled) {
|
|||
|
||||
XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
|
||||
|
||||
XWindowAttributes xwa;
|
||||
XGetWindowAttributes(x11_display,DefaultRootWindow(x11_display),&xwa);
|
||||
current_videomode.width = xwa.width;
|
||||
current_videomode.height = xwa.height;
|
||||
|
||||
maximized = p_enabled;
|
||||
visual_server->init();
|
||||
}
|
||||
|
||||
bool OS_X11::is_window_maximized() const {
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
/*************************************************************************/
|
||||
#include "animated_sprite.h"
|
||||
#include "scene/scene_string_names.h"
|
||||
#include "os/os.h"
|
||||
|
||||
void AnimatedSprite::edit_set_pivot(const Point2& p_pivot) {
|
||||
|
||||
set_offset(p_pivot);
|
||||
|
@ -153,6 +155,9 @@ void AnimatedSprite::_notification(int p_what) {
|
|||
if (centered)
|
||||
ofs-=s/2;
|
||||
|
||||
if (OS::get_singleton()->get_use_pixel_snap()) {
|
||||
ofs=ofs.floor();
|
||||
}
|
||||
Rect2 dst_rect(ofs,s);
|
||||
|
||||
if (hflip)
|
||||
|
|
|
@ -126,7 +126,7 @@ void Joint2D::_bind_methods() {
|
|||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::NODE_PATH, "node_a"), _SCS("set_node_a"),_SCS("get_node_a") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::NODE_PATH, "node_b"), _SCS("set_node_b"),_SCS("get_node_b") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::REAL, "bias/bias",PROPERTY_HINT_RANGE,"0,0.9,0.01"), _SCS("set_bias"),_SCS("get_bias") );
|
||||
ADD_PROPERTY( PropertyInfo( Variant::REAL, "bias/bias",PROPERTY_HINT_RANGE,"0,0.9,0.001"), _SCS("set_bias"),_SCS("get_bias") );
|
||||
|
||||
}
|
||||
|
||||
|
@ -175,15 +175,37 @@ RID PinJoint2D::_configure_joint() {
|
|||
//add a collision exception between both
|
||||
Physics2DServer::get_singleton()->body_add_collision_exception(body_a->get_rid(),body_b->get_rid());
|
||||
}
|
||||
|
||||
return Physics2DServer::get_singleton()->pin_joint_create(get_global_transform().get_origin(),body_a->get_rid(),body_b?body_b->get_rid():RID());
|
||||
RID pj = Physics2DServer::get_singleton()->pin_joint_create(get_global_transform().get_origin(),body_a->get_rid(),body_b?body_b->get_rid():RID());
|
||||
Physics2DServer::get_singleton()->pin_joint_set_param(pj, Physics2DServer::PIN_JOINT_SOFTNESS, softness);
|
||||
return pj;
|
||||
|
||||
}
|
||||
|
||||
void PinJoint2D::set_softness(real_t p_softness) {
|
||||
|
||||
softness=p_softness;
|
||||
update();
|
||||
if (get_joint().is_valid())
|
||||
Physics2DServer::get_singleton()->pin_joint_set_param(get_joint(), Physics2DServer::PIN_JOINT_SOFTNESS, p_softness);
|
||||
|
||||
}
|
||||
|
||||
real_t PinJoint2D::get_softness() const {
|
||||
|
||||
return softness;
|
||||
}
|
||||
|
||||
void PinJoint2D::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_softness","softness"), &PinJoint2D::set_softness);
|
||||
ObjectTypeDB::bind_method(_MD("get_softness"), &PinJoint2D::get_softness);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::REAL, "softness", PROPERTY_HINT_EXP_RANGE,"0.00,16,0.01"), _SCS("set_softness"), _SCS("get_softness"));
|
||||
}
|
||||
|
||||
PinJoint2D::PinJoint2D() {
|
||||
|
||||
|
||||
softness = 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -72,13 +72,17 @@ class PinJoint2D : public Joint2D {
|
|||
|
||||
OBJ_TYPE(PinJoint2D,Joint2D);
|
||||
|
||||
real_t softness;
|
||||
|
||||
protected:
|
||||
|
||||
void _notification(int p_what);
|
||||
virtual RID _configure_joint();
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
|
||||
void set_softness(real_t p_stiffness);
|
||||
real_t get_softness() const;
|
||||
|
||||
PinJoint2D();
|
||||
};
|
||||
|
|
|
@ -53,6 +53,16 @@ uint32_t RayCast2D::get_layer_mask() const {
|
|||
return layer_mask;
|
||||
}
|
||||
|
||||
void RayCast2D::set_type_mask(uint32_t p_mask) {
|
||||
|
||||
type_mask=p_mask;
|
||||
}
|
||||
|
||||
uint32_t RayCast2D::get_type_mask() const {
|
||||
|
||||
return type_mask;
|
||||
}
|
||||
|
||||
bool RayCast2D::is_colliding() const{
|
||||
|
||||
return collided;
|
||||
|
@ -162,7 +172,7 @@ void RayCast2D::_notification(int p_what) {
|
|||
|
||||
Physics2DDirectSpaceState::RayResult rr;
|
||||
|
||||
if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude,layer_mask)) {
|
||||
if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude,layer_mask,type_mask)) {
|
||||
|
||||
collided=true;
|
||||
against=rr.collider_id;
|
||||
|
@ -241,9 +251,13 @@ void RayCast2D::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&RayCast2D::set_layer_mask);
|
||||
ObjectTypeDB::bind_method(_MD("get_layer_mask"),&RayCast2D::get_layer_mask);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_type_mask","mask"),&RayCast2D::set_type_mask);
|
||||
ObjectTypeDB::bind_method(_MD("get_type_mask"),&RayCast2D::get_type_mask);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"enabled"),_SCS("set_enabled"),_SCS("is_enabled"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"cast_to"),_SCS("set_cast_to"),_SCS("get_cast_to"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT,"layer_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT,"type_mask",PROPERTY_HINT_FLAGS,"Static,Kinematic,Rigid,Character,Area"),_SCS("set_type_mask"),_SCS("get_type_mask"));
|
||||
}
|
||||
|
||||
RayCast2D::RayCast2D() {
|
||||
|
@ -253,5 +267,6 @@ RayCast2D::RayCast2D() {
|
|||
collided=false;
|
||||
against_shape=0;
|
||||
layer_mask=1;
|
||||
type_mask=Physics2DDirectSpaceState::TYPE_MASK_COLLISION;
|
||||
cast_to=Vector2(0,50);
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ class RayCast2D : public Node2D {
|
|||
Vector2 collision_normal;
|
||||
Set<RID> exclude;
|
||||
uint32_t layer_mask;
|
||||
uint32_t type_mask;
|
||||
|
||||
|
||||
Vector2 cast_to;
|
||||
|
@ -62,6 +63,9 @@ public:
|
|||
void set_layer_mask(uint32_t p_mask);
|
||||
uint32_t get_layer_mask() const;
|
||||
|
||||
void set_type_mask(uint32_t p_mask);
|
||||
uint32_t get_type_mask() const;
|
||||
|
||||
bool is_colliding() const;
|
||||
Object *get_collider() const;
|
||||
int get_collider_shape() const;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "core/core_string_names.h"
|
||||
#include "scene/scene_string_names.h"
|
||||
#include "scene/main/viewport.h"
|
||||
#include "os/os.h"
|
||||
|
||||
void Sprite::edit_set_pivot(const Point2& p_pivot) {
|
||||
|
||||
|
@ -85,6 +86,9 @@ void Sprite::_notification(int p_what) {
|
|||
Point2 ofs=offset;
|
||||
if (centered)
|
||||
ofs-=s/2;
|
||||
if (OS::get_singleton()->get_use_pixel_snap()) {
|
||||
ofs=ofs.floor();
|
||||
}
|
||||
|
||||
Rect2 dst_rect(ofs,s);
|
||||
|
||||
|
@ -422,6 +426,9 @@ void ViewportSprite::_notification(int p_what) {
|
|||
if (centered)
|
||||
ofs-=s/2;
|
||||
|
||||
if (OS::get_singleton()->get_use_pixel_snap()) {
|
||||
ofs=ofs.floor();
|
||||
}
|
||||
Rect2 dst_rect(ofs,s);
|
||||
texture->draw_rect_region(ci,dst_rect,src_rect,modulate);
|
||||
|
||||
|
|
|
@ -323,8 +323,10 @@ void PopupMenu::_input_event(const InputEvent &p_event) {
|
|||
invalidated_click=false;
|
||||
break;
|
||||
}
|
||||
if (over<0 || items[over].separator || items[over].disabled)
|
||||
if (over<0 || items[over].separator || items[over].disabled) {
|
||||
hide();
|
||||
break; //non-activable
|
||||
}
|
||||
|
||||
if (items[over].submenu!="") {
|
||||
|
||||
|
|
|
@ -709,7 +709,7 @@ void TextEdit::_notification(int p_what) {
|
|||
if (in_region==-1 && !in_keyword && is_char && !prev_is_char) {
|
||||
|
||||
int to=j;
|
||||
while(_is_text_char(str[to]) && to<str.length())
|
||||
while(to<str.length() && _is_text_char(str[to]))
|
||||
to++;
|
||||
|
||||
uint32_t hash = String::hash(&str[j],to-j);
|
||||
|
|
74
scene/main/instance_placeholder.cpp
Normal file
74
scene/main/instance_placeholder.cpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
#include "instance_placeholder.h"
|
||||
|
||||
#include "scene/resources/packed_scene.h"
|
||||
#include "io/resource_loader.h"
|
||||
|
||||
bool InstancePlaceholder::_set(const StringName& p_name, const Variant& p_value) {
|
||||
|
||||
PropSet ps;
|
||||
ps.name=p_name;
|
||||
ps.value=p_value;
|
||||
stored_values.push_back(ps);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InstancePlaceholder::_get(const StringName& p_name,Variant &r_ret) const{
|
||||
|
||||
return false;
|
||||
}
|
||||
void InstancePlaceholder::_get_property_list( List<PropertyInfo> *p_list) const{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void InstancePlaceholder::set_path(const String& p_name) {
|
||||
|
||||
path=p_name;
|
||||
}
|
||||
|
||||
String InstancePlaceholder::get_path() const {
|
||||
|
||||
return path;
|
||||
}
|
||||
void InstancePlaceholder::replace_by_instance(const Ref<PackedScene> &p_custom_scene){
|
||||
|
||||
ERR_FAIL_COND(!is_inside_tree());
|
||||
|
||||
Node *base = get_parent();
|
||||
if (!base)
|
||||
return;
|
||||
|
||||
Ref<PackedScene> ps;
|
||||
if (p_custom_scene.is_valid())
|
||||
ps = p_custom_scene;
|
||||
else
|
||||
ps = ResourceLoader::load(path,"PackedScene");
|
||||
|
||||
if (!ps.is_valid())
|
||||
return;
|
||||
Node *scene = ps->instance();
|
||||
scene->set_name(get_name());
|
||||
int pos = get_position_in_parent();
|
||||
|
||||
for(List<PropSet>::Element *E=stored_values.front();E;E=E->next()) {
|
||||
scene->set(E->get().name,E->get().value);
|
||||
}
|
||||
|
||||
queue_delete();
|
||||
|
||||
base->remove_child(this);
|
||||
base->add_child(scene);
|
||||
base->move_child(scene,pos);
|
||||
|
||||
}
|
||||
|
||||
void InstancePlaceholder::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("replace_by_instance","custom_scene:PackedScene"),&InstancePlaceholder::replace_by_instance,DEFVAL(Variant()));
|
||||
}
|
||||
|
||||
InstancePlaceholder::InstancePlaceholder() {
|
||||
|
||||
|
||||
}
|
37
scene/main/instance_placeholder.h
Normal file
37
scene/main/instance_placeholder.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef INSTANCE_PLACEHOLDER_H
|
||||
#define INSTANCE_PLACEHOLDER_H
|
||||
|
||||
#include "scene/main/node.h"
|
||||
|
||||
class PackedScene;
|
||||
|
||||
class InstancePlaceholder : public Node {
|
||||
|
||||
OBJ_TYPE(InstancePlaceholder,Node);
|
||||
|
||||
String path;
|
||||
struct PropSet {
|
||||
StringName name;
|
||||
Variant value;
|
||||
};
|
||||
|
||||
List<PropSet> stored_values;
|
||||
|
||||
protected:
|
||||
bool _set(const StringName& p_name, const Variant& p_value);
|
||||
bool _get(const StringName& p_name,Variant &r_ret) const;
|
||||
void _get_property_list( List<PropertyInfo> *p_list) const;
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
void set_path(const String& p_name);
|
||||
String get_path() const;
|
||||
|
||||
void replace_by_instance(const Ref<PackedScene>& p_custom_scene=Ref<PackedScene>());
|
||||
|
||||
InstancePlaceholder();
|
||||
};
|
||||
|
||||
#endif // INSTANCE_PLACEHOLDER_H
|
|
@ -841,6 +841,20 @@ Node *Node::get_child(int p_index) const {
|
|||
return data.children[p_index];
|
||||
}
|
||||
|
||||
|
||||
Node *Node::_get_child_by_name(const StringName& p_name) const {
|
||||
|
||||
int cc=data.children.size();
|
||||
Node* const* cd=data.children.ptr();
|
||||
|
||||
for(int i=0;i<cc;i++){
|
||||
if (cd[i]->data.name==p_name)
|
||||
return cd[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Node *Node::_get_node(const NodePath& p_path) const {
|
||||
|
||||
ERR_FAIL_COND_V( !data.inside_tree && p_path.is_absolute(), NULL );
|
||||
|
@ -906,8 +920,10 @@ Node *Node::_get_node(const NodePath& p_path) const {
|
|||
Node *Node::get_node(const NodePath& p_path) const {
|
||||
|
||||
Node *node = _get_node(p_path);
|
||||
ERR_EXPLAIN("Node not found: "+p_path);
|
||||
ERR_FAIL_COND_V(!node,NULL);
|
||||
if (!node) {
|
||||
ERR_EXPLAIN("Node not found: "+p_path);
|
||||
ERR_FAIL_COND_V(!node,NULL);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -1036,6 +1052,7 @@ void Node::get_owned_by(Node *p_by,List<Node*> *p_owned) {
|
|||
|
||||
void Node::_set_owner_nocheck(Node* p_owner) {
|
||||
|
||||
ERR_FAIL_COND(data.owner);
|
||||
data.owner=p_owner;
|
||||
data.owner->data.owned.push_back( this );
|
||||
data.OW = data.owner->data.owned.back();
|
||||
|
@ -1332,7 +1349,29 @@ String Node::get_filename() const {
|
|||
return data.filename;
|
||||
}
|
||||
|
||||
void Node::set_editable_instance(Node* p_node,bool p_editable) {
|
||||
|
||||
ERR_FAIL_NULL(p_node);
|
||||
ERR_FAIL_COND(!is_a_parent_of(p_node));
|
||||
NodePath p = get_path_to(p_node);
|
||||
if (!p_editable)
|
||||
data.editable_instances.erase(p);
|
||||
else
|
||||
data.editable_instances[p]=true;
|
||||
|
||||
}
|
||||
|
||||
bool Node::is_editable_instance(Node *p_node) const {
|
||||
|
||||
if (!p_node)
|
||||
return false; //easier, null is never editable :)
|
||||
ERR_FAIL_COND_V(!is_a_parent_of(p_node),false);
|
||||
NodePath p = get_path_to(p_node);
|
||||
return data.editable_instances.has(p);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
void Node::generate_instance_state() {
|
||||
|
||||
|
@ -1383,13 +1422,36 @@ Dictionary Node::get_instance_state() const {
|
|||
return data.instance_state;
|
||||
}
|
||||
|
||||
Vector<StringName> Node::get_instance_groups() const {
|
||||
#endif
|
||||
|
||||
return data.instance_groups;
|
||||
void Node::set_scene_instance_state(const Ref<SceneState>& p_state) {
|
||||
|
||||
data.instance_state=p_state;
|
||||
}
|
||||
Vector<Node::Connection> Node::get_instance_connections() const{
|
||||
|
||||
return data.instance_connections;
|
||||
Ref<SceneState> Node::get_scene_instance_state() const{
|
||||
|
||||
return data.instance_state;
|
||||
}
|
||||
|
||||
void Node::set_scene_inherited_state(const Ref<SceneState>& p_state) {
|
||||
|
||||
data.inherited_state=p_state;
|
||||
}
|
||||
|
||||
Ref<SceneState> Node::get_scene_inherited_state() const{
|
||||
|
||||
return data.inherited_state;
|
||||
}
|
||||
|
||||
void Node::set_scene_instance_load_placeholder(bool p_enable) {
|
||||
|
||||
data.use_placeholder=p_enable;
|
||||
}
|
||||
|
||||
bool Node::get_scene_instance_load_placeholder() const{
|
||||
|
||||
return data.use_placeholder;
|
||||
}
|
||||
|
||||
int Node::get_position_in_parent() const {
|
||||
|
@ -1931,7 +1993,7 @@ void Node::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("has_node","path"),&Node::has_node);
|
||||
ObjectTypeDB::bind_method(_MD("get_node:Node","path"),&Node::get_node);
|
||||
ObjectTypeDB::bind_method(_MD("get_parent:Parent"),&Node::get_parent);
|
||||
ObjectTypeDB::bind_method(_MD("find_node:Node","mask","recursive","owned"),&Node::get_node,DEFVAL(true),DEFVAL(true));
|
||||
ObjectTypeDB::bind_method(_MD("find_node:Node","mask","recursive","owned"),&Node::find_node,DEFVAL(true),DEFVAL(true));
|
||||
ObjectTypeDB::bind_method(_MD("has_node_and_resource","path"),&Node::has_node_and_resource);
|
||||
ObjectTypeDB::bind_method(_MD("get_node_and_resource","path"),&Node::_get_node_and_resource);
|
||||
|
||||
|
@ -2049,6 +2111,7 @@ Node::Node() {
|
|||
data.parent_owned=false;
|
||||
data.in_constructor=true;
|
||||
data.viewport=NULL;
|
||||
data.use_placeholder=false;
|
||||
}
|
||||
|
||||
Node::~Node() {
|
||||
|
@ -2065,3 +2128,4 @@ Node::~Node() {
|
|||
}
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
|
||||
class Viewport;
|
||||
class SceneState;
|
||||
class Node : public Object {
|
||||
|
||||
OBJ_TYPE( Node, Object );
|
||||
|
@ -69,9 +70,10 @@ private:
|
|||
struct Data {
|
||||
|
||||
String filename;
|
||||
Dictionary instance_state;
|
||||
Vector<StringName> instance_groups;
|
||||
Vector<Connection> instance_connections;
|
||||
Ref<SceneState> instance_state;
|
||||
Ref<SceneState> inherited_state;
|
||||
|
||||
HashMap<NodePath,int> editable_instances;
|
||||
|
||||
Node *parent;
|
||||
Node *owner;
|
||||
|
@ -96,6 +98,7 @@ private:
|
|||
PauseMode pause_mode;
|
||||
Node *pause_owner;
|
||||
// variables used to properly sort the node when processing, ignored otherwise
|
||||
//should move all the stuff below to bits
|
||||
bool fixed_process;
|
||||
bool idle_process;
|
||||
|
||||
|
@ -105,6 +108,9 @@ private:
|
|||
|
||||
bool parent_owned;
|
||||
bool in_constructor;
|
||||
bool use_placeholder;
|
||||
|
||||
|
||||
} data;
|
||||
|
||||
|
||||
|
@ -112,6 +118,7 @@ private:
|
|||
|
||||
virtual bool _use_builtin_script() const { return true; }
|
||||
Node *_get_node(const NodePath& p_path) const;
|
||||
Node *_get_child_by_name(const StringName& p_name) const;
|
||||
|
||||
|
||||
|
||||
|
@ -151,7 +158,7 @@ protected:
|
|||
|
||||
static void _bind_methods();
|
||||
|
||||
friend class PackedScene;
|
||||
friend class SceneState;
|
||||
|
||||
void _add_child_nocheck(Node* p_child,const StringName& p_name);
|
||||
void _set_owner_nocheck(Node* p_owner);
|
||||
|
@ -208,7 +215,7 @@ public:
|
|||
|
||||
struct GroupInfo {
|
||||
|
||||
String name;
|
||||
StringName name;
|
||||
bool persistent;
|
||||
};
|
||||
|
||||
|
@ -229,7 +236,11 @@ public:
|
|||
|
||||
void set_filename(const String& p_filename);
|
||||
String get_filename() const;
|
||||
|
||||
|
||||
void set_editable_instance(Node* p_node,bool p_editable);
|
||||
bool is_editable_instance(Node* p_node) const;
|
||||
|
||||
|
||||
/* NOTIFICATIONS */
|
||||
|
||||
void propagate_notification(int p_notification);
|
||||
|
@ -261,10 +272,14 @@ public:
|
|||
//Node *clone_tree() const;
|
||||
|
||||
// used by editors, to save what has changed only
|
||||
void generate_instance_state();
|
||||
Dictionary get_instance_state() const;
|
||||
Vector<StringName> get_instance_groups() const;
|
||||
Vector<Connection> get_instance_connections() const;
|
||||
void set_scene_instance_state(const Ref<SceneState>& p_state);
|
||||
Ref<SceneState> get_scene_instance_state() const;
|
||||
|
||||
void set_scene_inherited_state(const Ref<SceneState>& p_state);
|
||||
Ref<SceneState> get_scene_inherited_state() const;
|
||||
|
||||
void set_scene_instance_load_placeholder(bool p_enable);
|
||||
bool get_scene_instance_load_placeholder() const;
|
||||
|
||||
static Vector<Variant> make_binds(VARIANT_ARG_LIST);
|
||||
|
||||
|
@ -307,6 +322,4 @@ public:
|
|||
typedef Set<Node*,Node::Comparator> NodeSet;
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "resources/default_theme/default_theme.h"
|
||||
#include "object_type_db.h"
|
||||
#include "scene/main/canvas_layer.h"
|
||||
#include "scene/main/instance_placeholder.h"
|
||||
#include "scene/main/viewport.h"
|
||||
#include "scene/gui/control.h"
|
||||
#include "scene/gui/texture_progress.h"
|
||||
|
@ -216,7 +217,7 @@
|
|||
#include "scene/3d/collision_polygon.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include "scene/resources/scene_format_text.h"
|
||||
|
||||
static ResourceFormatLoaderImage *resource_loader_image=NULL;
|
||||
static ResourceFormatLoaderWAV *resource_loader_wav=NULL;
|
||||
|
@ -229,6 +230,8 @@ static ResourceFormatLoaderBitMap *resource_loader_bitmap=NULL;
|
|||
static ResourceFormatLoaderTheme *resource_loader_theme=NULL;
|
||||
static ResourceFormatLoaderShader *resource_loader_shader=NULL;
|
||||
|
||||
static ResourceFormatSaverText *resource_saver_text=NULL;
|
||||
|
||||
//static SceneStringNames *string_names;
|
||||
|
||||
void register_scene_types() {
|
||||
|
@ -267,6 +270,7 @@ void register_scene_types() {
|
|||
ObjectTypeDB::register_type<Object>();
|
||||
|
||||
ObjectTypeDB::register_type<Node>();
|
||||
ObjectTypeDB::register_virtual_type<InstancePlaceholder>();
|
||||
|
||||
ObjectTypeDB::register_type<Viewport>();
|
||||
ObjectTypeDB::register_virtual_type<RenderTargetTexture>();
|
||||
|
@ -612,6 +616,9 @@ void register_scene_types() {
|
|||
OS::get_singleton()->yield(); //may take time to init
|
||||
|
||||
|
||||
resource_saver_text = memnew( ResourceFormatSaverText );
|
||||
ResourceSaver::add_resource_format_saver(resource_saver_text);
|
||||
|
||||
}
|
||||
|
||||
void unregister_scene_types() {
|
||||
|
@ -629,5 +636,9 @@ void unregister_scene_types() {
|
|||
|
||||
memdelete( resource_loader_theme );
|
||||
memdelete( resource_loader_shader );
|
||||
|
||||
if (resource_saver_text) {
|
||||
memdelete(resource_saver_text);
|
||||
}
|
||||
SceneStringNames::free();
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -32,26 +32,27 @@
|
|||
#include "resource.h"
|
||||
#include "scene/main/node.h"
|
||||
|
||||
//changes:
|
||||
//1-make the InstanceState a reference inside the resource that can be shared
|
||||
//2-make the instance "editable" with a flag, save here and load here, no need for property
|
||||
//3-properly save modifications in sub-scene
|
||||
//4-add scene inheritance
|
||||
//5-chain of instance states in editor? (to check what was modified)
|
||||
//6-saving will be hell
|
||||
|
||||
class SceneState : public Reference {
|
||||
|
||||
class PackedScene : public Resource {
|
||||
|
||||
OBJ_TYPE( PackedScene, Resource );
|
||||
RES_BASE_EXTENSION("scn");
|
||||
OBJ_TYPE( SceneState, Reference );
|
||||
Vector<StringName> names;
|
||||
Vector<Variant> variants;
|
||||
Vector<NodePath> node_paths;
|
||||
Vector<NodePath> editable_instances;
|
||||
mutable HashMap<NodePath,int> node_path_cache;
|
||||
mutable Map<int,int> base_scene_node_remap;
|
||||
|
||||
//missing - instances
|
||||
//missing groups
|
||||
//missing - owner
|
||||
//missing - override names and values
|
||||
int base_scene_idx;
|
||||
|
||||
enum {
|
||||
FLAG_ID_IS_PATH=(1<<30),
|
||||
FLAG_INSTANCE_IS_PLACEHOLDER=(1<<30),
|
||||
FLAG_MASK=(1<<24)-1,
|
||||
NO_PARENT_SAVED=0x7FFFFFFF,
|
||||
TYPE_INSTANCED=0x7FFFFFFF,
|
||||
|
||||
};
|
||||
|
||||
struct NodeData {
|
||||
|
||||
|
@ -68,9 +69,15 @@ class PackedScene : public Resource {
|
|||
};
|
||||
|
||||
Vector<Property> properties;
|
||||
Vector<int> groups;
|
||||
Vector<int> groups;
|
||||
|
||||
};
|
||||
|
||||
struct PackState {
|
||||
Ref<SceneState> state;
|
||||
int node;
|
||||
PackState() { node=-1; }
|
||||
};
|
||||
|
||||
Vector<NodeData> nodes;
|
||||
|
||||
|
@ -86,16 +93,78 @@ class PackedScene : public Resource {
|
|||
|
||||
Vector<ConnectionData> connections;
|
||||
|
||||
Error _parse_node(Node *p_owner,Node *p_node,int p_parent_idx, Map<StringName,int> &name_map,HashMap<Variant,int,VariantHasher> &variant_map,Map<Node*,int> &node_map);
|
||||
Error _parse_connections(Node *p_owner,Node *p_node, Map<StringName,int> &name_map,HashMap<Variant,int,VariantHasher> &variant_map,Map<Node*,int> &node_map);
|
||||
|
||||
Error _parse_node(Node *p_owner,Node *p_node,int p_parent_idx, Map<StringName,int> &name_map,HashMap<Variant,int,VariantHasher> &variant_map,Map<Node*,int> &node_map,Map<Node*,int> &nodepath_map);
|
||||
Error _parse_connections(Node *p_owner,Node *p_node, Map<StringName,int> &name_map,HashMap<Variant,int,VariantHasher> &variant_map,Map<Node*,int> &node_map,Map<Node*,int> &nodepath_map);
|
||||
|
||||
String path;
|
||||
|
||||
_FORCE_INLINE_ Ref<SceneState> _get_base_scene_state() const;
|
||||
|
||||
static bool disable_placeholders;
|
||||
public:
|
||||
|
||||
static void set_disable_placeholders(bool p_disable);
|
||||
|
||||
int find_node_by_path(const NodePath& p_node) const;
|
||||
Variant get_property_value(int p_node,const StringName& p_property,bool &found) const;
|
||||
bool is_node_in_group(int p_node,const StringName& p_group) const;
|
||||
bool is_connection(int p_node,const StringName& p_signal,int p_to_node,const StringName& p_to_method) const;
|
||||
|
||||
|
||||
void set_bundled_scene(const Dictionary& p_dictionary);
|
||||
Dictionary get_bundled_scene() const;
|
||||
|
||||
Error pack(Node *p_scene);
|
||||
|
||||
void set_path(const String &p_path);
|
||||
String get_path() const;
|
||||
|
||||
void clear();
|
||||
|
||||
bool can_instance() const;
|
||||
Node *instance(bool p_gen_edit_state=false) const;
|
||||
|
||||
|
||||
//build-unbuild API
|
||||
|
||||
int get_node_count() const;
|
||||
StringName get_node_type(int p_idx) const;
|
||||
StringName get_node_name(int p_idx) const;
|
||||
NodePath get_node_path(int p_idx,bool p_for_parent=false) const;
|
||||
NodePath get_node_owner_path(int p_idx) const;
|
||||
Ref<PackedScene> get_node_instance(int p_idx) const;
|
||||
Vector<StringName> get_node_groups(int p_idx) const;
|
||||
|
||||
int get_node_property_count(int p_idx) const;
|
||||
StringName get_node_property_name(int p_idx,int p_prop) const;
|
||||
Variant get_node_property_value(int p_idx,int p_prop) const;
|
||||
|
||||
int get_connection_count() const;
|
||||
NodePath get_connection_source(int p_idx) const;
|
||||
StringName get_connection_signal(int p_idx) const;
|
||||
NodePath get_connection_target(int p_idx) const;
|
||||
StringName get_connection_method(int p_idx) const;
|
||||
int get_connection_flags(int p_idx) const;
|
||||
Array get_connection_binds(int p_idx) const;
|
||||
|
||||
Vector<NodePath> get_editable_instances() const;
|
||||
|
||||
SceneState();
|
||||
};
|
||||
|
||||
class PackedScene : public Resource {
|
||||
|
||||
OBJ_TYPE(PackedScene, Resource );
|
||||
RES_BASE_EXTENSION("scn");
|
||||
|
||||
Ref<SceneState> state;
|
||||
|
||||
void _set_bundled_scene(const Dictionary& p_scene);
|
||||
Dictionary _get_bundled_scene() const;
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
|
@ -107,7 +176,12 @@ public:
|
|||
bool can_instance() const;
|
||||
Node *instance(bool p_gen_edit_state=false) const;
|
||||
|
||||
virtual void set_path(const String& p_path,bool p_take_over=false);
|
||||
|
||||
Ref<SceneState> get_state();
|
||||
|
||||
PackedScene();
|
||||
|
||||
};
|
||||
|
||||
#endif // SCENE_PRELOADER_H
|
||||
|
|
792
scene/resources/scene_format_text.cpp
Normal file
792
scene/resources/scene_format_text.cpp
Normal file
|
@ -0,0 +1,792 @@
|
|||
#include "scene_format_text.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "version.h"
|
||||
#include "os/dir_access.h"
|
||||
|
||||
#define FORMAT_VERSION 1
|
||||
|
||||
void ResourceFormatSaverTextInstance::write_property(const String& p_name,const Variant& p_property,bool *r_ok) {
|
||||
|
||||
if (r_ok)
|
||||
*r_ok=false;
|
||||
|
||||
if (p_name!=String()) {
|
||||
f->store_string(p_name+" = ");
|
||||
}
|
||||
|
||||
switch( p_property.get_type() ) {
|
||||
|
||||
case Variant::NIL: {
|
||||
f->store_string("null");
|
||||
} break;
|
||||
case Variant::BOOL: {
|
||||
|
||||
f->store_string(p_property.operator bool() ? "true":"false" );
|
||||
} break;
|
||||
case Variant::INT: {
|
||||
|
||||
f->store_string( itos(p_property.operator int()) );
|
||||
} break;
|
||||
case Variant::REAL: {
|
||||
|
||||
f->store_string( rtoss(p_property.operator real_t()) );
|
||||
} break;
|
||||
case Variant::STRING: {
|
||||
|
||||
String str=p_property;
|
||||
|
||||
str="\""+str.c_escape()+"\"";
|
||||
f->store_string( str );
|
||||
} break;
|
||||
case Variant::VECTOR2: {
|
||||
|
||||
Vector2 v = p_property;
|
||||
f->store_string("Vector2( "+rtoss(v.x) +", "+rtoss(v.y)+" )" );
|
||||
} break;
|
||||
case Variant::RECT2: {
|
||||
|
||||
Rect2 aabb = p_property;
|
||||
f->store_string("Rect2( "+rtoss(aabb.pos.x) +", "+rtoss(aabb.pos.y) +", "+rtoss(aabb.size.x) +", "+rtoss(aabb.size.y)+" )" );
|
||||
|
||||
} break;
|
||||
case Variant::VECTOR3: {
|
||||
|
||||
Vector3 v = p_property;
|
||||
f->store_string("Vector3( "+rtoss(v.x) +", "+rtoss(v.y)+", "+rtoss(v.z)+" )");
|
||||
} break;
|
||||
case Variant::PLANE: {
|
||||
|
||||
Plane p = p_property;
|
||||
f->store_string("Plane( "+rtoss(p.normal.x) +", "+rtoss(p.normal.y)+", "+rtoss(p.normal.z)+", "+rtoss(p.d)+" )" );
|
||||
|
||||
} break;
|
||||
case Variant::_AABB: {
|
||||
|
||||
AABB aabb = p_property;
|
||||
f->store_string("AABB( "+rtoss(aabb.pos.x) +", "+rtoss(aabb.pos.y) +", "+rtoss(aabb.pos.z) +", "+rtoss(aabb.size.x) +", "+rtoss(aabb.size.y) +", "+rtoss(aabb.size.z)+" )" );
|
||||
|
||||
} break;
|
||||
case Variant::QUAT: {
|
||||
|
||||
Quat quat = p_property;
|
||||
f->store_string("Quat( "+rtoss(quat.x)+", "+rtoss(quat.y)+", "+rtoss(quat.z)+", "+rtoss(quat.w)+" )");
|
||||
|
||||
} break;
|
||||
case Variant::MATRIX32: {
|
||||
|
||||
String s="Matrix32( ";
|
||||
Matrix32 m3 = p_property;
|
||||
for (int i=0;i<3;i++) {
|
||||
for (int j=0;j<2;j++) {
|
||||
|
||||
if (i!=0 || j!=0)
|
||||
s+=", ";
|
||||
s+=rtoss( m3.elements[i][j] );
|
||||
}
|
||||
}
|
||||
|
||||
f->store_string(s+" )");
|
||||
|
||||
} break;
|
||||
case Variant::MATRIX3: {
|
||||
|
||||
String s="Matrix3( ";
|
||||
Matrix3 m3 = p_property;
|
||||
for (int i=0;i<3;i++) {
|
||||
for (int j=0;j<3;j++) {
|
||||
|
||||
if (i!=0 || j!=0)
|
||||
s+=", ";
|
||||
s+=rtoss( m3.elements[i][j] );
|
||||
}
|
||||
}
|
||||
|
||||
f->store_string(s+" )");
|
||||
|
||||
} break;
|
||||
case Variant::TRANSFORM: {
|
||||
|
||||
String s="Transform( ";
|
||||
Transform t = p_property;
|
||||
Matrix3 &m3 = t.basis;
|
||||
for (int i=0;i<3;i++) {
|
||||
for (int j=0;j<3;j++) {
|
||||
|
||||
if (i!=0 || j!=0)
|
||||
s+=", ";
|
||||
s+=rtoss( m3.elements[i][j] );
|
||||
}
|
||||
}
|
||||
|
||||
s=s+", "+rtoss(t.origin.x) +", "+rtoss(t.origin.y)+", "+rtoss(t.origin.z);
|
||||
|
||||
f->store_string(s+" )");
|
||||
} break;
|
||||
|
||||
// misc types
|
||||
case Variant::COLOR: {
|
||||
|
||||
Color c = p_property;
|
||||
f->store_string("Color( "+rtoss(c.r) +", "+rtoss(c.g)+", "+rtoss(c.b)+", "+rtoss(c.a)+" )");
|
||||
|
||||
} break;
|
||||
case Variant::IMAGE: {
|
||||
|
||||
|
||||
Image img=p_property;
|
||||
|
||||
if (img.empty()) {
|
||||
f->store_string("RawImage()");
|
||||
break;
|
||||
}
|
||||
|
||||
String imgstr="RawImage( ";
|
||||
imgstr+=itos(img.get_width());
|
||||
imgstr+=", "+itos(img.get_height());
|
||||
imgstr+=", "+itos(img.get_mipmaps());
|
||||
imgstr+=", ";
|
||||
|
||||
switch(img.get_format()) {
|
||||
|
||||
case Image::FORMAT_GRAYSCALE: imgstr+="GRAYSCALE"; break;
|
||||
case Image::FORMAT_INTENSITY: imgstr+="INTENSITY"; break;
|
||||
case Image::FORMAT_GRAYSCALE_ALPHA: imgstr+="GRAYSCALE_ALPHA"; break;
|
||||
case Image::FORMAT_RGB: imgstr+="RGB"; break;
|
||||
case Image::FORMAT_RGBA: imgstr+="RGBA"; break;
|
||||
case Image::FORMAT_INDEXED : imgstr+="INDEXED"; break;
|
||||
case Image::FORMAT_INDEXED_ALPHA: imgstr+="INDEXED_ALPHA"; break;
|
||||
case Image::FORMAT_BC1: imgstr+="BC1"; break;
|
||||
case Image::FORMAT_BC2: imgstr+="BC2"; break;
|
||||
case Image::FORMAT_BC3: imgstr+="BC3"; break;
|
||||
case Image::FORMAT_BC4: imgstr+="BC4"; break;
|
||||
case Image::FORMAT_BC5: imgstr+="BC5"; break;
|
||||
case Image::FORMAT_PVRTC2: imgstr+="PVRTC2"; break;
|
||||
case Image::FORMAT_PVRTC2_ALPHA: imgstr+="PVRTC2_ALPHA"; break;
|
||||
case Image::FORMAT_PVRTC4: imgstr+="PVRTC4"; break;
|
||||
case Image::FORMAT_PVRTC4_ALPHA: imgstr+="PVRTC4_ALPHA"; break;
|
||||
case Image::FORMAT_ETC: imgstr+="ETC"; break;
|
||||
case Image::FORMAT_ATC: imgstr+="ATC"; break;
|
||||
case Image::FORMAT_ATC_ALPHA_EXPLICIT: imgstr+="ATC_ALPHA_EXPLICIT"; break;
|
||||
case Image::FORMAT_ATC_ALPHA_INTERPOLATED: imgstr+="ATC_ALPHA_INTERPOLATED"; break;
|
||||
case Image::FORMAT_CUSTOM: imgstr+="CUSTOM"; break;
|
||||
default: {}
|
||||
}
|
||||
|
||||
|
||||
String s;
|
||||
|
||||
DVector<uint8_t> data = img.get_data();
|
||||
int len = data.size();
|
||||
DVector<uint8_t>::Read r = data.read();
|
||||
const uint8_t *ptr=r.ptr();;
|
||||
for (int i=0;i<len;i++) {
|
||||
|
||||
uint8_t byte = ptr[i];
|
||||
const char hex[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
|
||||
char str[3]={ hex[byte>>4], hex[byte&0xF], 0};
|
||||
s+=str;
|
||||
}
|
||||
|
||||
imgstr+=", ";
|
||||
f->store_string(imgstr);
|
||||
f->store_string(s);
|
||||
f->store_string(" )");
|
||||
} break;
|
||||
case Variant::NODE_PATH: {
|
||||
|
||||
String str=p_property;
|
||||
|
||||
str="NodePath(\""+str.c_escape()+"\")";
|
||||
f->store_string(str);
|
||||
|
||||
} break;
|
||||
|
||||
case Variant::OBJECT: {
|
||||
|
||||
RES res = p_property;
|
||||
if (res.is_null()) {
|
||||
f->store_string("null");
|
||||
if (r_ok)
|
||||
*r_ok=true;
|
||||
|
||||
break; // don't save it
|
||||
}
|
||||
|
||||
if (external_resources.has(res)) {
|
||||
|
||||
f->store_string("ExtResource( "+itos(external_resources[res]+1)+" )");
|
||||
} else {
|
||||
|
||||
if (internal_resources.has(res)) {
|
||||
f->store_string("SubResource( "+itos(internal_resources[res])+" )");
|
||||
} else if (res->get_path().length() && res->get_path().find("::")==-1) {
|
||||
|
||||
//external resource
|
||||
String path=relative_paths?local_path.path_to_file(res->get_path()):res->get_path();
|
||||
f->store_string("Resource( \""+path+"\" )");
|
||||
} else {
|
||||
f->store_string("null");
|
||||
ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?");
|
||||
ERR_BREAK(true);
|
||||
//internal resource
|
||||
}
|
||||
}
|
||||
|
||||
} break;
|
||||
case Variant::INPUT_EVENT: {
|
||||
|
||||
f->store_string("InputEvent()"); //will be added later
|
||||
} break;
|
||||
case Variant::DICTIONARY: {
|
||||
|
||||
Dictionary dict = p_property;
|
||||
|
||||
List<Variant> keys;
|
||||
dict.get_key_list(&keys);
|
||||
keys.sort();
|
||||
|
||||
f->store_string("{ ");
|
||||
for(List<Variant>::Element *E=keys.front();E;E=E->next()) {
|
||||
|
||||
//if (!_check_type(dict[E->get()]))
|
||||
// continue;
|
||||
bool ok;
|
||||
write_property("",E->get(),&ok);
|
||||
ERR_CONTINUE(!ok);
|
||||
|
||||
f->store_string(":");
|
||||
write_property("",dict[E->get()],&ok);
|
||||
if (!ok)
|
||||
write_property("",Variant()); //at least make the file consistent..
|
||||
if (E->next())
|
||||
f->store_string(", ");
|
||||
}
|
||||
|
||||
|
||||
f->store_string(" }");
|
||||
|
||||
|
||||
} break;
|
||||
case Variant::ARRAY: {
|
||||
|
||||
f->store_string("[ ");
|
||||
Array array = p_property;
|
||||
int len=array.size();
|
||||
for (int i=0;i<len;i++) {
|
||||
|
||||
if (i>0)
|
||||
f->store_string(", ");
|
||||
write_property("",array[i]);
|
||||
|
||||
|
||||
}
|
||||
f->store_string(" ]");
|
||||
|
||||
} break;
|
||||
|
||||
case Variant::RAW_ARRAY: {
|
||||
|
||||
f->store_string("RawArray( ");
|
||||
String s;
|
||||
DVector<uint8_t> data = p_property;
|
||||
int len = data.size();
|
||||
DVector<uint8_t>::Read r = data.read();
|
||||
const uint8_t *ptr=r.ptr();;
|
||||
for (int i=0;i<len;i++) {
|
||||
|
||||
if (i>0)
|
||||
f->store_string(", ");
|
||||
uint8_t byte = ptr[i];
|
||||
const char hex[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
|
||||
char str[3]={ hex[byte>>4], hex[byte&0xF], 0};
|
||||
f->store_string(str);
|
||||
|
||||
}
|
||||
|
||||
f->store_string(" )");
|
||||
|
||||
} break;
|
||||
case Variant::INT_ARRAY: {
|
||||
|
||||
f->store_string("IntArray( ");
|
||||
DVector<int> data = p_property;
|
||||
int len = data.size();
|
||||
DVector<int>::Read r = data.read();
|
||||
const int *ptr=r.ptr();;
|
||||
|
||||
for (int i=0;i<len;i++) {
|
||||
|
||||
if (i>0)
|
||||
f->store_string(", ");
|
||||
|
||||
f->store_string(itos(ptr[i]));
|
||||
}
|
||||
|
||||
|
||||
f->store_string(" )");
|
||||
|
||||
} break;
|
||||
case Variant::REAL_ARRAY: {
|
||||
|
||||
f->store_string("FloatArray( ");
|
||||
DVector<real_t> data = p_property;
|
||||
int len = data.size();
|
||||
DVector<real_t>::Read r = data.read();
|
||||
const real_t *ptr=r.ptr();;
|
||||
|
||||
for (int i=0;i<len;i++) {
|
||||
|
||||
if (i>0)
|
||||
f->store_string(", ");
|
||||
f->store_string(rtoss(ptr[i]));
|
||||
}
|
||||
|
||||
f->store_string(" )");
|
||||
|
||||
} break;
|
||||
case Variant::STRING_ARRAY: {
|
||||
|
||||
f->store_string("StringArray( ");
|
||||
DVector<String> data = p_property;
|
||||
int len = data.size();
|
||||
DVector<String>::Read r = data.read();
|
||||
const String *ptr=r.ptr();;
|
||||
String s;
|
||||
//write_string("\n");
|
||||
|
||||
|
||||
|
||||
for (int i=0;i<len;i++) {
|
||||
|
||||
if (i>0)
|
||||
f->store_string(", ");
|
||||
String str=ptr[i];
|
||||
f->store_string(""+str.c_escape()+"\"");
|
||||
}
|
||||
|
||||
f->store_string(" )");
|
||||
|
||||
} break;
|
||||
case Variant::VECTOR2_ARRAY: {
|
||||
|
||||
f->store_string("Vector2Array( ");
|
||||
DVector<Vector2> data = p_property;
|
||||
int len = data.size();
|
||||
DVector<Vector2>::Read r = data.read();
|
||||
const Vector2 *ptr=r.ptr();;
|
||||
|
||||
for (int i=0;i<len;i++) {
|
||||
|
||||
if (i>0)
|
||||
f->store_string(", ");
|
||||
f->store_string(rtoss(ptr[i].x)+", "+rtoss(ptr[i].y) );
|
||||
}
|
||||
|
||||
f->store_string(" )");
|
||||
|
||||
} break;
|
||||
case Variant::VECTOR3_ARRAY: {
|
||||
|
||||
f->store_string("Vector3Array( ");
|
||||
DVector<Vector3> data = p_property;
|
||||
int len = data.size();
|
||||
DVector<Vector3>::Read r = data.read();
|
||||
const Vector3 *ptr=r.ptr();;
|
||||
|
||||
for (int i=0;i<len;i++) {
|
||||
|
||||
if (i>0)
|
||||
f->store_string(", ");
|
||||
f->store_string(rtoss(ptr[i].x)+", "+rtoss(ptr[i].y)+", "+rtoss(ptr[i].z) );
|
||||
}
|
||||
|
||||
f->store_string(" )");
|
||||
|
||||
} break;
|
||||
case Variant::COLOR_ARRAY: {
|
||||
|
||||
f->store_string("ColorArray( ");
|
||||
|
||||
DVector<Color> data = p_property;
|
||||
int len = data.size();
|
||||
DVector<Color>::Read r = data.read();
|
||||
const Color *ptr=r.ptr();;
|
||||
|
||||
for (int i=0;i<len;i++) {
|
||||
|
||||
if (i>0)
|
||||
f->store_string(", ");
|
||||
|
||||
f->store_string(rtoss(ptr[i].r)+", "+rtoss(ptr[i].g)+", "+rtoss(ptr[i].b)+", "+rtoss(ptr[i].a) );
|
||||
|
||||
}
|
||||
f->store_string(" )");
|
||||
|
||||
} break;
|
||||
default: {}
|
||||
|
||||
}
|
||||
|
||||
if (r_ok)
|
||||
*r_ok=true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ResourceFormatSaverTextInstance::_find_resources(const Variant& p_variant,bool p_main) {
|
||||
|
||||
|
||||
switch(p_variant.get_type()) {
|
||||
case Variant::OBJECT: {
|
||||
|
||||
|
||||
RES res = p_variant.operator RefPtr();
|
||||
|
||||
if (res.is_null() || external_resources.has(res))
|
||||
return;
|
||||
|
||||
if (!p_main && (!bundle_resources ) && res->get_path().length() && res->get_path().find("::") == -1 ) {
|
||||
int index = external_resources.size();
|
||||
external_resources[res]=index;
|
||||
return;
|
||||
}
|
||||
|
||||
if (resource_set.has(res))
|
||||
return;
|
||||
|
||||
List<PropertyInfo> property_list;
|
||||
|
||||
res->get_property_list( &property_list );
|
||||
property_list.sort();
|
||||
|
||||
List<PropertyInfo>::Element *I=property_list.front();
|
||||
|
||||
while(I) {
|
||||
|
||||
PropertyInfo pi=I->get();
|
||||
|
||||
if (pi.usage&PROPERTY_USAGE_STORAGE || (bundle_resources && pi.usage&PROPERTY_USAGE_BUNDLE)) {
|
||||
|
||||
Variant v=res->get(I->get().name);
|
||||
_find_resources(v);
|
||||
}
|
||||
|
||||
I=I->next();
|
||||
}
|
||||
|
||||
resource_set.insert( res ); //saved after, so the childs it needs are available when loaded
|
||||
saved_resources.push_back(res);
|
||||
|
||||
} break;
|
||||
case Variant::ARRAY: {
|
||||
|
||||
Array varray=p_variant;
|
||||
int len=varray.size();
|
||||
for(int i=0;i<len;i++) {
|
||||
|
||||
Variant v=varray.get(i);
|
||||
_find_resources(v);
|
||||
}
|
||||
|
||||
} break;
|
||||
case Variant::DICTIONARY: {
|
||||
|
||||
Dictionary d=p_variant;
|
||||
List<Variant> keys;
|
||||
d.get_key_list(&keys);
|
||||
for(List<Variant>::Element *E=keys.front();E;E=E->next()) {
|
||||
|
||||
Variant v = d[E->get()];
|
||||
_find_resources(v);
|
||||
}
|
||||
} break;
|
||||
default: {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Error ResourceFormatSaverTextInstance::save(const String &p_path,const RES& p_resource,uint32_t p_flags) {
|
||||
|
||||
if (p_path.ends_with(".tscn")) {
|
||||
packed_scene=p_resource;
|
||||
}
|
||||
|
||||
Error err;
|
||||
f = FileAccess::open(p_path, FileAccess::WRITE,&err);
|
||||
ERR_FAIL_COND_V( err, ERR_CANT_OPEN );
|
||||
FileAccessRef _fref(f);
|
||||
|
||||
local_path = Globals::get_singleton()->localize_path(p_path);
|
||||
|
||||
relative_paths=p_flags&ResourceSaver::FLAG_RELATIVE_PATHS;
|
||||
skip_editor=p_flags&ResourceSaver::FLAG_OMIT_EDITOR_PROPERTIES;
|
||||
bundle_resources=p_flags&ResourceSaver::FLAG_BUNDLE_RESOURCES;
|
||||
takeover_paths=p_flags&ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS;
|
||||
if (!p_path.begins_with("res://")) {
|
||||
takeover_paths=false;
|
||||
}
|
||||
|
||||
// save resources
|
||||
_find_resources(p_resource,true);
|
||||
|
||||
if (packed_scene.is_valid()) {
|
||||
//add instances to external resources if saving a packed scene
|
||||
for(int i=0;i<packed_scene->get_state()->get_node_count();i++) {
|
||||
Ref<PackedScene> instance=packed_scene->get_state()->get_node_instance(i);
|
||||
if (instance.is_valid() && !external_resources.has(instance)) {
|
||||
int index = external_resources.size();
|
||||
external_resources[instance]=index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ERR_FAIL_COND_V(err!=OK,err);
|
||||
|
||||
{
|
||||
String title=packed_scene.is_valid()?"[gd_scene ":"[gd_resource ";
|
||||
if (packed_scene.is_null())
|
||||
title+="type=\""+p_resource->get_type()+"\" ";
|
||||
int load_steps=saved_resources.size()+external_resources.size();
|
||||
//if (packed_scene.is_valid()) {
|
||||
// load_steps+=packed_scene->get_node_count();
|
||||
//}
|
||||
//no, better to not use load steps from nodes, no point to that
|
||||
|
||||
if (load_steps>1) {
|
||||
title+="load_steps="+itos(load_steps)+" ";
|
||||
}
|
||||
title+="format="+itos(FORMAT_VERSION)+"";
|
||||
//title+="engine_version=\""+itos(VERSION_MAJOR)+"."+itos(VERSION_MINOR)+"\"";
|
||||
|
||||
f->store_string(title);
|
||||
f->store_line("]\n"); //one empty line
|
||||
}
|
||||
|
||||
|
||||
for(Map<RES,int>::Element *E=external_resources.front();E;E=E->next()) {
|
||||
|
||||
String p = E->key()->get_path();
|
||||
|
||||
f->store_string("[ext_resource path=\""+p+"\" type=\""+E->key()->get_save_type()+"\" id="+itos(E->get()+1)+"]\n"); //bundled
|
||||
}
|
||||
|
||||
if (external_resources.size())
|
||||
f->store_line(String()); //separate
|
||||
|
||||
Set<int> used_indices;
|
||||
|
||||
for(List<RES>::Element *E=saved_resources.front();E;E=E->next()) {
|
||||
|
||||
RES res = E->get();
|
||||
if (E->next() && (res->get_path()=="" || res->get_path().find("::") != -1 )) {
|
||||
|
||||
if (res->get_subindex()!=0) {
|
||||
if (used_indices.has(res->get_subindex())) {
|
||||
res->set_subindex(0); //repeated
|
||||
} else {
|
||||
used_indices.insert(res->get_subindex());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(List<RES>::Element *E=saved_resources.front();E;E=E->next()) {
|
||||
|
||||
RES res = E->get();
|
||||
ERR_CONTINUE(!resource_set.has(res));
|
||||
bool main = (E->next()==NULL);
|
||||
|
||||
if (main && packed_scene.is_valid())
|
||||
break; //save as a scene
|
||||
|
||||
if (main) {
|
||||
f->store_line("[resource]\n");
|
||||
} else {
|
||||
String line="[sub_resource ";
|
||||
if (res->get_subindex()==0) {
|
||||
int new_subindex=1;
|
||||
if (used_indices.size()) {
|
||||
new_subindex=used_indices.back()->get()+1;
|
||||
}
|
||||
|
||||
res->set_subindex(new_subindex);
|
||||
used_indices.insert(new_subindex);
|
||||
}
|
||||
|
||||
int idx = res->get_subindex();
|
||||
line+="type=\""+res->get_type()+"\" id="+itos(idx);
|
||||
f->store_line(line+"]\n");
|
||||
if (takeover_paths) {
|
||||
res->set_path(p_path+"::"+itos(idx),true);
|
||||
}
|
||||
|
||||
internal_resources[res]=idx;
|
||||
|
||||
}
|
||||
|
||||
|
||||
List<PropertyInfo> property_list;
|
||||
res->get_property_list(&property_list);
|
||||
// property_list.sort();
|
||||
for(List<PropertyInfo>::Element *PE = property_list.front();PE;PE=PE->next()) {
|
||||
|
||||
|
||||
if (skip_editor && PE->get().name.begins_with("__editor"))
|
||||
continue;
|
||||
|
||||
if (PE->get().usage&PROPERTY_USAGE_STORAGE || (bundle_resources && PE->get().usage&PROPERTY_USAGE_BUNDLE)) {
|
||||
|
||||
String name = PE->get().name;
|
||||
Variant value = res->get(name);
|
||||
|
||||
|
||||
if ((PE->get().usage&PROPERTY_USAGE_STORE_IF_NONZERO && value.is_zero())||(PE->get().usage&PROPERTY_USAGE_STORE_IF_NONONE && value.is_one()) )
|
||||
continue;
|
||||
|
||||
if (PE->get().type==Variant::OBJECT && value.is_zero())
|
||||
continue;
|
||||
|
||||
write_property(name,value);
|
||||
f->store_string("\n");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
f->store_string("\n");
|
||||
|
||||
}
|
||||
|
||||
if (packed_scene.is_valid()) {
|
||||
//if this is a scene, save nodes and connections!
|
||||
Ref<SceneState> state = packed_scene->get_state();
|
||||
for(int i=0;i<state->get_node_count();i++) {
|
||||
|
||||
StringName type = state->get_node_type(i);
|
||||
StringName name = state->get_node_name(i);
|
||||
NodePath path = state->get_node_path(i,true);
|
||||
NodePath owner = state->get_node_owner_path(i);
|
||||
Ref<PackedScene> instance = state->get_node_instance(i);
|
||||
Vector<StringName> groups = state->get_node_groups(i);
|
||||
|
||||
String header="[node";
|
||||
header+=" name=\""+String(name)+"\"";
|
||||
if (type!=StringName()) {
|
||||
header+=" type=\""+String(type)+"\"";
|
||||
}
|
||||
if (path!=NodePath()) {
|
||||
header+=" parent=\""+String(path.simplified())+"\"";
|
||||
}
|
||||
if (owner!=NodePath() && owner!=NodePath(".")) {
|
||||
header+=" owner=\""+String(owner.simplified())+"\"";
|
||||
}
|
||||
|
||||
if (groups.size()) {
|
||||
String sgroups=" groups=[ ";
|
||||
for(int j=0;j<groups.size();j++) {
|
||||
if (j>0)
|
||||
sgroups+=", ";
|
||||
sgroups+="\""+groups[i].operator String().c_escape()+"\"";
|
||||
}
|
||||
sgroups+=" ]";
|
||||
header+=sgroups;
|
||||
}
|
||||
|
||||
f->store_string(header);
|
||||
|
||||
if (instance.is_valid()) {
|
||||
f->store_string(" instance=");
|
||||
write_property("",instance);
|
||||
}
|
||||
|
||||
f->store_line("]\n");
|
||||
|
||||
for(int j=0;j<state->get_node_property_count(i);j++) {
|
||||
|
||||
write_property(state->get_node_property_name(i,j),state->get_node_property_value(i,j));
|
||||
f->store_line(String());
|
||||
|
||||
}
|
||||
|
||||
if (state->get_node_property_count(i)) {
|
||||
//add space
|
||||
f->store_line(String());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for(int i=0;i<state->get_connection_count();i++) {
|
||||
|
||||
String connstr="[connection";
|
||||
connstr+=" signal=\""+String(state->get_connection_signal(i))+"\"";
|
||||
connstr+=" from=\""+String(state->get_connection_source(i).simplified())+"\"";
|
||||
connstr+=" to=\""+String(state->get_connection_target(i).simplified())+"\"";
|
||||
connstr+=" method=\""+String(state->get_connection_method(i))+"\"";
|
||||
int flags = state->get_connection_flags(i);
|
||||
if (flags!=Object::CONNECT_PERSIST) {
|
||||
connstr+=" flags="+itos(flags);
|
||||
}
|
||||
|
||||
Array binds=state->get_connection_binds(i);
|
||||
f->store_string(connstr);
|
||||
if (binds.size()) {
|
||||
f->store_string(" binds=");
|
||||
write_property("",binds);
|
||||
}
|
||||
|
||||
f->store_line("]\n");
|
||||
}
|
||||
|
||||
f->store_line(String());
|
||||
|
||||
Vector<NodePath> editable_instances = state->get_editable_instances();
|
||||
for(int i=0;i<editable_instances.size();i++) {
|
||||
f->store_line("[editable path=\""+editable_instances[i].operator String()+"\"]");
|
||||
}
|
||||
}
|
||||
|
||||
if (f->get_error()!=OK && f->get_error()!=ERR_FILE_EOF) {
|
||||
f->close();
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
|
||||
f->close();
|
||||
//memdelete(f);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Error ResourceFormatSaverText::save(const String &p_path,const RES& p_resource,uint32_t p_flags) {
|
||||
|
||||
if (p_path.ends_with(".sct") && p_resource->get_type()!="PackedScene") {
|
||||
return ERR_FILE_UNRECOGNIZED;
|
||||
}
|
||||
|
||||
ResourceFormatSaverTextInstance saver;
|
||||
return saver.save(p_path,p_resource,p_flags);
|
||||
|
||||
}
|
||||
|
||||
bool ResourceFormatSaverText::recognize(const RES& p_resource) const {
|
||||
|
||||
|
||||
return true; // all recognized!
|
||||
}
|
||||
void ResourceFormatSaverText::get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const {
|
||||
|
||||
p_extensions->push_back("tres"); //text resource
|
||||
if (p_resource->get_type()=="PackedScene")
|
||||
p_extensions->push_back("tscn"); //text scene
|
||||
|
||||
}
|
||||
|
||||
ResourceFormatSaverText* ResourceFormatSaverText::singleton=NULL;
|
||||
ResourceFormatSaverText::ResourceFormatSaverText() {
|
||||
singleton=this;
|
||||
}
|
46
scene/resources/scene_format_text.h
Normal file
46
scene/resources/scene_format_text.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
#ifndef SCENE_FORMAT_TEXT_H
|
||||
#define SCENE_FORMAT_TEXT_H
|
||||
|
||||
#include "io/resource_loader.h"
|
||||
#include "io/resource_saver.h"
|
||||
#include "os/file_access.h"
|
||||
#include "scene/resources/packed_scene.h"
|
||||
|
||||
class ResourceFormatSaverTextInstance {
|
||||
|
||||
String local_path;
|
||||
|
||||
Ref<PackedScene> packed_scene;
|
||||
|
||||
bool takeover_paths;
|
||||
bool relative_paths;
|
||||
bool bundle_resources;
|
||||
bool skip_editor;
|
||||
FileAccess *f;
|
||||
Set<RES> resource_set;
|
||||
List<RES> saved_resources;
|
||||
Map<RES,int> external_resources;
|
||||
Map<RES,int> internal_resources;
|
||||
|
||||
void _find_resources(const Variant& p_variant,bool p_main=false);
|
||||
void write_property(const String& p_name,const Variant& p_property,bool *r_ok=NULL);
|
||||
|
||||
public:
|
||||
|
||||
Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0);
|
||||
|
||||
|
||||
};
|
||||
|
||||
class ResourceFormatSaverText : public ResourceFormatSaver {
|
||||
public:
|
||||
static ResourceFormatSaverText* singleton;
|
||||
virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0);
|
||||
virtual bool recognize(const RES& p_resource) const;
|
||||
virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const;
|
||||
|
||||
ResourceFormatSaverText();
|
||||
};
|
||||
|
||||
|
||||
#endif // SCENE_FORMAT_TEXT_H
|
|
@ -194,7 +194,6 @@ bool BodyPairSW::_test_ccd(float p_step,BodySW *p_A, int p_shape_A,const Transfo
|
|||
|
||||
//cast a segment from support in motion normal, in the same direction of motion by motion length
|
||||
//support is the worst case collision point, so real collision happened before
|
||||
int a;
|
||||
Vector3 s=p_A->get_shape(p_shape_A)->get_support(p_xform_A.basis.xform(mnormal).normalized());
|
||||
Vector3 from = p_xform_A.xform(s);
|
||||
Vector3 to = from + motion;
|
||||
|
|
|
@ -34,10 +34,10 @@
|
|||
|
||||
_FORCE_INLINE_ static bool _match_object_type_query(CollisionObjectSW *p_object, uint32_t p_layer_mask, uint32_t p_type_mask) {
|
||||
|
||||
if ((p_object->get_layer_mask()&p_layer_mask)==0)
|
||||
return false;
|
||||
if (p_object->get_type()==CollisionObjectSW::TYPE_AREA)
|
||||
return p_type_mask&PhysicsDirectSpaceState::TYPE_MASK_AREA;
|
||||
|
||||
if (p_object->get_type()==CollisionObjectSW::TYPE_AREA && !(p_type_mask&PhysicsDirectSpaceState::TYPE_MASK_AREA))
|
||||
if ((p_object->get_layer_mask()&p_layer_mask)==0)
|
||||
return false;
|
||||
|
||||
BodySW *body = static_cast<BodySW*>(p_object);
|
||||
|
|
|
@ -279,6 +279,18 @@ void PinJoint2DSW::solve(float p_step){
|
|||
P += impulse;
|
||||
}
|
||||
|
||||
void PinJoint2DSW::set_param(Physics2DServer::PinJointParam p_param, real_t p_value) {
|
||||
|
||||
if(p_param == Physics2DServer::PIN_JOINT_SOFTNESS)
|
||||
softness = p_value;
|
||||
}
|
||||
|
||||
real_t PinJoint2DSW::get_param(Physics2DServer::PinJointParam p_param) const {
|
||||
|
||||
if(p_param == Physics2DServer::PIN_JOINT_SOFTNESS)
|
||||
return softness;
|
||||
ERR_FAIL_V(0);
|
||||
}
|
||||
|
||||
PinJoint2DSW::PinJoint2DSW(const Vector2& p_pos,Body2DSW* p_body_a,Body2DSW* p_body_b) : Joint2DSW(_arr,p_body_b?2:1) {
|
||||
|
||||
|
|
|
@ -121,6 +121,8 @@ public:
|
|||
virtual bool setup(float p_step);
|
||||
virtual void solve(float p_step);
|
||||
|
||||
void set_param(Physics2DServer::PinJointParam p_param, real_t p_value);
|
||||
real_t get_param(Physics2DServer::PinJointParam p_param) const;
|
||||
|
||||
PinJoint2DSW(const Vector2& p_pos,Body2DSW* p_body_a,Body2DSW* p_body_b=NULL);
|
||||
~PinJoint2DSW();
|
||||
|
|
|
@ -1096,6 +1096,25 @@ RID Physics2DServerSW::damped_spring_joint_create(const Vector2& p_anchor_a,cons
|
|||
|
||||
}
|
||||
|
||||
void Physics2DServerSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) {
|
||||
|
||||
Joint2DSW *j = joint_owner.get(p_joint);
|
||||
ERR_FAIL_COND(!j);
|
||||
ERR_FAIL_COND(j->get_type()!=JOINT_PIN);
|
||||
|
||||
PinJoint2DSW *pin_joint = static_cast<PinJoint2DSW*>(j);
|
||||
pin_joint->set_param(p_param, p_value);
|
||||
}
|
||||
|
||||
real_t Physics2DServerSW::pin_joint_get_param(RID p_joint, PinJointParam p_param) const {
|
||||
Joint2DSW *j = joint_owner.get(p_joint);
|
||||
ERR_FAIL_COND_V(!j,0);
|
||||
ERR_FAIL_COND_V(j->get_type()!=JOINT_PIN,0);
|
||||
|
||||
PinJoint2DSW *pin_joint = static_cast<PinJoint2DSW*>(j);
|
||||
return pin_joint->get_param(p_param);
|
||||
}
|
||||
|
||||
void Physics2DServerSW::damped_string_joint_set_param(RID p_joint, DampedStringParam p_param, real_t p_value) {
|
||||
|
||||
|
||||
|
|
|
@ -243,6 +243,8 @@ public:
|
|||
virtual RID pin_joint_create(const Vector2& p_pos,RID p_body_a,RID p_body_b=RID());
|
||||
virtual RID groove_joint_create(const Vector2& p_a_groove1,const Vector2& p_a_groove2, const Vector2& p_b_anchor, RID p_body_a,RID p_body_b);
|
||||
virtual RID damped_spring_joint_create(const Vector2& p_anchor_a,const Vector2& p_anchor_b,RID p_body_a,RID p_body_b=RID());
|
||||
virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value);
|
||||
virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const;
|
||||
virtual void damped_string_joint_set_param(RID p_joint, DampedStringParam p_param, real_t p_value);
|
||||
virtual real_t damped_string_joint_get_param(RID p_joint, DampedStringParam p_param) const;
|
||||
|
||||
|
|
|
@ -258,6 +258,9 @@ public:
|
|||
FUNC5R(RID,groove_joint_create,const Vector2&,const Vector2&,const Vector2&,RID,RID);
|
||||
FUNC4R(RID,damped_spring_joint_create,const Vector2&,const Vector2&,RID,RID);
|
||||
|
||||
FUNC3(pin_joint_set_param,RID,PinJointParam,real_t);
|
||||
FUNC2RC(real_t,pin_joint_get_param,RID,PinJointParam);
|
||||
|
||||
FUNC3(damped_string_joint_set_param,RID,DampedStringParam,real_t);
|
||||
FUNC2RC(real_t,damped_string_joint_get_param,RID,DampedStringParam);
|
||||
|
||||
|
|
|
@ -36,8 +36,8 @@ _FORCE_INLINE_ static bool _match_object_type_query(CollisionObject2DSW *p_objec
|
|||
if ((p_object->get_layer_mask()&p_layer_mask)==0)
|
||||
return false;
|
||||
|
||||
if (p_object->get_type()==CollisionObject2DSW::TYPE_AREA && !(p_type_mask&Physics2DDirectSpaceState::TYPE_MASK_AREA))
|
||||
return false;
|
||||
if (p_object->get_type()==CollisionObject2DSW::TYPE_AREA)
|
||||
return p_type_mask&Physics2DDirectSpaceState::TYPE_MASK_AREA;
|
||||
|
||||
Body2DSW *body = static_cast<Body2DSW*>(p_object);
|
||||
|
||||
|
|
|
@ -516,6 +516,13 @@ public:
|
|||
virtual RID groove_joint_create(const Vector2& p_a_groove1,const Vector2& p_a_groove2, const Vector2& p_b_anchor, RID p_body_a,RID p_body_b)=0;
|
||||
virtual RID damped_spring_joint_create(const Vector2& p_anchor_a,const Vector2& p_anchor_b,RID p_body_a,RID p_body_b=RID())=0;
|
||||
|
||||
enum PinJointParam {
|
||||
PIN_JOINT_SOFTNESS
|
||||
};
|
||||
|
||||
virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value)=0;
|
||||
virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const=0;
|
||||
|
||||
enum DampedStringParam {
|
||||
DAMPED_STRING_REST_LENGTH,
|
||||
DAMPED_STRING_STIFFNESS,
|
||||
|
|
|
@ -5219,7 +5219,6 @@ void VisualServerRaster::_light_instance_update_lispsm_shadow(Instance *p_light,
|
|||
|
||||
|
||||
AABB proj_space_aabb;
|
||||
float max_d,min_d;
|
||||
|
||||
{
|
||||
|
||||
|
@ -6824,7 +6823,11 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
|
|||
copymem(child_items,ci->child_items.ptr(),child_item_count*sizeof(CanvasItem*));
|
||||
|
||||
if (ci->clip) {
|
||||
ci->final_clip_rect=global_rect;
|
||||
if (p_canvas_clip != NULL) {
|
||||
ci->final_clip_rect=p_canvas_clip->final_clip_rect.clip(global_rect);
|
||||
} else {
|
||||
ci->final_clip_rect=global_rect;
|
||||
}
|
||||
ci->final_clip_owner=ci;
|
||||
|
||||
} else {
|
||||
|
|
BIN
tools/docdump/locales/es/LC_MESSAGES/makedocs.mo
Normal file
BIN
tools/docdump/locales/es/LC_MESSAGES/makedocs.mo
Normal file
Binary file not shown.
142
tools/docdump/locales/es/LC_MESSAGES/makedocs.po
Normal file
142
tools/docdump/locales/es/LC_MESSAGES/makedocs.po
Normal file
|
@ -0,0 +1,142 @@
|
|||
# Translations template for PROJECT.
|
||||
# Copyright (C) 2015 ORGANIZATION
|
||||
# This file is distributed under the same license as the PROJECT project.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: makedocs\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2015-10-07 11:47-0600\n"
|
||||
"PO-Revision-Date: 2015-10-07 13:10-0600\n"
|
||||
"Last-Translator: Jorge Araya Navarro <elcorreo@deshackra.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.0\n"
|
||||
"X-Generator: Poedit 1.8.4\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: makedocs.py:74
|
||||
msgid ""
|
||||
"\"<code>{gclass}</code>(Go to page of class {gclass})\":/class_{lkclass}"
|
||||
msgstr ""
|
||||
"\"<code>{gclass}</code>(Ir a la pagina de la clase {gclass})\":/"
|
||||
"class_{lkclass}"
|
||||
|
||||
#: makedocs.py:76
|
||||
msgid ""
|
||||
"\"<code>{gclass}.{method}</code>(Go to page {gclass}, section {method})\":/"
|
||||
"class_{lkclass}#{lkmethod}"
|
||||
msgstr ""
|
||||
"\"<code>{gclass}.{method}</code>(Ir a la pagina {gclass}, sección "
|
||||
"{method})\":/class_{lkclass}#{lkmethod}"
|
||||
|
||||
#: makedocs.py:79
|
||||
msgid "\"<code>{method}</code>(Jump to method {method})\":#{lkmethod}"
|
||||
msgstr "\"<code>{method}</code>(Saltar al método {method})\":#{lkmethod}"
|
||||
|
||||
#: makedocs.py:81
|
||||
msgid " \"{rtype}(Go to page of class {rtype})\":/class_{link} "
|
||||
msgstr " \"{rtype}(Ir a la pagina de la clase {rtype})\":/class_{link} "
|
||||
|
||||
#: makedocs.py:82
|
||||
msgid ""
|
||||
"\"*{funcname}*(Jump to description for node {funcname})\":#{link} <b>(</b> "
|
||||
msgstr ""
|
||||
"\"*{funcname}*(Saltar a la descripción para el nodo {funcname})\":#{link} "
|
||||
"<b>(</b> "
|
||||
|
||||
#: makedocs.py:87
|
||||
msgid "h4. Inherits: "
|
||||
msgstr "h4. Hereda de: "
|
||||
|
||||
#: makedocs.py:232
|
||||
msgid "<doc>'s version attribute missing"
|
||||
msgstr "El atributo version de <doc> no existe"
|
||||
|
||||
#: makedocs.py:246
|
||||
msgid "|_. Index symbol |_. Class name |_. Index symbol |_. Class name |\n"
|
||||
msgstr ""
|
||||
"|_. Índice de símbolo |_. Nombre de la clase |_. Índice de símbolo |_. "
|
||||
"Nombre de la clase |\n"
|
||||
|
||||
#: makedocs.py:305
|
||||
msgid ""
|
||||
"h4. Category: {}\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"h4. Categoría: {}\n"
|
||||
"\n"
|
||||
|
||||
#: makedocs.py:310
|
||||
msgid ""
|
||||
"h2. Brief Description\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"h2. Descripción breve\n"
|
||||
"\n"
|
||||
|
||||
#: makedocs.py:312
|
||||
msgid ""
|
||||
"\"read more\":#more\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"\"Leer más\":#more\n"
|
||||
"\n"
|
||||
|
||||
#: makedocs.py:317
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Member Functions\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"h3. Funciones miembro\n"
|
||||
"\n"
|
||||
|
||||
#: makedocs.py:323
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Signals\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"h3. Señales\n"
|
||||
"\n"
|
||||
|
||||
#: makedocs.py:331
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Numeric Constants\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"h3. Constantes numéricas\n"
|
||||
"\n"
|
||||
|
||||
#: makedocs.py:347
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3(#more). Description\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"h3(#more). Descripción\n"
|
||||
"\n"
|
||||
|
||||
#: makedocs.py:351
|
||||
msgid "_Nothing here, yet..._\n"
|
||||
msgstr "_Aún nada por aquí..._\n"
|
||||
|
||||
#: makedocs.py:355
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Member Function Description\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"h3. Descripción de las funciones miembro\n"
|
||||
"\n"
|
108
tools/docdump/makedocs.pot
Normal file
108
tools/docdump/makedocs.pot
Normal file
|
@ -0,0 +1,108 @@
|
|||
# Translations template for PROJECT.
|
||||
# Copyright (C) 2015 ORGANIZATION
|
||||
# This file is distributed under the same license as the PROJECT project.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: makedocs 0.1\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2015-10-07 11:47-0600\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.0\n"
|
||||
"X-Generator: Poedit 1.8.4\n"
|
||||
|
||||
#: makedocs.py:74
|
||||
msgid "\"<code>{gclass}</code>(Go to page of class {gclass})\":/class_{lkclass}"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:76
|
||||
msgid "\"<code>{gclass}.{method}</code>(Go to page {gclass}, section {method})\":/class_{lkclass}#{lkmethod}"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:79
|
||||
msgid "\"<code>{method}</code>(Jump to method {method})\":#{lkmethod}"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:81
|
||||
msgid " \"{rtype}(Go to page of class {rtype})\":/class_{link} "
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:82
|
||||
msgid "\"*{funcname}*(Jump to description for node {funcname})\":#{link} <b>(</b> "
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:87
|
||||
msgid "h4. Inherits: "
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:232
|
||||
msgid "<doc>'s version attribute missing"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:246
|
||||
msgid "|_. Index symbol |_. Class name |_. Index symbol |_. Class name |\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:305
|
||||
msgid ""
|
||||
"h4. Category: {}\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:310
|
||||
msgid ""
|
||||
"h2. Brief Description\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:312
|
||||
msgid ""
|
||||
"\"read more\":#more\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:317
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Member Functions\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:323
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Signals\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:331
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Numeric Constants\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:347
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3(#more). Description\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:351
|
||||
msgid "_Nothing here, yet..._\n"
|
||||
msgstr ""
|
||||
|
||||
#: makedocs.py:355
|
||||
msgid ""
|
||||
"\n"
|
||||
"h3. Member Function Description\n"
|
||||
"\n"
|
||||
msgstr ""
|
382
tools/docdump/makedocs.py
Normal file
382
tools/docdump/makedocs.py
Normal file
|
@ -0,0 +1,382 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# makedocs.py: Generate documentation for Open Project Wiki
|
||||
# Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur.
|
||||
# Contributor: Jorge Araya Navarro <elcorreo@deshackra.com>
|
||||
#
|
||||
|
||||
# IMPORTANT NOTICE:
|
||||
# If you are going to modify anything from this file, please be sure to follow
|
||||
# the Style Guide for Python Code or often called "PEP8". To do this
|
||||
# automagically just install autopep8:
|
||||
#
|
||||
# $ sudo pip3 install autopep8
|
||||
#
|
||||
# and run:
|
||||
#
|
||||
# $ autopep8 makedocs.py
|
||||
#
|
||||
# Before committing your changes. Also be sure to delete any trailing
|
||||
# whitespace you may left.
|
||||
#
|
||||
# TODO:
|
||||
# * Refactor code.
|
||||
# * Adapt this script for generating content in other markup formats like
|
||||
# DokuWiki, Markdown, etc.
|
||||
#
|
||||
# Also check other TODO entries in this script for more information on what is
|
||||
# left to do.
|
||||
import argparse
|
||||
import gettext
|
||||
import logging
|
||||
import re
|
||||
from itertools import zip_longest
|
||||
from os import path, listdir
|
||||
from xml.etree import ElementTree
|
||||
|
||||
|
||||
# add an option to change the verbosity
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
|
||||
def getxmlfloc():
|
||||
""" Returns the supposed location of the XML file
|
||||
"""
|
||||
filepath = path.dirname(path.abspath(__file__))
|
||||
return path.join(filepath, "class_list.xml")
|
||||
|
||||
|
||||
def langavailable():
|
||||
""" Return a list of languages available for translation
|
||||
"""
|
||||
filepath = path.join(
|
||||
path.dirname(path.abspath(__file__)), "locales")
|
||||
files = listdir(filepath)
|
||||
choices = [x for x in files]
|
||||
choices.insert(0, "none")
|
||||
return choices
|
||||
|
||||
|
||||
desc = "Generates documentation from a XML file to different markup languages"
|
||||
|
||||
parser = argparse.ArgumentParser(description=desc)
|
||||
parser.add_argument("--input", dest="xmlfp", default=getxmlfloc(),
|
||||
help="Input XML file, default: {}".format(getxmlfloc()))
|
||||
parser.add_argument("--output-dir", dest="outputdir", required=True,
|
||||
help="Output directory for generated files")
|
||||
parser.add_argument("--language", choices=langavailable(), default="none",
|
||||
help=("Choose the language of translation"
|
||||
" for the output files. Default is English (none). "
|
||||
"Note: This is NOT for the documentation itself!"))
|
||||
# TODO: add an option for outputting different markup formats
|
||||
|
||||
args = parser.parse_args()
|
||||
# Let's check if the file and output directory exists
|
||||
if not path.isfile(args.xmlfp):
|
||||
logging.critical("File not found: {}".format(args.xmlfp))
|
||||
exit(1)
|
||||
elif not path.isdir(args.outputdir):
|
||||
logging.critical("Path does not exist: {}".format(args.outputdir))
|
||||
exit(1)
|
||||
|
||||
_ = gettext.gettext
|
||||
if args.language != "none":
|
||||
lang = gettext.translation(domain="makedocs",
|
||||
localedir="locales",
|
||||
languages=[args.language])
|
||||
lang.install()
|
||||
|
||||
_ = lang.gettext
|
||||
|
||||
# Strings
|
||||
C_LINK = _("\"<code>{gclass}</code>(Go to page of class"
|
||||
" {gclass})\":/class_{lkclass}")
|
||||
MC_LINK = _("\"<code>{gclass}.{method}</code>(Go "
|
||||
"to page {gclass}, section {method})\""
|
||||
":/class_{lkclass}#{lkmethod}")
|
||||
TM_JUMP = _("\"<code>{method}</code>(Jump to method"
|
||||
" {method})\":#{lkmethod}")
|
||||
GTC_LINK = _(" \"{rtype}(Go to page of class {rtype})\":/class_{link} ")
|
||||
DFN_JUMP = _("\"*{funcname}*(Jump to description for"
|
||||
" node {funcname})\":#{link} <b>(</b> ")
|
||||
M_ARG_DEFAULT = C_LINK + " {name}={default}"
|
||||
M_ARG = C_LINK + " {name}"
|
||||
|
||||
OPENPROJ_INH = _("h4. Inherits: ") + C_LINK + "\n\n"
|
||||
|
||||
|
||||
def tb(string):
|
||||
""" Return a byte representation of a string
|
||||
"""
|
||||
return bytes(string, "UTF-8")
|
||||
|
||||
|
||||
def sortkey(c):
|
||||
""" Symbols are first, letters second
|
||||
"""
|
||||
if "_" == c.attrib["name"][0]:
|
||||
return "A"
|
||||
else:
|
||||
return c.attrib["name"]
|
||||
|
||||
|
||||
def toOP(text):
|
||||
""" Convert commands in text to Open Project commands
|
||||
"""
|
||||
# TODO: Make this capture content between [command] ... [/command]
|
||||
groups = re.finditer((r'\[html (?P<command>/?\w+/?)(\]| |=)?(\]| |=)?(?P<a'
|
||||
'rg>\w+)?(\]| |=)?(?P<value>"[^"]+")?/?\]'), text)
|
||||
alignstr = ""
|
||||
for group in groups:
|
||||
gd = group.groupdict()
|
||||
if gd["command"] == "br/":
|
||||
text = text.replace(group.group(0), "\n\n", 1)
|
||||
elif gd["command"] == "div":
|
||||
if gd["value"] == '"center"':
|
||||
alignstr = ("{display:block; margin-left:auto;"
|
||||
" margin-right:auto;}")
|
||||
elif gd["value"] == '"left"':
|
||||
alignstr = "<"
|
||||
elif gd["value"] == '"right"':
|
||||
alignstr = ">"
|
||||
text = text.replace(group.group(0), "\n\n", 1)
|
||||
elif gd["command"] == "/div":
|
||||
alignstr = ""
|
||||
text = text.replace(group.group(0), "\n\n", 1)
|
||||
elif gd["command"] == "img":
|
||||
text = text.replace(group.group(0), "!{align}{src}!".format(
|
||||
align=alignstr, src=gd["value"].strip('"')), 1)
|
||||
elif gd["command"] == "b" or gd["command"] == "/b":
|
||||
text = text.replace(group.group(0), "*", 1)
|
||||
elif gd["command"] == "i" or gd["command"] == "/i":
|
||||
text = text.replace(group.group(0), "_", 1)
|
||||
elif gd["command"] == "u" or gd["command"] == "/u":
|
||||
text = text.replace(group.group(0), "+", 1)
|
||||
# Process other non-html commands
|
||||
groups = re.finditer((r'\[method ((?P<class>[aA0-zZ9_]+)(?:\.))'
|
||||
r'?(?P<method>[aA0-zZ9_]+)\]'), text)
|
||||
for group in groups:
|
||||
gd = group.groupdict()
|
||||
if gd["class"]:
|
||||
replacewith = (MC_LINK.format(gclass=gd["class"],
|
||||
method=gd["method"],
|
||||
lkclass=gd["class"].lower(),
|
||||
lkmethod=gd["method"].lower()))
|
||||
else:
|
||||
# The method is located in the same wiki page
|
||||
replacewith = (TM_JUMP.format(method=gd["method"],
|
||||
lkmethod=gd["method"].lower()))
|
||||
|
||||
text = text.replace(group.group(0), replacewith, 1)
|
||||
# Finally, [Classes] are around brackets, make them direct links
|
||||
groups = re.finditer(r'\[(?P<class>[az0-AZ0_]+)\]', text)
|
||||
for group in groups:
|
||||
gd = group.groupdict()
|
||||
replacewith = (C_LINK.
|
||||
format(gclass=gd["class"],
|
||||
lkclass=gd["class"].lower()))
|
||||
text = text.replace(group.group(0), replacewith, 1)
|
||||
|
||||
return text + "\n\n"
|
||||
|
||||
|
||||
def mkfn(node, is_signal=False):
|
||||
""" Return a string containing a unsorted item for a function
|
||||
"""
|
||||
finalstr = ""
|
||||
name = node.attrib["name"]
|
||||
rtype = node.find("return")
|
||||
if rtype:
|
||||
rtype = rtype.attrib["type"]
|
||||
else:
|
||||
rtype = "void"
|
||||
# write the return type and the function name first
|
||||
finalstr += "* "
|
||||
# return type
|
||||
if not is_signal:
|
||||
if rtype != "void":
|
||||
finalstr += GTC_LINK.format(
|
||||
rtype=rtype,
|
||||
link=rtype.lower())
|
||||
else:
|
||||
finalstr += " void "
|
||||
|
||||
# function name
|
||||
if not is_signal:
|
||||
finalstr += DFN_JUMP.format(
|
||||
funcname=name,
|
||||
link=name.lower())
|
||||
else:
|
||||
# Signals have no description
|
||||
finalstr += "*{funcname}* <b>(</b>".format(funcname=name)
|
||||
# loop for the arguments of the function, if any
|
||||
args = []
|
||||
for arg in sorted(
|
||||
node.iter(tag="argument"),
|
||||
key=lambda a: int(a.attrib["index"])):
|
||||
|
||||
ntype = arg.attrib["type"]
|
||||
nname = arg.attrib["name"]
|
||||
|
||||
if "default" in arg.attrib:
|
||||
args.insert(-1, M_ARG_DEFAULT.format(
|
||||
gclass=ntype,
|
||||
lkclass=ntype.lower(),
|
||||
name=nname,
|
||||
default=arg.attrib["default"]))
|
||||
else:
|
||||
# No default value present
|
||||
args.insert(-1, M_ARG.format(gclass=ntype,
|
||||
lkclass=ntype.lower(), name=nname))
|
||||
# join the arguments together
|
||||
finalstr += ", ".join(args)
|
||||
# and, close the function with a )
|
||||
finalstr += " <b>)</b>"
|
||||
# write the qualifier, if any
|
||||
if "qualifiers" in node.attrib:
|
||||
qualifier = node.attrib["qualifiers"]
|
||||
finalstr += " " + qualifier
|
||||
|
||||
finalstr += "\n"
|
||||
|
||||
return finalstr
|
||||
|
||||
# Let's begin
|
||||
tree = ElementTree.parse(args.xmlfp)
|
||||
root = tree.getroot()
|
||||
|
||||
# Check version attribute exists in <doc>
|
||||
if "version" not in root.attrib:
|
||||
logging.critical(_("<doc>'s version attribute missing"))
|
||||
exit(1)
|
||||
|
||||
version = root.attrib["version"]
|
||||
classes = sorted(root, key=sortkey)
|
||||
# first column is always longer, second column of classes should be shorter
|
||||
zclasses = zip_longest(classes[:int(len(classes) / 2 + 1)],
|
||||
classes[int(len(classes) / 2 + 1):],
|
||||
fillvalue="")
|
||||
|
||||
# We write the class_list file and also each class file at once
|
||||
with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl:
|
||||
# Write header of table
|
||||
fcl.write(tb("|^.\n"))
|
||||
fcl.write(tb(_("|_. Index symbol |_. Class name "
|
||||
"|_. Index symbol |_. Class name |\n")))
|
||||
fcl.write(tb("|-.\n"))
|
||||
|
||||
indexletterl = ""
|
||||
indexletterr = ""
|
||||
for gdclassl, gdclassr in zclasses:
|
||||
# write a row #
|
||||
# write the index symbol column, left
|
||||
if indexletterl != gdclassl.attrib["name"][0]:
|
||||
indexletterl = gdclassl.attrib["name"][0]
|
||||
fcl.write(tb("| *{}* |".format(indexletterl.upper())))
|
||||
else:
|
||||
# empty cell
|
||||
fcl.write(tb("| |"))
|
||||
# write the class name column, left
|
||||
fcl.write(tb(C_LINK.format(
|
||||
gclass=gdclassl.attrib["name"],
|
||||
lkclass=gdclassl.attrib["name"].lower())))
|
||||
|
||||
# write the index symbol column, right
|
||||
if isinstance(gdclassr, ElementTree.Element):
|
||||
if indexletterr != gdclassr.attrib["name"][0]:
|
||||
indexletterr = gdclassr.attrib["name"][0]
|
||||
fcl.write(tb("| *{}* |".format(indexletterr.upper())))
|
||||
else:
|
||||
# empty cell
|
||||
fcl.write(tb("| |"))
|
||||
# We are dealing with an empty string
|
||||
else:
|
||||
# two empty cell
|
||||
fcl.write(tb("| | |\n"))
|
||||
# We won't get the name of the class since there is no ElementTree
|
||||
# object for the right side of the tuple, so we iterate the next
|
||||
# tuple instead
|
||||
continue
|
||||
|
||||
# write the class name column (if any), right
|
||||
fcl.write(tb(C_LINK.format(
|
||||
gclass=gdclassl.attrib["name"],
|
||||
lkclass=gdclassl.attrib["name"].lower()) + "|\n"))
|
||||
|
||||
# row written #
|
||||
# now, let's write each class page for each class
|
||||
for gdclass in [gdclassl, gdclassr]:
|
||||
if not isinstance(gdclass, ElementTree.Element):
|
||||
continue
|
||||
|
||||
classname = gdclass.attrib["name"]
|
||||
with open(path.join(args.outputdir, "{}.txt".format(
|
||||
classname.lower())), "wb") as clsf:
|
||||
# First level header with the name of the class
|
||||
clsf.write(tb("h1. {}\n\n".format(classname)))
|
||||
# lay the attributes
|
||||
if "inherits" in gdclass.attrib:
|
||||
inh = gdclass.attrib["inherits"].strip()
|
||||
clsf.write(tb(OPENPROJ_INH.format(gclass=inh,
|
||||
lkclass=inh.lower())))
|
||||
if "category" in gdclass.attrib:
|
||||
clsf.write(tb(_("h4. Category: {}\n\n").
|
||||
format(gdclass.attrib["category"].strip())))
|
||||
# lay child nodes
|
||||
briefd = gdclass.find("brief_description")
|
||||
if briefd.text.strip():
|
||||
clsf.write(tb(_("h2. Brief Description\n\n")))
|
||||
clsf.write(tb(toOP(briefd.text.strip()) +
|
||||
_("\"read more\":#more\n\n")))
|
||||
|
||||
# Write the list of member functions of this class
|
||||
methods = gdclass.find("methods")
|
||||
if methods and len(methods) > 0:
|
||||
clsf.write(tb(_("\nh3. Member Functions\n\n")))
|
||||
for method in methods.iter(tag='method'):
|
||||
clsf.write(tb(mkfn(method)))
|
||||
|
||||
signals = gdclass.find("signals")
|
||||
if signals and len(signals) > 0:
|
||||
clsf.write(tb(_("\nh3. Signals\n\n")))
|
||||
for signal in signals.iter(tag='signal'):
|
||||
clsf.write(tb(mkfn(signal, True)))
|
||||
# TODO: <members> tag is necessary to process? it does not
|
||||
# exists in class_list.xml file.
|
||||
|
||||
consts = gdclass.find("constants")
|
||||
if consts and len(consts) > 0:
|
||||
clsf.write(tb(_("\nh3. Numeric Constants\n\n")))
|
||||
for const in sorted(consts, key=lambda k:
|
||||
k.attrib["name"]):
|
||||
if const.text.strip():
|
||||
clsf.write(tb("* *{name}* = *{value}* - {desc}\n".
|
||||
format(
|
||||
name=const.attrib["name"],
|
||||
value=const.attrib["value"],
|
||||
desc=const.text.strip())))
|
||||
else:
|
||||
# Constant have no description
|
||||
clsf.write(tb("* *{name}* = *{value}*\n".
|
||||
format(
|
||||
name=const.attrib["name"],
|
||||
value=const.attrib["value"])))
|
||||
descrip = gdclass.find("description")
|
||||
clsf.write(tb(_("\nh3(#more). Description\n\n")))
|
||||
if descrip.text:
|
||||
clsf.write(tb(descrip.text.strip() + "\n"))
|
||||
else:
|
||||
clsf.write(tb(_("_Nothing here, yet..._\n")))
|
||||
|
||||
# and finally, the description for each method
|
||||
if methods and len(methods) > 0:
|
||||
clsf.write(tb(_("\nh3. Member Function Description\n\n")))
|
||||
for method in methods.iter(tag='method'):
|
||||
clsf.write(tb("h4(#{n}). {name}\n\n".format(
|
||||
n=method.attrib["name"].lower(),
|
||||
name=method.attrib["name"])))
|
||||
clsf.write(tb(mkfn(method) + "\n"))
|
||||
clsf.write(tb(toOP(method.find(
|
||||
"description").text.strip())))
|
|
@ -547,6 +547,7 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
|
|||
class_desc->pop();
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
|
||||
}
|
||||
|
||||
|
@ -563,6 +564,7 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
|
|||
_add_text(cd.brief_description);
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
}
|
||||
|
||||
bool method_descr=false;
|
||||
|
@ -637,7 +639,6 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
|
|||
|
||||
if (cd.properties.size()) {
|
||||
|
||||
|
||||
class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/keyword_color"));
|
||||
class_desc->push_font(doc_title_font);
|
||||
class_desc->add_text("Members:");
|
||||
|
@ -715,9 +716,10 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
|
|||
class_desc->add_newline();
|
||||
}
|
||||
|
||||
class_desc->add_newline();
|
||||
class_desc->pop();
|
||||
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
|
||||
}
|
||||
if (cd.signals.size()) {
|
||||
|
@ -779,6 +781,7 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
|
|||
|
||||
class_desc->pop();
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
|
||||
}
|
||||
|
||||
|
@ -823,6 +826,7 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
|
|||
|
||||
class_desc->pop();
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
|
||||
|
||||
}
|
||||
|
@ -830,17 +834,18 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
|
|||
if (cd.description!="") {
|
||||
|
||||
description_line=class_desc->get_line_count()-2;
|
||||
|
||||
class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/keyword_color"));
|
||||
class_desc->push_font(doc_title_font);
|
||||
class_desc->add_text("Description:");
|
||||
class_desc->pop();
|
||||
class_desc->pop();
|
||||
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
_add_text(cd.description);
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
}
|
||||
|
||||
if (method_descr) {
|
||||
|
@ -853,12 +858,16 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
|
|||
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
class_desc->push_indent(1);
|
||||
|
||||
|
||||
for(int i=0;i<cd.methods.size();i++) {
|
||||
|
||||
method_line[cd.methods[i].name]=class_desc->get_line_count()-2;
|
||||
|
||||
if( cd.methods[i].description != "") {
|
||||
class_desc->add_newline();
|
||||
}
|
||||
class_desc->push_font(doc_code_font);
|
||||
_add_type(cd.methods[i].return_type);
|
||||
|
||||
|
@ -899,9 +908,12 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
|
|||
|
||||
class_desc->pop();
|
||||
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
_add_text(cd.methods[i].description);
|
||||
if( cd.methods[i].description != "") {
|
||||
class_desc->add_text(" ");
|
||||
_add_text(cd.methods[i].description);
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
}
|
||||
class_desc->add_newline();
|
||||
class_desc->add_newline();
|
||||
|
||||
|
@ -1392,6 +1404,8 @@ EditorHelp::EditorHelp(EditorNode *p_editor) {
|
|||
PanelContainer *pc = memnew( PanelContainer );
|
||||
Ref<StyleBoxFlat> style( memnew( StyleBoxFlat ) );
|
||||
style->set_bg_color( EditorSettings::get_singleton()->get("text_editor/background_color") );
|
||||
style->set_default_margin(MARGIN_LEFT,20);
|
||||
style->set_default_margin(MARGIN_TOP,20);
|
||||
pc->add_style_override("panel", style); //get_stylebox("normal","TextEdit"));
|
||||
h_split->add_child(pc);
|
||||
class_desc = memnew( RichTextLabel );
|
||||
|
|
|
@ -1108,6 +1108,11 @@ void EditorNode::_dialog_action(String p_file) {
|
|||
|
||||
push_item(res.operator->() );
|
||||
} break;
|
||||
case FILE_NEW_INHERITED_SCENE: {
|
||||
|
||||
|
||||
load_scene(p_file,false,true);
|
||||
} break;
|
||||
case FILE_OPEN_SCENE: {
|
||||
|
||||
|
||||
|
@ -1931,6 +1936,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
|
|||
|
||||
|
||||
} break;
|
||||
case FILE_NEW_INHERITED_SCENE:
|
||||
case FILE_OPEN_SCENE: {
|
||||
|
||||
|
||||
|
@ -1951,7 +1957,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
|
|||
if (scene) {
|
||||
file->set_current_path(scene->get_filename());
|
||||
};
|
||||
file->set_title("Open Scene");
|
||||
file->set_title(p_option==FILE_OPEN_SCENE?"Open Scene":"Open Base Scene");
|
||||
file->popup_centered_ratio();
|
||||
|
||||
} break;
|
||||
|
@ -3312,7 +3318,7 @@ void EditorNode::fix_dependencies(const String& p_for_file) {
|
|||
dependency_fixer->edit(p_for_file);
|
||||
}
|
||||
|
||||
Error EditorNode::load_scene(const String& p_scene, bool p_ignore_broken_deps) {
|
||||
Error EditorNode::load_scene(const String& p_scene, bool p_ignore_broken_deps,bool p_set_inherited) {
|
||||
|
||||
if (!is_inside_tree()) {
|
||||
defer_load_scene = p_scene;
|
||||
|
@ -3442,6 +3448,13 @@ Error EditorNode::load_scene(const String& p_scene, bool p_ignore_broken_deps) {
|
|||
}
|
||||
*/
|
||||
|
||||
if (p_set_inherited) {
|
||||
Ref<SceneState> state = sdata->get_state();
|
||||
state->set_path(lpath);
|
||||
new_scene->set_scene_inherited_state(state);
|
||||
}
|
||||
|
||||
|
||||
set_edited_scene(new_scene);
|
||||
_get_scene_metadata();
|
||||
/*
|
||||
|
@ -4404,6 +4417,7 @@ void EditorNode::_scene_tab_changed(int p_tab) {
|
|||
EditorNode::EditorNode() {
|
||||
|
||||
EditorHelp::generate_doc(); //before any editor classes are crated
|
||||
SceneState::set_disable_placeholders(true);
|
||||
|
||||
InputDefault *id = Input::get_singleton()->cast_to<InputDefault>();
|
||||
|
||||
|
@ -4794,6 +4808,7 @@ EditorNode::EditorNode() {
|
|||
file_menu->set_tooltip("Operations with scene files.");
|
||||
p=file_menu->get_popup();
|
||||
p->add_item("New Scene",FILE_NEW_SCENE);
|
||||
p->add_item("New Inherited Scene..",FILE_NEW_INHERITED_SCENE);
|
||||
p->add_item("Open Scene..",FILE_OPEN_SCENE,KEY_MASK_CMD+KEY_O);
|
||||
p->add_separator();
|
||||
p->add_item("Save Scene",FILE_SAVE_SCENE,KEY_MASK_CMD+KEY_S);
|
||||
|
|
|
@ -107,6 +107,7 @@ class EditorNode : public Node {
|
|||
enum MenuOptions {
|
||||
|
||||
FILE_NEW_SCENE,
|
||||
FILE_NEW_INHERITED_SCENE,
|
||||
FILE_OPEN_SCENE,
|
||||
FILE_SAVE_SCENE,
|
||||
FILE_SAVE_AS_SCENE,
|
||||
|
@ -565,7 +566,7 @@ public:
|
|||
|
||||
void fix_dependencies(const String& p_for_file);
|
||||
void clear_scene() { _cleanup_scene(); }
|
||||
Error load_scene(const String& p_scene,bool p_ignore_broken_deps=false);
|
||||
Error load_scene(const String& p_scene, bool p_ignore_broken_deps=false, bool p_set_inherited=false);
|
||||
Error load_resource(const String& p_scene);
|
||||
|
||||
bool is_scene_open(const String& p_path);
|
||||
|
|
|
@ -74,6 +74,7 @@ void EditorPlugin::add_custom_control(CustomControlContainer p_location,Control
|
|||
case CONTAINER_CANVAS_EDITOR_SIDE: {
|
||||
|
||||
CanvasItemEditor::get_singleton()->get_palette_split()->add_child(p_control);
|
||||
CanvasItemEditor::get_singleton()->get_palette_split()->move_child(p_control,0);
|
||||
|
||||
} break;
|
||||
case CONTAINER_CANVAS_EDITOR_BOTTOM: {
|
||||
|
|
|
@ -710,7 +710,7 @@ void EditorSampleImportPlugin::_compress_ima_adpcm(const Vector<float>& p_data,D
|
|||
*(out++) =0;
|
||||
|
||||
for (i=0;i<datalen;i++) {
|
||||
int step,diff,vpdiff,signed_nibble,p,mask;
|
||||
int step,diff,vpdiff,mask;
|
||||
uint8_t nibble;
|
||||
int16_t xm_sample;
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
#include "multi_node_edit.h"
|
||||
#include "array_property_edit.h"
|
||||
#include "editor_help.h"
|
||||
#include "scene/resources/packed_scene.h"
|
||||
|
||||
|
||||
void CustomPropertyEditor::_notification(int p_what) {
|
||||
|
||||
|
@ -1655,25 +1657,101 @@ CustomPropertyEditor::CustomPropertyEditor() {
|
|||
menu->connect("item_pressed",this,"_menu_option");
|
||||
}
|
||||
|
||||
bool PropertyEditor::_might_be_in_instance() {
|
||||
|
||||
|
||||
Node *PropertyEditor::get_instanced_node() {
|
||||
|
||||
//this sucks badly
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
Node *node = obj->cast_to<Node>();
|
||||
|
||||
Node* edited_scene =EditorNode::get_singleton()->get_edited_scene();
|
||||
|
||||
bool might_be=false;
|
||||
|
||||
while(node) {
|
||||
|
||||
if (node->get_scene_instance_state().is_valid()) {
|
||||
might_be=true;
|
||||
break;
|
||||
}
|
||||
if (node==edited_scene) {
|
||||
if (node->get_scene_inherited_state().is_valid()) {
|
||||
might_be=true;
|
||||
break;
|
||||
}
|
||||
might_be=false;
|
||||
break;
|
||||
}
|
||||
node=node->get_owner();
|
||||
}
|
||||
|
||||
return might_be;
|
||||
|
||||
}
|
||||
|
||||
bool PropertyEditor::_get_instanced_node_original_property(const StringName& p_prop,Variant& value) {
|
||||
|
||||
Node *node = obj->cast_to<Node>();
|
||||
|
||||
if (!node)
|
||||
return NULL;
|
||||
return false;
|
||||
|
||||
if (node->get_filename()=="")
|
||||
return NULL;
|
||||
Node *orig=node;
|
||||
|
||||
if (!node->get_owner())
|
||||
return NULL; //scene root i guess
|
||||
Node* edited_scene =EditorNode::get_singleton()->get_edited_scene();
|
||||
|
||||
return node;
|
||||
bool found=false;
|
||||
|
||||
// print_line("for prop - "+String(p_prop));
|
||||
|
||||
while(node) {
|
||||
|
||||
Ref<SceneState> ss;
|
||||
|
||||
if (node==edited_scene) {
|
||||
ss=node->get_scene_inherited_state();
|
||||
} else {
|
||||
ss=node->get_scene_instance_state();
|
||||
}
|
||||
// print_line("at - "+String(edited_scene->get_path_to(node)));
|
||||
|
||||
if (ss.is_valid()) {
|
||||
NodePath np = node->get_path_to(orig);
|
||||
int node_idx = ss->find_node_by_path(np);
|
||||
// print_line("\t valid, nodeidx "+itos(node_idx));
|
||||
if (node_idx>=0) {
|
||||
bool lfound=false;
|
||||
Variant lvar;
|
||||
lvar=ss->get_property_value(node_idx,p_prop,lfound);
|
||||
if (lfound) {
|
||||
found=true;
|
||||
value=lvar;
|
||||
// print_line("\t found value "+String(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node==edited_scene) {
|
||||
//just in case
|
||||
break;
|
||||
}
|
||||
node=node->get_owner();
|
||||
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
bool PropertyEditor::_is_property_different(const Variant& p_current, const Variant& p_orig,int p_usage) {
|
||||
|
||||
if (p_orig.get_type()==Variant::NIL) {
|
||||
//special cases
|
||||
if (p_current.is_zero() && p_usage&PROPERTY_USAGE_STORE_IF_NONZERO)
|
||||
return false;
|
||||
if (p_current.is_one() && p_usage&PROPERTY_USAGE_STORE_IF_NONONE)
|
||||
return false;
|
||||
}
|
||||
|
||||
return bool(Variant::evaluate(Variant::OP_NOT_EQUAL,p_current,p_orig));
|
||||
}
|
||||
|
||||
TreeItem *PropertyEditor::find_item(TreeItem *p_item,const String& p_name) {
|
||||
|
@ -1910,6 +1988,8 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String& p
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PropertyEditor::_notification(int p_what) {
|
||||
|
||||
if (p_what==NOTIFICATION_ENTER_TREE) {
|
||||
|
@ -1950,12 +2030,16 @@ void PropertyEditor::_notification(int p_what) {
|
|||
if (!item)
|
||||
continue;
|
||||
|
||||
if (get_instanced_node()) {
|
||||
if (_might_be_in_instance()) {
|
||||
|
||||
Dictionary d = get_instanced_node()->get_instance_state();
|
||||
if (d.has(*k)) {
|
||||
|
||||
Variant vorig;
|
||||
Dictionary d=item->get_metadata(0);
|
||||
int usage = d.has("usage")?int(int(d["usage"])&(PROPERTY_USAGE_STORE_IF_NONONE|PROPERTY_USAGE_STORE_IF_NONZERO)):0;
|
||||
|
||||
|
||||
if (_get_instanced_node_original_property(*k,vorig) || usage) {
|
||||
Variant v = obj->get(*k);
|
||||
Variant vorig = d[*k];
|
||||
|
||||
int found=-1;
|
||||
for(int i=0;i<item->get_button_count(1);i++) {
|
||||
|
@ -1966,7 +2050,7 @@ void PropertyEditor::_notification(int p_what) {
|
|||
}
|
||||
}
|
||||
|
||||
bool changed = ! (v==vorig);
|
||||
bool changed = _is_property_different(v,vorig,usage);
|
||||
|
||||
if ((found!=-1)!=changed) {
|
||||
|
||||
|
@ -2049,12 +2133,14 @@ void PropertyEditor::_refresh_item(TreeItem *p_item) {
|
|||
|
||||
if (name!=String()) {
|
||||
|
||||
if (get_instanced_node()) {
|
||||
if (_might_be_in_instance()) {
|
||||
|
||||
Dictionary d = get_instanced_node()->get_instance_state();
|
||||
if (d.has(name)) {
|
||||
Variant vorig;
|
||||
Dictionary d=p_item->get_metadata(0);
|
||||
int usage = d.has("usage")?int(int(d["usage"])&(PROPERTY_USAGE_STORE_IF_NONONE|PROPERTY_USAGE_STORE_IF_NONZERO)):0;
|
||||
|
||||
if (_get_instanced_node_original_property(name,vorig) || usage) {
|
||||
Variant v = obj->get(name);
|
||||
Variant vorig = d[name];
|
||||
|
||||
int found=-1;
|
||||
for(int i=0;i<p_item->get_button_count(1);i++) {
|
||||
|
@ -2065,7 +2151,7 @@ void PropertyEditor::_refresh_item(TreeItem *p_item) {
|
|||
}
|
||||
}
|
||||
|
||||
bool changed = ! (v==vorig);
|
||||
bool changed = _is_property_different(v,vorig,usage);
|
||||
|
||||
if ((found!=-1)!=changed) {
|
||||
|
||||
|
@ -2326,7 +2412,8 @@ void PropertyEditor::update_tree() {
|
|||
d["type"]=(int)p.type;
|
||||
d["hint"]=(int)p.hint;
|
||||
d["hint_text"]=p.hint_string;
|
||||
|
||||
d["usage"]=(int)p.usage;
|
||||
|
||||
item->set_metadata( 0, d );
|
||||
item->set_metadata( 1, p.name );
|
||||
|
||||
|
@ -2777,14 +2864,17 @@ void PropertyEditor::update_tree() {
|
|||
}
|
||||
}
|
||||
|
||||
if (get_instanced_node()) {
|
||||
if (_might_be_in_instance()) {
|
||||
|
||||
Dictionary d = get_instanced_node()->get_instance_state();
|
||||
if (d.has(p.name)) {
|
||||
Variant vorig;
|
||||
Dictionary d=item->get_metadata(0);
|
||||
int usage = d.has("usage")?int(int(d["usage"])&(PROPERTY_USAGE_STORE_IF_NONONE|PROPERTY_USAGE_STORE_IF_NONZERO)):0;
|
||||
if (_get_instanced_node_original_property(p.name,vorig) || usage) {
|
||||
Variant v = obj->get(p.name);
|
||||
Variant vorig = d[p.name];
|
||||
if (! (v==vorig)) {
|
||||
|
||||
|
||||
if (_is_property_different(v,vorig,usage)) {
|
||||
//print_line("FOR "+String(p.name)+" RELOAD WITH: "+String(v)+"("+Variant::get_type_name(v.get_type())+")=="+String(vorig)+"("+Variant::get_type_name(vorig.get_type())+")");
|
||||
item->add_button(1,get_icon("Reload","EditorIcons"),3);
|
||||
}
|
||||
}
|
||||
|
@ -3081,17 +3171,18 @@ void PropertyEditor::_edit_button(Object *p_item, int p_column, int p_button) {
|
|||
call_deferred("_set_range_def",ti,prop,ti->get_range(p_column)+1.0);
|
||||
} else if (p_button==3) {
|
||||
|
||||
if (!get_instanced_node())
|
||||
if (!_might_be_in_instance())
|
||||
return;
|
||||
if (!d.has("name"))
|
||||
return;
|
||||
|
||||
String prop=d["name"];
|
||||
|
||||
Dictionary d2 = get_instanced_node()->get_instance_state();
|
||||
if (d2.has(prop)) {
|
||||
Variant vorig;
|
||||
|
||||
_edit_set(prop,d2[prop]);
|
||||
if (_get_instanced_node_original_property(prop,vorig)) {
|
||||
|
||||
_edit_set(prop,vorig);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
|
@ -121,6 +121,7 @@ class CustomPropertyEditor : public Popup {
|
|||
void show_value_editors(int p_amount);
|
||||
void config_value_editors(int p_amount, int p_columns,int p_label_w,const List<String>& p_strings);
|
||||
void config_action_buttons(const List<String>& p_strings);
|
||||
|
||||
protected:
|
||||
|
||||
void _notification(int p_what);
|
||||
|
@ -184,13 +185,17 @@ class PropertyEditor : public Control {
|
|||
virtual void _changed_callback(Object *p_changed,const char * p_what);
|
||||
virtual void _changed_callbacks(Object *p_changed,const String& p_callback);
|
||||
|
||||
|
||||
void _edit_button(Object *p_item, int p_column, int p_button);
|
||||
|
||||
void _node_removed(Node *p_node);
|
||||
void _edit_set(const String& p_name, const Variant& p_value);
|
||||
void _draw_flags(Object *ti,const Rect2& p_rect);
|
||||
|
||||
Node *get_instanced_node();
|
||||
bool _might_be_in_instance();
|
||||
bool _get_instanced_node_original_property(const StringName& p_prop,Variant& value);
|
||||
bool _is_property_different(const Variant& p_current, const Variant& p_orig,int p_usage=0);
|
||||
|
||||
void _refresh_item(TreeItem *p_item);
|
||||
void _set_range_def(Object *p_item, String prop, float p_frame);
|
||||
|
||||
|
|
|
@ -103,6 +103,7 @@ ReparentDialog::ReparentDialog() {
|
|||
add_child(node_only);
|
||||
node_only->hide();
|
||||
|
||||
tree->set_show_enabled_subscene(true);
|
||||
//vbc->add_margin_child("Options:",node_only);;
|
||||
|
||||
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
#include "script_editor_debugger.h"
|
||||
#include "tools/editor/plugins/script_editor_plugin.h"
|
||||
#include "multi_node_edit.h"
|
||||
void SceneTreeDock::_unhandled_key_input(InputEvent p_event) {
|
||||
|
||||
void SceneTreeDock::_unhandled_key_input(InputEvent p_event) {
|
||||
|
||||
uint32_t sc = p_event.key.get_scancode_with_modifiers();
|
||||
if (!p_event.key.pressed || p_event.key.echo)
|
||||
|
@ -71,7 +71,7 @@ Node* SceneTreeDock::instance(const String& p_file) {
|
|||
Node*instanced_scene=NULL;
|
||||
Ref<PackedScene> sdata = ResourceLoader::load(p_file);
|
||||
if (sdata.is_valid())
|
||||
instanced_scene=sdata->instance();
|
||||
instanced_scene=sdata->instance(true);
|
||||
|
||||
|
||||
if (!instanced_scene) {
|
||||
|
@ -96,7 +96,7 @@ Node* SceneTreeDock::instance(const String& p_file) {
|
|||
}
|
||||
}
|
||||
|
||||
instanced_scene->generate_instance_state();
|
||||
//instanced_scene->generate_instance_state();
|
||||
instanced_scene->set_filename( Globals::get_singleton()->localize_path(p_file) );
|
||||
|
||||
editor_data->get_undo_redo().create_action("Instance Scene");
|
||||
|
@ -158,8 +158,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
|||
case TOOL_NEW: {
|
||||
|
||||
|
||||
if (!_validate_no_foreign())
|
||||
break;
|
||||
//if (!_validate_no_foreign())
|
||||
// break;
|
||||
create_dialog->popup_centered_ratio();
|
||||
} break;
|
||||
case TOOL_INSTANCE: {
|
||||
|
@ -176,8 +176,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (!_validate_no_foreign())
|
||||
break;
|
||||
//if (!_validate_no_foreign())
|
||||
// break;
|
||||
|
||||
file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
|
||||
List<String> extensions;
|
||||
|
@ -202,8 +202,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
|||
if (!current)
|
||||
break;
|
||||
|
||||
if (!_validate_no_foreign())
|
||||
break;
|
||||
//if (!_validate_no_foreign())
|
||||
// break;
|
||||
connect_dialog->popup_centered_ratio();
|
||||
connect_dialog->set_node(current);
|
||||
|
||||
|
@ -213,8 +213,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
|||
Node *current = scene_tree->get_selected();
|
||||
if (!current)
|
||||
break;
|
||||
if (!_validate_no_foreign())
|
||||
break;
|
||||
//if (!_validate_no_foreign())
|
||||
// break;
|
||||
groups_editor->set_current(current);
|
||||
groups_editor->popup_centered_ratio();
|
||||
} break;
|
||||
|
@ -224,8 +224,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
|||
if (!selected)
|
||||
break;
|
||||
|
||||
if (!_validate_no_foreign())
|
||||
break;
|
||||
//if (!_validate_no_foreign())
|
||||
// break;
|
||||
|
||||
Ref<Script> existing = selected->get_script();
|
||||
if (existing.is_valid())
|
||||
|
@ -573,9 +573,9 @@ Node *SceneTreeDock::_duplicate(Node *p_node, Map<Node*,Node*> &duplimap) {
|
|||
|
||||
Ref<PackedScene> sd = ResourceLoader::load( p_node->get_filename() );
|
||||
ERR_FAIL_COND_V(!sd.is_valid(),NULL);
|
||||
node = sd->instance();
|
||||
node = sd->instance(true);
|
||||
ERR_FAIL_COND_V(!node,NULL);
|
||||
node->generate_instance_state();
|
||||
//node->generate_instance_state();
|
||||
} else {
|
||||
Object *obj = ObjectTypeDB::instance(p_node->get_type());
|
||||
ERR_FAIL_COND_V(!obj,NULL);
|
||||
|
@ -874,6 +874,16 @@ bool SceneTreeDock::_validate_no_foreign() {
|
|||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (edited_scene->get_scene_instance_state().is_valid() && edited_scene->get_scene_instance_state()->find_node_by_path(edited_scene->get_path_to(E->get()))>=0) {
|
||||
|
||||
accept->get_ok()->set_text("Makes Sense!");
|
||||
accept->set_text("Can't operate on nodes the current scene inherits from!");
|
||||
accept->popup_centered_minsize();
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1078,14 +1088,15 @@ void SceneTreeDock::_delete_confirm() {
|
|||
void SceneTreeDock::_update_tool_buttons() {
|
||||
|
||||
Node *sel = scene_tree->get_selected();
|
||||
bool disable = !sel || (sel!=edited_scene && sel->get_owner()!=edited_scene);
|
||||
bool disable = !sel || (sel!=edited_scene && sel->get_owner()!=edited_scene) || (edited_scene->get_scene_instance_state().is_valid() && edited_scene->get_scene_instance_state()->find_node_by_path(edited_scene->get_path_to(sel))>=0);
|
||||
bool disable_root = disable || sel->get_parent()==scene_root;
|
||||
bool disable_edit = !sel;
|
||||
|
||||
tool_buttons[TOOL_INSTANCE]->set_disabled(disable);
|
||||
tool_buttons[TOOL_INSTANCE]->set_disabled(disable_edit);
|
||||
tool_buttons[TOOL_REPLACE]->set_disabled(disable);
|
||||
tool_buttons[TOOL_CONNECT]->set_disabled(disable);
|
||||
tool_buttons[TOOL_GROUP]->set_disabled(disable);
|
||||
tool_buttons[TOOL_SCRIPT]->set_disabled(disable);
|
||||
tool_buttons[TOOL_CONNECT]->set_disabled(disable_edit);
|
||||
tool_buttons[TOOL_GROUP]->set_disabled(disable_edit);
|
||||
tool_buttons[TOOL_SCRIPT]->set_disabled(disable_edit);
|
||||
tool_buttons[TOOL_MOVE_UP]->set_disabled(disable_root);
|
||||
tool_buttons[TOOL_MOVE_DOWN]->set_disabled(disable_root);
|
||||
tool_buttons[TOOL_DUPLICATE]->set_disabled(disable_root);
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
#include "scene/main/viewport.h"
|
||||
#include "tools/editor/plugins/canvas_item_editor_plugin.h"
|
||||
|
||||
#include "scene/resources/packed_scene.h"
|
||||
|
||||
Node *SceneTreeEditor::get_scene_node() {
|
||||
|
||||
ERR_FAIL_COND_V(!is_inside_tree(),NULL);
|
||||
|
@ -57,22 +59,58 @@ void SceneTreeEditor::_subscene_option(int p_idx) {
|
|||
|
||||
switch(p_idx) {
|
||||
|
||||
case SCENE_MENU_SHOW_CHILDREN: {
|
||||
case SCENE_MENU_EDITABLE_CHILDREN: {
|
||||
|
||||
if (node->has_meta("__editor_show_subtree")) {
|
||||
instance_menu->set_item_checked(0,true);
|
||||
node->set_meta("__editor_show_subtree",Variant());
|
||||
_update_tree();
|
||||
} else {
|
||||
node->set_meta("__editor_show_subtree",true);
|
||||
_update_tree();
|
||||
bool editable = EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(node);
|
||||
editable = !editable;
|
||||
|
||||
//node->set_instance_children_editable(editable);
|
||||
EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(node,editable);
|
||||
instance_menu->set_item_checked(0,editable);
|
||||
if (editable) {
|
||||
node->set_scene_instance_load_placeholder(false);
|
||||
instance_menu->set_item_checked(1,false);
|
||||
}
|
||||
|
||||
_update_tree();
|
||||
|
||||
} break;
|
||||
case SCENE_MENU_USE_PLACEHOLDER: {
|
||||
|
||||
bool placeholder = node->get_scene_instance_load_placeholder();
|
||||
placeholder = !placeholder;
|
||||
|
||||
//node->set_instance_children_editable(editable);
|
||||
if (placeholder) {
|
||||
EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(node,false);
|
||||
}
|
||||
node->set_scene_instance_load_placeholder(placeholder);
|
||||
instance_menu->set_item_checked(0,false);
|
||||
instance_menu->set_item_checked(1,placeholder);
|
||||
|
||||
_update_tree();
|
||||
|
||||
} break;
|
||||
case SCENE_MENU_OPEN: {
|
||||
|
||||
emit_signal("open",node->get_filename());
|
||||
} break;
|
||||
case SCENE_MENU_CLEAR_INHERITANCE: {
|
||||
clear_inherit_confirm->popup_centered_minsize();
|
||||
} break;
|
||||
case SCENE_MENU_OPEN_INHERITED: {
|
||||
if (node && node->get_scene_inherited_state().is_valid()) {
|
||||
emit_signal("open",node->get_scene_inherited_state()->get_path());
|
||||
}
|
||||
} break;
|
||||
case SCENE_MENU_CLEAR_INHERITANCE_CONFIRM: {
|
||||
if (node && node->get_scene_inherited_state().is_valid()) {
|
||||
node->set_scene_inherited_state(Ref<SceneState>());
|
||||
update_tree();
|
||||
EditorNode::get_singleton()->get_property_editor()->update_tree();
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
}
|
||||
|
||||
|
@ -94,15 +132,33 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item,int p_column,int p_id)
|
|||
Rect2 item_rect = tree->get_item_rect(item,0);
|
||||
item_rect.pos.y-=tree->get_scroll().y;
|
||||
item_rect.pos+=tree->get_global_pos();
|
||||
instance_menu->set_pos(item_rect.pos+Vector2(0,item_rect.size.y));
|
||||
instance_menu->set_size(Vector2(item_rect.size.x,0));
|
||||
if (n->has_meta("__editor_show_subtree"))
|
||||
instance_menu->set_item_checked(0,true);
|
||||
else
|
||||
instance_menu->set_item_checked(0,false);
|
||||
|
||||
instance_menu->popup();
|
||||
instance_node=n->get_instance_ID();
|
||||
if (n==get_scene_node()) {
|
||||
inheritance_menu->set_pos(item_rect.pos+Vector2(0,item_rect.size.y));
|
||||
inheritance_menu->set_size(Vector2(item_rect.size.x,0));
|
||||
inheritance_menu->popup();
|
||||
instance_node=n->get_instance_ID();
|
||||
|
||||
} else {
|
||||
instance_menu->set_pos(item_rect.pos+Vector2(0,item_rect.size.y));
|
||||
instance_menu->set_size(Vector2(item_rect.size.x,0));
|
||||
if (EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(n))
|
||||
instance_menu->set_item_checked(0,true);
|
||||
else
|
||||
instance_menu->set_item_checked(0,false);
|
||||
|
||||
if (n->get_owner()==get_scene_node()) {
|
||||
instance_menu->set_item_checked(1,n->get_scene_instance_load_placeholder());
|
||||
instance_menu->set_item_disabled(1,false);
|
||||
} else {
|
||||
|
||||
instance_menu->set_item_checked(1,false);
|
||||
instance_menu->set_item_disabled(1,true);
|
||||
}
|
||||
|
||||
instance_menu->popup();
|
||||
instance_node=n->get_instance_ID();
|
||||
}
|
||||
//emit_signal("open",n->get_filename());
|
||||
} else if (p_id==BUTTON_SCRIPT) {
|
||||
RefPtr script=n->get_script();
|
||||
|
@ -168,15 +224,17 @@ void SceneTreeEditor::_add_nodes(Node *p_node,TreeItem *p_parent) {
|
|||
|
||||
bool part_of_subscene=false;
|
||||
|
||||
if (!display_foreign && p_node->get_owner()!=get_scene_node() && p_node!=get_scene_node()) {
|
||||
if (!display_foreign && p_node->get_owner()!=get_scene_node() && p_node!=get_scene_node()) {
|
||||
|
||||
if ((show_enabled_subscene || can_open_instance) && p_node->get_owner() && p_node->get_owner()->get_owner()==get_scene_node() && p_node->get_owner()->has_meta("__editor_show_subtree")) {
|
||||
if ((show_enabled_subscene || can_open_instance) && p_node->get_owner() && (get_scene_node()->is_editable_instance(p_node->get_owner()))) {
|
||||
|
||||
part_of_subscene=true;
|
||||
//allow
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
part_of_subscene = get_scene_node()->get_scene_inherited_state().is_valid() && get_scene_node()->get_scene_inherited_state()->find_node_by_path(get_scene_node()->get_path_to(p_node))>=0;
|
||||
}
|
||||
|
||||
TreeItem *item = tree->create_item(p_parent);
|
||||
|
@ -199,6 +257,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node,TreeItem *p_parent) {
|
|||
icon=get_icon( (has_icon(p_node->get_type(),"EditorIcons")?p_node->get_type():String("Object")),"EditorIcons");
|
||||
item->set_icon(0, icon );
|
||||
item->set_metadata( 0,p_node->get_path() );
|
||||
|
||||
if (part_of_subscene) {
|
||||
|
||||
//item->set_selectable(0,marked_selectable);
|
||||
|
@ -221,7 +280,10 @@ void SceneTreeEditor::_add_nodes(Node *p_node,TreeItem *p_parent) {
|
|||
}
|
||||
}
|
||||
|
||||
if (p_node!=get_scene_node() && p_node->get_filename()!="" && can_open_instance) {
|
||||
if (p_node==get_scene_node() && p_node->get_scene_inherited_state().is_valid()) {
|
||||
item->add_button(0,get_icon("InstanceOptions","EditorIcons"),BUTTON_SUBSCENE);
|
||||
item->set_tooltip(0,"Inherits: "+p_node->get_scene_inherited_state()->get_path()+"\nType: "+p_node->get_type());
|
||||
} else if (p_node!=get_scene_node() && p_node->get_filename()!="" && can_open_instance) {
|
||||
|
||||
item->add_button(0,get_icon("InstanceOptions","EditorIcons"),BUTTON_SUBSCENE);
|
||||
item->set_tooltip(0,"Instance: "+p_node->get_filename()+"\nType: "+p_node->get_type());
|
||||
|
@ -487,8 +549,11 @@ void SceneTreeEditor::_notification(int p_what) {
|
|||
|
||||
get_tree()->connect("tree_changed",this,"_tree_changed");
|
||||
get_tree()->connect("node_removed",this,"_node_removed");
|
||||
instance_menu->set_item_icon(2,get_icon("Load","EditorIcons"));
|
||||
instance_menu->set_item_icon(3,get_icon("Load","EditorIcons"));
|
||||
tree->connect("item_collapsed",this,"_cell_collapsed");
|
||||
inheritance_menu->set_item_icon(2,get_icon("Load","EditorIcons"));
|
||||
clear_inherit_confirm->connect("confirmed",this,"_subscene_option",varray(SCENE_MENU_CLEAR_INHERITANCE_CONFIRM));
|
||||
|
||||
|
||||
// get_scene()->connect("tree_changed",this,"_tree_changed",Vector<Variant>(),CONNECT_DEFERRED);
|
||||
// get_scene()->connect("node_removed",this,"_node_removed",Vector<Variant>(),CONNECT_DEFERRED);
|
||||
|
@ -499,6 +564,7 @@ void SceneTreeEditor::_notification(int p_what) {
|
|||
get_tree()->disconnect("tree_changed",this,"_tree_changed");
|
||||
get_tree()->disconnect("node_removed",this,"_node_removed");
|
||||
tree->disconnect("item_collapsed",this,"_cell_collapsed");
|
||||
clear_inherit_confirm->disconnect("confirmed",this,"_subscene_option");
|
||||
_update_tree();
|
||||
}
|
||||
|
||||
|
@ -788,12 +854,27 @@ SceneTreeEditor::SceneTreeEditor(bool p_label,bool p_can_rename, bool p_can_open
|
|||
blocked=0;
|
||||
|
||||
instance_menu = memnew( PopupMenu );
|
||||
instance_menu->add_check_item("Show Children",SCENE_MENU_SHOW_CHILDREN);
|
||||
instance_menu->add_check_item("Editable Children",SCENE_MENU_EDITABLE_CHILDREN);
|
||||
instance_menu->add_check_item("Load As Placeholder",SCENE_MENU_USE_PLACEHOLDER);
|
||||
instance_menu->add_separator();
|
||||
instance_menu->add_item("Open in Editor",SCENE_MENU_OPEN);
|
||||
instance_menu->connect("item_pressed",this,"_subscene_option");
|
||||
add_child(instance_menu);
|
||||
|
||||
inheritance_menu = memnew( PopupMenu );
|
||||
inheritance_menu->add_item("Clear Inheritance",SCENE_MENU_CLEAR_INHERITANCE);
|
||||
inheritance_menu->add_separator();
|
||||
inheritance_menu->add_item("Open in Editor",SCENE_MENU_OPEN_INHERITED);
|
||||
inheritance_menu->connect("item_pressed",this,"_subscene_option");
|
||||
|
||||
add_child(inheritance_menu);
|
||||
|
||||
clear_inherit_confirm = memnew( ConfirmationDialog );
|
||||
clear_inherit_confirm->set_text("Clear Inheritance? (No Undo!)");
|
||||
clear_inherit_confirm->get_ok()->set_text("Clear!");
|
||||
add_child(clear_inherit_confirm);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -52,16 +52,22 @@ class SceneTreeEditor : public Control {
|
|||
};
|
||||
|
||||
enum {
|
||||
SCENE_MENU_SHOW_CHILDREN,
|
||||
SCENE_MENU_EDITABLE_CHILDREN,
|
||||
SCENE_MENU_USE_PLACEHOLDER,
|
||||
SCENE_MENU_OPEN,
|
||||
SCENE_MENU_CLEAR_INHERITANCE,
|
||||
SCENE_MENU_OPEN_INHERITED,
|
||||
SCENE_MENU_CLEAR_INHERITANCE_CONFIRM,
|
||||
};
|
||||
|
||||
Tree *tree;
|
||||
Node *selected;
|
||||
PopupMenu *instance_menu;
|
||||
PopupMenu *inheritance_menu;
|
||||
ObjectID instance_node;
|
||||
|
||||
AcceptDialog *error;
|
||||
ConfirmationDialog *clear_inherit_confirm;
|
||||
|
||||
int blocked;
|
||||
|
||||
|
|
|
@ -104,11 +104,6 @@ class ExportDAE(bpy.types.Operator, ExportHelper):
|
|||
description="Export only objects on the active layers.",
|
||||
default=True,
|
||||
)
|
||||
use_exclude_ctrl_bones = BoolProperty(
|
||||
name="Exclude Control Bones",
|
||||
description="Exclude skeleton bones with names that begin with 'ctrl'.",
|
||||
default=True,
|
||||
)
|
||||
use_anim = BoolProperty(
|
||||
name="Export Animation",
|
||||
description="Export keyframe animation",
|
||||
|
|
Loading…
Reference in a new issue