فهرست منبع

Merge pull request #1495 from Jason0214/TSCN_format

Add some tscn nodes and resources documents
Max Hilbrunner 7 سال پیش
والد
کامیت
590f90dd16
1فایلهای تغییر یافته به همراه297 افزوده شده و 57 حذف شده
  1. 297 57
      development/file_formats/tscn.rst

+ 297 - 57
development/file_formats/tscn.rst

@@ -60,6 +60,190 @@ so on. For example, a spatial node looks like:
     [node name="Cube" type="Spatial" parent="."]
     transform=Transform( 1.0, 0.0, 0.0 ,0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0 )
 
+The Scene Tree
+--------------
+
+The scene tree is made up of ... nodes! The heading of each node consists of
+it's name, parent and (most of the time) a type. For example
+:code:`[node type="Camera" name="PlayerCamera" parent="Player/Head"]`
+
+Other valid keywords include:
+
+ - instance
+ - instance_placeholder
+ - owner
+ - index (if two nodes have the same name)
+ - groups
+
+The first node in the file should not have the :code:`parent=Path/To/Node` 
+entry in it's heading, and it is the scene root. All scene files should have 
+exactly one scene root. It it does not, Godot will fail to import the file. 
+The parent path of other nodes should be absolute, but without the scene 
+root's name. If it is a direct child of the scene root, it should be 
+:code:`"."`. Here is an example scene tree (but without any node content).
+::
+
+    [node name="Player" type="Spatial"]             ; The scene root
+    [node name="Arm" parent="." type="Spatial"]     ; Parented to the scene root
+    [node name="Hand" parent="Arm" type="Spatial"]
+    [node name="Finger" parent="Arm/Hand" type="Spatial"]
+    
+Similar to the internal resource, the document for each node is currently 
+incomplete. Fortunately it is easy to find out because you can simply 
+save a file with that node in it. Some example nodes are:
+
+::
+
+    [node  type="CollisionShape" name="SphereCollision" parent="SpherePhysics"]
+
+    shape = SubResource(8)
+    transform = Transform( 1.0 , 0.0 , -0.0 , 0.0 , -4.371138828673793e-08 , 1.0 , -0.0 , -1.0 , -4.371138828673793e-08 ,0.0 ,0.0 ,-0.0  )
+
+
+    [node  type="MeshInstance" name="Sphere" parent="SpherePhysics"]
+
+    mesh = SubResource(9)
+    transform = Transform( 1.0 , 0.0 , -0.0 , 0.0 , 1.0 , -0.0 , -0.0 , -0.0 , 1.0 ,0.0 ,0.0 ,-0.0  )
+
+
+    [node  type="OmniLight" name="Lamp" parent="."]
+
+    light_energy = 1.0
+    light_specular = 1.0
+    transform = Transform( -0.29086464643478394 , -0.7711008191108704 , 0.5663931369781494 , -0.05518905818462372 , 0.6045246720314026 , 0.7946722507476807 , -0.9551711678504944 , 0.199883371591568 , -0.21839118003845215 ,4.076245307922363 ,7.3235554695129395 ,-1.0054539442062378  )
+    omni_range = 30
+    shadow_enabled = true
+    light_negative = false
+    light_color = Color( 1.0, 1.0, 1.0, 1.0 )
+
+
+    [node  type="Camera" name="Camera" parent="."]
+
+    projection = 0
+    near = 0.10000000149011612
+    fov = 50
+    transform = Transform( 0.6859206557273865 , -0.32401350140571594 , 0.6515582203865051 , 0.0 , 0.8953956365585327 , 0.44527143239974976 , -0.7276763319969177 , -0.3054208755493164 , 0.6141703724861145 ,14.430776596069336 ,10.093015670776367 ,13.058500289916992  )
+    far = 100.0
+
+Node Path
+~~~~~~~~~
+
+A tree structure is not enough to represent the whole scene, Godot use
+a :code:`NodePath(Path/To/Node)` structure to refer to another node or
+attribute of the node anywhere in the scene tree. Some typical usages of
+NodePath like mesh node use :code:`NodePath()` to point to its skeleton,
+animation track use :code:`NodePath()` points to animated attribute in node.
+
+::
+
+    [node name="mesh" type="MeshInstance" parent="Armature001"]
+
+    mesh = SubResource(1)
+    skeleton = NodePath("..:")
+
+::
+
+    [sub_resource id=3 type="Animation"]
+
+    ...
+    tracks/0/type = "transform
+    tracks/0/path = NodePath("Cube:")
+    ...
+
+Skeleton
+~~~~~~~~~
+Skeleton node inherits Spatial node, besides that it may have a list
+of bones described in key, value pair in the format :code:`bones/Id/Attribute=Value`,
+attributes of bone consisits of 
+
+- name
+- parent
+- rest
+- pose
+- enabled
+- bound_children
+
+1) :code:`name` must put as the first attribute of each bone
+
+2) :code:`parent` is the index of parent bone in the bone list, with parent index,
+   the bone list is built to a bone tree
+
+3) :code:`rest` is the transform matrix of bone in rest position
+
+4) :code:`pose` is the pose matrix use :code:`rest` as basis
+
+5) :code:`bound_children` is a list of NodePath() points to 
+   BoneAttachments belong to this bone
+
+An example of a skeleton node with two bones:
+
+::
+
+    [node name="Skeleton" type="Skeleton" parent="Armature001" index="0"]
+
+    bones/0/name = "Bone.001"
+    bones/0/parent = -1
+    bones/0/rest = Transform( 1, 0, 0, 0, 0, -1, 0, 1, 0, 0.038694, 0.252999, 0.0877164 )
+    bones/0/pose = Transform( 1.0, 0.0, -0.0, 0.0, 1.0, -0.0, -0.0, -0.0, 1.0, 0.0, 0.0, -0.0 )
+    bones/0/enabled = true
+    bones/0/bound_children = [  ]
+    bones/1/name = "Bone.002"
+    bones/1/parent = 0
+    bones/1/rest = Transform( 0.0349042, 0.99939, 0.000512929, -0.721447, 0.0248417, 0.692024, 0.691589, -0.0245245, 0.721874, 0, 5.96046e-08, -1.22688 )
+    bones/1/pose = Transform( 1.0, 0.0, -0.0, 0.0, 1.0, -0.0, -0.0, -0.0, 1.0, 0.0, 0.0, -0.0 )
+    bones/1/enabled = true
+    bones/1/bound_children = [  ]
+
+BoneAttachment
+~~~~~~~~~~~~~~
+BoneAttachment node is an intermediate node to describe some node being parented
+to a single bone in Skeleton node. The BoneAttachment has a :code:`bone_name=NameOfBone`,
+and the corresponding bone being the parent has the BoneAttachment node 
+in its :code:`bound_children` list.
+
+An example of one MeshInstance parented to a bone in Skeleton:
+
+::
+
+    [node name="Armature" type="Skeleton" parent="."]
+
+    transform = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -0.0219986, 0.0125825, 0.0343127)
+    bones/0/name = "Bone"
+    bones/0/parent = -1
+    bones/0/rest = Transform(1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0)
+    bones/0/pose = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0)
+    bones/0/enabled = true
+    bones/0/bound_children = [NodePath("BoneAttachment:")]
+
+    [node name="BoneAttachment" type="BoneAttachment" parent="Armature"]
+
+    bone_name = "Bone"
+
+    [node name="Cylinder" type="MeshInstance" parent="Armature/BoneAttachment"]
+
+    mesh = SubResource(1)
+    transform = Transform(1.0, 0.0, 0.0, 0.0, 1.86265e-09, 1.0, 0.0, -1.0, 0.0, 0.0219986, -0.0343127, 2.25595)
+
+AnimationPlayer
+~~~~~~~~~~~~~~~~
+AnimationPlayer works as an animation lib. it has animations listed in the format
+:code:`anim/Name=SubResource(ResourceId)`, each refers to a Animation
+internal resource. All the animation resources use the root node of AnimationPlayer.
+The root node is stored as :code:`root_node=NodePath(Path/To/Node)`.
+
+::
+
+    [node name="AnimationPlayer" type="AnimationPlayer" parent="." index="1"]
+
+    root_node = NodePath("..")
+    autoplay = ""
+    playback_process_mode = 1
+    playback_default_blend_time = 0.0
+    playback_speed = 1.0
+    anims/default = SubResource( 2 )
+    blend_times = [  ]
+
+
 
 Resources
 ---------
