/// <summary> /// Exports the given model to the given data stream. Uses the RSM /// Compressed model format. /// </summary> public static void exportModel(Stream stream, RSModel model) { try { ModelData data = model.data; bool collision = false; bool drawn = false; bool uvs = false; BinaryWriter writer = new BinaryWriter(stream); // No data to write, abort. if (!data.drawn && !data.collision) return; // :::: Magic Number byte[] magic_number = Encoding.ASCII.GetBytes("RSMc_005"); writer.Write(magic_number, 0, 8); // :::: Header info byte flag = 0; // Calculate the export settings (suggested by the model options) if (data.has_uvs) { uvs = true; flag += 1; } if (model.drawn && data.drawn) { drawn = true; flag += 2; } if (model.collision && data.collision) { collision = true; flag += 4; } writer.Write(flag); writer.Write(data.num_lvertices); if (drawn) { writer.Write(data.num_dvertices); writer.Write(data.num_bones); writer.Write(data.num_animations); } // :::: Bone Structure if (drawn) { for (int i = 0; i < data.num_bones; ++i) writer.Write(data.bone_parents[i]); for (int i = 0; i < data.num_bones; ++i) { for (int col = 0; col < 4; ++col) for (int row = 0; row < 4; ++row) writer.Write(data.inv_bone_matrices[i].a[row, col]); } } // :::: Logical Vertex Data if (collision) { for (int i = 0; i < data.num_lvertices; ++i) { writer.Write(data.position[i].x); writer.Write(data.position[i].y); writer.Write(data.position[i].z); writer.Write(data.collision_normal[i].x); writer.Write(data.collision_normal[i].y); writer.Write(data.collision_normal[i].z); } } // :::: Drawn Vertex Data if (drawn) { for (int i = 0; i < data.num_dvertices; ++i) { if (!collision) { int id = data.drawn_index[i]; writer.Write(data.position[id].x); writer.Write(data.position[id].y); writer.Write(data.position[id].z); } else writer.Write(data.drawn_index[i]); writer.Write(data.lighting_normal[i].x); writer.Write(data.lighting_normal[i].y); writer.Write(data.lighting_normal[i].z); if (uvs) { writer.Write(data.texture_uvs[i].u); writer.Write(data.texture_uvs[i].v); } if (data.num_bones > 0) { int id = data.drawn_index[i]; writer.Write(data.bone_weights[id].boneid_1); writer.Write(data.bone_weights[id].boneid_2); writer.Write(data.bone_weights[id].boneid_3); writer.Write(data.bone_weights[id].boneid_4); writer.Write(data.bone_weights[id].boneweight_1); writer.Write(data.bone_weights[id].boneweight_2); writer.Write(data.bone_weights[id].boneweight_3); writer.Write(data.bone_weights[id].boneweight_4); } } } // :::: Triangle Data writer.Write(data.num_triangles); for (int i = 0; i < data.num_triangles; ++i) { if (collision) { writer.Write(data.collision_triangles[i].id_1); writer.Write(data.collision_triangles[i].id_2); writer.Write(data.collision_triangles[i].id_3); writer.Write(data.ctriangle_normals[i].x); writer.Write(data.ctriangle_normals[i].y); writer.Write(data.ctriangle_normals[i].z); } if (drawn) { writer.Write(data.drawn_triangles[i].id_1); writer.Write(data.drawn_triangles[i].id_2); writer.Write(data.drawn_triangles[i].id_3); } } // :::: Animation Blocks if (drawn) { foreach( ModelData.Animation animation in data.animations) { writer.Write(animation.num_keys); foreach (float keyframe in animation.keyframes) writer.Write(keyframe); foreach (ModelData.BoneAnimation bone in animation.bone_animations) { foreach (ModelData.AnimationKey key in bone.key_states) { foreach (ModelData.BezierHandle handle in key.handles) { writer.Write(handle.center); writer.Write(handle.left); writer.Write(handle.right); } } } } } } catch (Exception ex) { MessageBox.Show(ex.Message); } }
/// <summary> /// Adds a new [empty] content for the given content type. /// </summary> /// <returns>The newly created resource.</returns> public RSContentContainer addNewContent( ContentType type, string id) { // Verify that the id does not conflict, modifying it if it does id = getNonconflictingId(type, id, null); // Automatically sets the selected node to the new node RSContentContainer new_content = null; if (type == ContentType.Model) new_content = new RSModel(); else if (type == ContentType.Texture) new_content = new RSTexture(); new_content.context = this; new_content.id = id; // Determine Default Icon TreeNode new_node; if( type == ContentType.Model) new_node = new TreeNode(id, 2, 2); else new_node = new TreeNode(id, 1, 1); new_content.assosciated_node = new_node; new_node.Name = file_identifier[(int)type]; new_node.Tag = new_content; insertNodeIntoContentTree(type, new_node); contentTree.SelectedNode = new_node; context.file_changed = true; return new_content; }