@@ -121,73 +305,129 @@ mesh having a material). In this case, the referring resource must appear
 before the reference to it. Thus, in the internal resources section of the 
 file, order does matter.
 
-Unfortunately, documentation on the formats for these subresources is
-completely absent, and while some can be found through inspecting resources of
-saved files, but others can only be found by looking through Godot's source.
-
-
-The Scene Tree
---------------
-
-The scene tree is made up of ... nodes! The heading of each node consists of
-it's name, parent and (most of the time) a type. For example
-:code:`[node type="Camera" name="PlayerCamera" parent="Player/Head"]`
-
-Other valid keywords include:
-
- - instance
- - instance_placeholder
- - owner
- - index (if two nodes have the same name)
- - groups
-
-The first node in the file should not have the :code:`parent=Path/To/Node` 
-entry in it's heading, and it is the scene root. All scene files should have 
-exactly one scene root. It it does not, Godot will fail to import the file. 
-The parent path of other nodes should be absolute, but without the scene 
-root's name. If it is a direct child of the scene root, it should be 
-:code:`"."`. Here is an example scene tree (but without any node content).
-::
+Unfortunately, documentation on the formats for these subresources is not
+complete, and while some can be found through inspecting resources of
+saved files, others can only be found by looking through Godot's source.
 
-    [node name="Player" type="Spatial"]             ; The scene root
-    [node name="Arm" parent="." type="Spatial"]     ; Parented to the scene root
-    [node name="Hand" parent="Arm" type="Spatial"]
-    [node name="Finger" parent="Arm/Hand" type="Spatial"]
-    
-Similar to the internal resource, the content for each node is currently 
-undocumented. Fortunately it is easy to find out because you can simply 
-save a file with that node in it. Some example nodes are:
+ArrayMesh
+~~~~~~~~~
+ArrayMesh consists of several surfaces, each in the format :code:`surface\Index={}`,
+each surface is a set of vertex and a material.
 
-::
+TSCN support two format of surface,
 
-    [node  type="CollisionShape" name="SphereCollision" parent="SpherePhysics"]
-
-    shape = SubResource(8)
-    transform = Transform( 1.0 , 0.0 , -0.0 , 0.0 , -4.371138828673793e-08 , 1.0 , -0.0 , -1.0 , -4.371138828673793e-08 ,0.0 ,0.0 ,-0.0  )
+1) for the old format, each surface has three essential keys:
 
+- primitive
+- arrays
+- morph_arrays
 
-    [node  type="MeshInstance" name="Sphere" parent="SpherePhysics"]
+    i) :code:`primitive` is an enumerate variable, :code:`primitive=4` which is 
+       PRIMITIVE_TRIANGLES is frequently used.
 
-    mesh = SubResource(9)
-    transform = Transform( 1.0 , 0.0 , -0.0 , 0.0 , 1.0 , -0.0 , -0.0 , -0.0 , 1.0 ,0.0 ,0.0 ,-0.0  )
+    ii) :code:`arrays` as name suggestes is an array of array, it contains:
 
+        1) a array of vertex position
+        2) tagents array
+        3) vertex color array
+        4) UV array 1
+        5) UV array 2
+        6) bone index array
+        7) bone weight array
+        8) vertex index array
 
-    [node  type="OmniLight" name="Lamp" parent="."]
+    iii) :code:`morph_arrays` is an array of morph, each morph is exactly an 
+         :code:`arrays` without vertex index array.
 
-    light_energy = 1.0
-    light_specular = 1.0
-    transform = Transform( -0.29086464643478394 , -0.7711008191108704 , 0.5663931369781494 , -0.05518905818462372 , 0.6045246720314026 , 0.7946722507476807 , -0.9551711678504944 , 0.199883371591568 , -0.21839118003845215 ,4.076245307922363 ,7.3235554695129395 ,-1.0054539442062378  )
-    omni_range = 30
-    shadow_enabled = true
-    light_negative = false
-    light_color = Color( 1.0, 1.0, 1.0, 1.0 )
+An example of ArrayMesh:
 
+::
 
-    [node  type="Camera" name="Camera" parent="."]
+    [sub_resource id=1 type="ArrayMesh"]
+
+    surfaces/0 = {
+        "primitive":4,
+        "arrays":[
+            Vector3Array(0.0, 1.0, -1.0, 0.866025, -1.0, -0.5, 0.0, -1.0, -1.0, 0.866025, 1.0, -0.5, 0.866025, -1.0, 0.5, 0.866025, 1.0, 0.5, -8.74228e-08, -1.0, 1.0, -8.74228e-08, 1.0, 1.0, -0.866025, -1.0, 0.5, -0.866025, 1.0, 0.5, -0.866025, -1.0, -0.5, -0.866025, 1.0, -0.5),
+            Vector3Array(0.0, 0.609973, -0.792383, 0.686239, -0.609973, -0.396191, 0.0, -0.609973, -0.792383, 0.686239, 0.609973, -0.396191, 0.686239, -0.609973, 0.396191, 0.686239, 0.609973, 0.396191, 0.0, -0.609973, 0.792383, 0.0, 0.609973, 0.792383, -0.686239, -0.609973, 0.396191, -0.686239, 0.609973, 0.396191, -0.686239, -0.609973, -0.396191, -0.686239, 0.609973, -0.396191),
+            null, ; No Tangents,
+            null, ; no Vertex Colors,
+            null, ; No UV1,
+            null, ; No UV2,
+            null, ; No Bones,
+            null, ; No Weights,
+            IntArray(0, 2, 1, 3, 1, 4, 5, 4, 6, 7, 6, 8, 0, 5, 9, 9, 8, 10, 11, 10, 2, 1, 10, 8, 0, 1, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 5, 0, 3, 0, 9, 11, 9, 5, 7, 9, 10, 11, 11, 2, 0, 10, 1, 2, 1, 6, 4, 6, 1, 8)
+        ],
+        "morph_arrays":[]
+    }
+
+Animation
+~~~~~~~~~~
+An animation resource consists of tracks. Besides, it has 'length', 'loop' and
+'step' applied to all the tracks.
+
+- length
+- loop
+- step
+
+1) :code:`length` and :code:`step` are both time in seconds
+
+Each track is described by a list of key, value pairt in the format :code:`tracks/Id/Attribute`,
+it includs:
+
+- type
+- path
+- interp
+- keys
+- loop_wrap
+- imported
+- enabled
+
+
+1) The :code:`type` must be put as the first attribute of each track. 
+   The value of :code:`type` can be:
+
+    - 'transform'
+    - 'value'
+    - 'method'
+
+2) The :code:`path` has the format :code:`NodePath(Path/To/Node:Attribute)`. 
+   It is the path from animation root node (property of AnimationPlayer) to the 
+   animated node or attrbute.
+
+3) The :code:`interp` is the method to interpolate frames from the keyframes.
+   it is a enum variable and can has value:
+
+    - 0 (constant)
+    - 1 (linear)
+    - 2 (cubic)
+
+4) The :code:`keys` is the keyframes, it appears as a PoolRealArray() 
+   but have different structure for track with different type
+
+    - A transform track use every 12 real number in the :code:`keys` to describte a keyframe. 
+      The first number is the timestamp, the second number is the transision (default 1.0
+      in transform track), followed by a three number translation vector, followed by 
+      four number rotation quaternion (x,y,z,w) and finally a three number scale vector.
 
-    projection = 0
-    near = 0.10000000149011612
-    fov = 50
-    transform = Transform( 0.6859206557273865 , -0.32401350140571594 , 0.6515582203865051 , 0.0 , 0.8953956365585327 , 0.44527143239974976 , -0.7276763319969177 , -0.3054208755493164 , 0.6141703724861145 ,14.430776596069336 ,10.093015670776367 ,13.058500289916992  )
-    far = 100.0
+::
 
+    [sub_resource type="Animation" id=2]
+
+    length = 4.95833
+    loop = false
+    step = 0.1
+    tracks/0/type = "transform"
+    tracks/0/path = NodePath("Armature001")
+    tracks/0/interp = 1
+    tracks/0/loop_wrap = true
+    tracks/0/imported = true
+    tracks/0/enabled = true
+    tracks/0/keys = PoolRealArray( 0, 1, -0.0358698, -0.829927, 0.444204, 0, 0, 0, 1, 0.815074, 0.815074, 0.815074, 4.95833, 1, -0.0358698, -0.829927, 0.444204, 0, 0, 0, 1, 0.815074, 0.815074, 0.815074 )
+    tracks/1/type = "transform"
+    tracks/1/path = NodePath("Armature001/Skeleton:Bone.001")
+    tracks/1/interp = 1
+    tracks/1/loop_wrap = true
+    tracks/1/imported = true
+    tracks/1/enabled = false
+    tracks/1/keys = PoolRealArray( 0, 1, 0, 5.96046e-08, 0, 0, 0, 0, 1, 1, 1, 1, 4.95833, 1, 0, 5.96046e-08, 0, 0, 0, 0, 1, 1, 1, 1 )