public static source makePositionsSource(ref Model3D mdl) { source src = new source(); src.id = "positions_source"; float_array fa = new float_array(); fa.id = "positions"; List <double> values = new List <double>(); for (int id_num = 0; id_num < mdl.meshes.Count; id_num++) { int len = mdl.meshes[id_num].vertices.Length; for (int i = 0; i < len; i++) { values.Add(mdl.meshes[id_num].vertices[i].X * _scale); values.Add(mdl.meshes[id_num].vertices[i].Y * _scale); values.Add(mdl.meshes[id_num].vertices[i].Z * _scale); } } fa.Values = values.ToArray(); fa.count = (ulong)fa.Values.LongLength; src.technique_common = new sourceTechnique_common(); src.technique_common.accessor = MakePosAccessor(fa.count / 3, fa.id); src.Item = fa; return(src); }
private static source GenerateSource <T>(string id, string[] paramnames, List <T> list, Func <T, double[]> converter) { float_array verts = new float_array(); source source = new source { id = id, name = id, Item = verts }; List <double> values = new List <double>(); int length = -1; foreach (T item in list) { double[] vals = converter(item); if (length == -1) { length = vals.Length; } else if (vals.Length != length) { throw new Exception("Incompatable lengths!"); } values.AddRange(vals); } verts.Values = values.ToArray(); verts.count = (ulong)verts.Values.LongLength; verts.id = id + "-data"; verts.name = verts.id; param[] indexes = new param[paramnames.Length]; for (int i = 0; i < paramnames.Length; i++) { indexes[i] = new param { name = paramnames[i], type = "float" }; } source.technique_common = new sourceTechnique_common { accessor = new accessor { source = "#" + verts.id, count = (ulong)list.Count, stride = (ulong)length, param = indexes } }; return(source); }
public static source MakeFloatSource(string parentName, string name, string[] components, float[] values, int stride = 1, string type = "float") { var posName = parentName + "-" + name + "-array"; // Create a shortened source name if the length exceeds 64 bytes if (posName.Length > 64) { var hash = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(parentName)); parentName = string.Join("", hash.Select(c => ((int)c).ToString("X2"))); } var positions = new float_array(); positions.id = parentName + "-" + name + "-array"; var source = new source(); source.id = parentName + "-" + name; source.name = name; positions.count = (ulong)values.Length; positions.Values = values.Select(x => (double)x).ToArray(); var technique = MakeAccessor(type, components, stride, values.Length / components.Length, positions.id); source.technique_common = technique; source.Item = positions; return(source); }
internal List <float> GetTimesForBone(string bone, library_visual_scenes lvs) { List <float> ret = new List <float>(); foreach (channel chan in mChannels) { //extract the node name and address int sidx = chan.target.IndexOf('/'); string sid = chan.target.Substring(0, sidx); //ok this is tricky, the spec says that the <source> //referenced by the input with the JOINT semantic //should contain a <Name_array> that contains sids //to identify the joint nodes. sids are used instead //of IDREFs to allow a skin controller to be instantiated //multiple times, where each instance can be animated //independently. // //So max's default collada exporter doesn't even give the //bones sids at all, and the other one whose name escapes //me gives the bones sids, but then the address element //says Name (note the case), so I guess you need to try //to match via sid first and if that fails, use name? node n = AnimForm.LookUpNode(lvs, sid); if (n == null) { continue; } if (bone != n.name) { continue; } //grab sampler key string sampKey = chan.source; //strip # sampKey = sampKey.Substring(1); sampler samp = mSamplers[sampKey]; string srcInp = GetSourceForSemantic(samp, "INPUT"); float_array srcTimes = mSources[srcInp].Item as float_array; foreach (float time in srcTimes.Values) { float t = time; if (ret.Contains(t)) { continue; } ret.Add(t); } } return(ret); }
private void LoadGeometryFromCollada(CollisionGroupNode parent, geometry geo) { mesh m = geo.Item as mesh; // For safety, read the model's definition of where the position data is // and grab it from there. We could just do a search for "position" in the // source list names, but this makes sure there are no errors. InputLocal pos_input = Array.Find(m.vertices.input, x => x.semantic == "POSITION"); source pos_src = Array.Find(m.source, x => x.id == pos_input.source.Trim('#')); float_array pos_arr = pos_src.Item as float_array; // For some reason Maya puts a leading space in the face index data, // so we need to trim that out before trying to parse the index string. triangles tris = m.Items[0] as triangles; string[] indices = tris.p.Trim(' ').Split(' '); int stride = tris.input.Length; // Make sure this tool can support meshes with multiple vertex attributes. for (int i = 0; i < indices.Length; i += stride * 3) { int vec1_index = Convert.ToInt32(indices[i]); int vec2_index = Convert.ToInt32(indices[i + stride]); int vec3_index = Convert.ToInt32(indices[i + (stride * 2)]); Vector3 vec1 = new Vector3((float)pos_arr.Values[vec1_index * 3], (float)pos_arr.Values[(vec1_index * 3) + 1], (float)pos_arr.Values[(vec1_index * 3) + 2]); Vector3 vec2 = new Vector3((float)pos_arr.Values[vec2_index * 3], (float)pos_arr.Values[(vec2_index * 3) + 1], (float)pos_arr.Values[(vec2_index * 3) + 2]); Vector3 vec3 = new Vector3((float)pos_arr.Values[vec3_index * 3], (float)pos_arr.Values[(vec3_index * 3) + 1], (float)pos_arr.Values[(vec3_index * 3) + 2]); // The benefit of using this library is that we easily got the up-axis // info from the file. If the up-axis was defined as Z-up, we need to // swap the Y and Z components of our vectors so the mesh isn't sideways. // (The Wind Waker is Y-up.) if (m_UpAxis == UpAxisType.Z_UP) { vec1 = SwapYZ(vec1); vec2 = SwapYZ(vec2); vec3 = SwapYZ(vec3); } CollisionTriangle new_tri = new CollisionTriangle(vec1, vec2, vec3, parent); parent.Triangles.Add(new_tri); Triangles.Add(new_tri); } }
List <float> LerpValue(float time, float_array chanTimes, float_array chanValues, int stride) { List <float> ret = new List <float>(); //calc totaltime float totalTime = chanTimes.Values[chanTimes.Values.Length - 1] - chanTimes.Values[0]; //make sure the time is in range float animTime = time; if (time > chanTimes.Values[chanTimes.Values.Length - 1]) { animTime = chanTimes.Values[chanTimes.Values.Length - 1]; } //locate the key index to start with int startIndex; for (startIndex = 0; startIndex < chanTimes.Values.Length; startIndex++) { if (animTime <= chanTimes.Values[startIndex]) { //back up one startIndex = Math.Max(startIndex - 1, 0); break; //found } } //figure out the percentage between pos1 and pos2 //get the deltatime float percentage = chanTimes.Values[startIndex + 1] - chanTimes.Values[startIndex]; //convert to percentage percentage = 1.0f / percentage; //multiply by amount beyond p1 percentage *= (animTime - chanTimes.Values[startIndex]); Debug.Assert(percentage >= 0.0f && percentage <= 1.0f); for (int i = 0; i < stride; i++) { float value = MathUtil.Lerp( chanValues.Values[(startIndex * stride) + i], chanValues.Values[((startIndex + 1) * stride) + i], percentage); ret.Add(value); } return(ret); }
public static source MakeFloatSource(string parentName, string name, string[] components, float[] values, int stride = 1, string type = "float") { var positions = new float_array(); positions.id = parentName + "-" + name + "-array"; var source = new source(); source.id = parentName + "-" + name; source.name = name; positions.count = (ulong)values.Length; positions.Values = values.Select(x => (double)x).ToArray(); var technique = MakeAccessor(type, components, stride, values.Length / components.Length, positions.id); source.technique_common = technique; source.Item = positions; return(source); }
public static source makeTexCoordSource(ref Model3D mdl) { source src = new source(); src.id = "texCoord_source"; float_array fa = new float_array(); fa.id = "texCoord"; List <double> values = new List <double>(); for (int id_num = 0; id_num < mdl.meshes.Count; id_num++) { bool clampX = mdl.meshes[id_num].texture.TextureParamS == 33071; bool clampY = mdl.meshes[id_num].texture.TextureParamT == 33071; int len = mdl.meshes[id_num].colors.Length; for (int i = 0; i < len; i++) { float X = mdl.meshes[id_num].texCoord[i].X; float Y = mdl.meshes[id_num].texCoord[i].Y; if (clampX) { X = (X > 1.0f ? 1.0f : (X < 0.0f ? 0.0f : X)); } if (clampY) { Y = (Y > 1.0f ? 1.0f : (Y < 0.0f ? 0.0f : Y)); } values.Add(X); values.Add(-Y); } } fa.Values = values.ToArray(); fa.count = (ulong)fa.Values.LongLength; src.technique_common = new sourceTechnique_common(); src.technique_common.accessor = MakeTexCoordAccessor(fa.count / 2, fa.id); src.Item = fa; return(src); }
static List <CELLMARK> cellmark_List = new List <CELLMARK>(); // для текущей сцены static void Main() { var filesName = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.cellgrup", SearchOption.AllDirectories); System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); List <Model> Models = new List <Model>(); // список мешей на сцене foreach (var file in filesName) { byte[] array1d = File.ReadAllBytes(file); int ci = 0; // счётчик вхождений //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 using (var br = new BinaryReader(File.Open(file, FileMode.Open))) { for (int i = 0; i < array1d.Length; i++) // проходим по всем байтам файла *.cellgrup { if (array1d[i + 0] == 0x69 && array1d[i + 1] == 0x00 && array1d[i + 2] == 0x00 && array1d[i + 3] == 0x00 && // i*** array1d[i + 4] == 0x64 && array1d[i + 5] == 0x65 && array1d[i + 6] == 0x66 && array1d[i + 7] == 0x61 && // defa array1d[i + 8] == 0x75 && array1d[i + 9] == 0x6C && array1d[i + 10] == 0x74 && array1d[i + 11] == 0x00) // ult* { br.BaseStream.Position = i + 12; // отступаем от "вхождения" на i***default* байт int BlockSize = br.ReadInt32(); // размер блока br.ReadInt32(); // пропускаем пустые байты [00 00 00 00] int type = br.ReadInt32(); // "тип" модели if (type == 1819045731) { ci++; // coll[modc] } if (type == 1634493549) { ci++; // mdla[ttr*] } if (type == 6581618) // только для rmd*[****] { br.BaseStream.Position = i + 4; // "возвращаемся", чтобы скопировать модель Model mesh = new Model(); // создаём модель mesh.BaseStreamPosition = br.BaseStream.Position; mesh.type = type; mesh.index = ci++; // присваиваем и увеличиваем индекс mesh.content = br.ReadBytes(BlockSize).ToList(); Models.Add(mesh); // добавляем её в список моделей на "сцене" } i = i + BlockSize; // ускоряем поиск? } // 63 65 6C 6C 69 6E 73 74 (места моделей) if (array1d[i + 0] == 0x63 && array1d[i + 1] == 0x65 && array1d[i + 2] == 0x6C && array1d[i + 3] == 0x6C && // cell array1d[i + 4] == 0x69 && array1d[i + 5] == 0x6E && array1d[i + 6] == 0x73 && array1d[i + 7] == 0x74) // inst { br.BaseStream.Position = i + 16; int count = br.ReadInt32(); // кол-во координат для расстановки моделей for (int j = 0; j < count; j++) { CELLINST cellinst = new CELLINST(br); cellinst_List.Add(cellinst); } } // 63 65 6C 6C 6D 61 72 6B cellmark if (array1d[i + 0] == 0x63 && array1d[i + 1] == 0x65 && array1d[i + 2] == 0x6C && array1d[i + 3] == 0x6C && // cell array1d[i + 4] == 0x6D && array1d[i + 5] == 0x61 && array1d[i + 6] == 0x72 && array1d[i + 7] == 0x6B) // mark { br.BaseStream.Position = i + 16; int count = br.ReadInt32(); // кол-во координат для расстановки моделей for (int j = 0; j < count; j++) { CELLMARK cellmark = new CELLMARK(br); cellmark_List.Add(cellmark); } } } //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 foreach (var mesh in Models) { for (int ji = 0; ji < mesh.content.Count; ji++) { // ИЩЕМ ВЕРШИНЫ // v // если нашли строку "position" = 00 00 00 00 70 6F 73 69 74 69 6F 6E if (mesh.content[ji + 0] == 0x70 && mesh.content[ji + 1] == 0x6F && mesh.content[ji + 2] == 0x73 && mesh.content[ji + 3] == 0x69 && // 70 6F 73 69 mesh.content[ji + 4] == 0x74 && mesh.content[ji + 5] == 0x69 && mesh.content[ji + 6] == 0x6F && mesh.content[ji + 7] == 0x6E) // 74 69 6F 6E { br.BaseStream.Position = mesh.BaseStreamPosition + ji + 16; // +20, если отступаем OOOO_position int count = br.ReadInt32(); for (int j = 0; j < count; j++) { mesh.positionList.Add(new Vector3(br)); } } ///////////// ИЩЕМ Vn (нормали) if (mesh.content[ji + 0] == 0x6E && mesh.content[ji + 1] == 0x6F && mesh.content[ji + 2] == 0x72 && mesh.content[ji + 3] == 0x6D && // 6E 6F 72 6D mesh.content[ji + 4] == 0x61 && mesh.content[ji + 5] == 0x6C && mesh.content[ji + 6] == 0x73 && mesh.content[ji + 7] == 0x00) // 61 6C 73 00 { br.BaseStream.Position = mesh.BaseStreamPosition + ji + 16; int count = br.ReadInt32(); for (int j = 0; j < count; j++) { mesh.normalsList.Add(new Vector3(br)); } } ///////////// ИЩЕМ ГРАНИ FACES // 70 72 69 6D // 73 ( 00 00 00 ) if (mesh.content[ji + 0] == 0x70 && mesh.content[ji + 1] == 0x72 && mesh.content[ji + 2] == 0x69 && mesh.content[ji + 3] == 0x6D) // 70 72 69 6D 73 { br.BaseStream.Position = mesh.BaseStreamPosition + ji + 16; int primsCount = br.ReadInt32(); for (int j = 0; j < primsCount; j++) { int faceNumber = br.ReadInt32(); int faceCount = br.ReadInt32(); int faceSize = br.ReadInt32(); List <TRI> face = new List <TRI>(); for (int f = 0; f < faceCount; f++) { face.Add(new TRI(br, faceNumber)); } mesh.subMeshFaces.Add(face); for (int jj = 0; jj < 10; jj++) { br.ReadInt32(); // непонятные данные, мб для наложения текстур } if ((faceCount % 2) != 0) { br.ReadUInt16(); // для "выравнивания" читается FF FF } } } ///////////// ИЩЕМ uvs index , индексы текстурных координат // строку "textures" = // (00 00 FF FF) 74 65 78 74 75 72 65 73 // if ( mesh.content[ji+0] == 0x00 && mesh.content[ji+1] == 0x00 && mesh.content[ji+2] == 0x00 && mesh.content[ji+3] == 0x00 && // это необходимо ? if (mesh.content[ji + 0] == 0x74 && mesh.content[ji + 1] == 0x65 && mesh.content[ji + 2] == 0x78 && mesh.content[ji + 3] == 0x74 && // если да mesh.content[ji + 4] == 0x75 && mesh.content[ji + 5] == 0x72 && mesh.content[ji + 6] == 0x65 && mesh.content[ji + 7] == 0x73) // то изменить индексы { br.BaseStream.Position = mesh.BaseStreamPosition + ji + 16; // или +20 в big файле int count = br.ReadInt32(); for (int j = 0; j < count; j++) { mesh.texturesList.Add(br.ReadUInt16()); } } ///////////// ТЕКСТУРНЫЕ КООРДИНАТЫ // vt // uvs. // 75 76 73 00 00 00 00 00 // может попастся два набора, поэтому пока что сохраняем смещение, а затем читаем что надо if (mesh.content[ji + 0] == 0x75 && mesh.content[ji + 1] == 0x76 && mesh.content[ji + 2] == 0x73 && mesh.content[ji + 3] == 0x00) // 75 76 73 00 { uvs_offset_int_list.Add(ji); } /////////////// /* * // mdlattr* * * if ( mesh.content[ji+0] == 0x6D && mesh.content[ji+1] == 0x64 && mesh.content[ji+2] == 0x6C && mesh.content[ji+3] == 0x61 && * mesh.content[ji+4] == 0x74 && mesh.content[ji+5] == 0x74 && mesh.content[ji+6] == 0x72 && mesh.content[ji+7] == 0x00) * { * br.BaseStream.Position = mesh.BaseStreamPosition + ji + 8; * int BlockSize = br.ReadInt32(); br.ReadInt32(); // 00 00 00 00 * * br.ReadInt32(); // 00 00 00 00 * br.ReadInt32(); // 00 00 00 00 * * int defaultBlockSize = br.ReadInt32(); * * br.ReadInt32(); * br.ReadInt32(); * } */ ///////////// mtlctrl* // 6D 74 6C 63 74 72 6C 00 if (mesh.content[ji + 0] == 0x6D && mesh.content[ji + 1] == 0x74 && mesh.content[ji + 2] == 0x6C && mesh.content[ji + 3] == 0x63 && // 6D 74 6C 63 mesh.content[ji + 4] == 0x74 && mesh.content[ji + 5] == 0x72 && mesh.content[ji + 6] == 0x6C && mesh.content[ji + 7] == 0x00) // 74 72 6C 00 { br.BaseStream.Position = mesh.BaseStreamPosition + ji + 16; int count = br.ReadInt32(); for (int j = 0; j < count; j++) { Mtlctrl mtlctrl = new Mtlctrl(br); mesh.mtlctrlList.Add(mtlctrl); } } ///////////// mlyrcolr ??? привильно ли я добавляю в список? по "сомнению" надо выделить три "строки" в один объект if (mesh.content[ji + 0] == 0x6D && mesh.content[ji + 1] == 0x6C && mesh.content[ji + 2] == 0x79 && mesh.content[ji + 3] == 0x72 && // 6D 6C 79 72 mesh.content[ji + 4] == 0x63 && mesh.content[ji + 5] == 0x6F && mesh.content[ji + 6] == 0x6C && mesh.content[ji + 7] == 0x72) // 63 6F 6C 72 { br.BaseStream.Position = mesh.BaseStreamPosition + ji + 20; int count = br.ReadInt32(); for (int j = 0; j < count; j++) { for (int jj = 0; jj < 3; jj++) { Mlyrcolr mlyrcolr = new Mlyrcolr(br); mesh.mlyrcolrList.Add(mlyrcolr); } } } ///////////// mlyrctrl +++ if (mesh.content[ji + 0] == 0x6D && mesh.content[ji + 1] == 0x6C && mesh.content[ji + 2] == 0x79 && mesh.content[ji + 3] == 0x72 && // 6D 6C 79 72 mesh.content[ji + 4] == 0x63 && mesh.content[ji + 5] == 0x74 && mesh.content[ji + 6] == 0x72 && mesh.content[ji + 7] == 0x6C) // 63 74 72 6C { br.BaseStream.Position = mesh.BaseStreamPosition + ji + 16; int flag = br.ReadInt32(); // 0 или 1 int count = br.ReadInt32(); for (int j = 0; j < count; j++) { Mlyrctrl m = new Mlyrctrl(br); mesh.mlyrctrlList.Add(m); } } ///////////// texture* +++ if (mesh.content[ji + 0] == 0x74 && mesh.content[ji + 1] == 0x65 && mesh.content[ji + 2] == 0x78 && mesh.content[ji + 3] == 0x74 && // 74 65 78 74 mesh.content[ji + 4] == 0x75 && mesh.content[ji + 5] == 0x72 && mesh.content[ji + 6] == 0x65 && mesh.content[ji + 7] == 0x00) // 75 72 65 00 { br.BaseStream.Position = mesh.BaseStreamPosition + ji + 20; // br.BaseStream.Position = mesh.BaseStreamPosition + ji + 20; int count = br.ReadInt32(); for (int j = 0; j < count; j++) { Texture thz = new Texture(br); mesh.texture_List.Add(thz); } } ///////////// vtxweigh +++ if (mesh.content[ji + 0] == 0x76 && mesh.content[ji + 1] == 0x74 && mesh.content[ji + 2] == 0x78 && mesh.content[ji + 3] == 0x77 && // 76 74 78 77 mesh.content[ji + 4] == 0x65 && mesh.content[ji + 5] == 0x69 && mesh.content[ji + 6] == 0x67 && mesh.content[ji + 7] == 0x68) // 65 69 67 68 { br.BaseStream.Position = mesh.BaseStreamPosition + ji + 16; int count = br.ReadInt32(); for (int ii = 0; ii < count; ii++) { mesh.vtxweighList.Add(br.ReadSingle()); } } ///////////// jointidx +++ if (mesh.content[ji + 0] == 0x6A && mesh.content[ji + 1] == 0x6F && mesh.content[ji + 2] == 0x69 && mesh.content[ji + 3] == 0x6E && // 6A 6F 69 6E // join mesh.content[ji + 4] == 0x74 && mesh.content[ji + 5] == 0x69 && mesh.content[ji + 6] == 0x64 && mesh.content[ji + 7] == 0x78) // 74 69 64 78 // tidx { br.BaseStream.Position = mesh.BaseStreamPosition + ji + 16; int count = br.ReadInt32(); for (int j = 0; j < count; j++) { mesh.jointidxList.Add(br.ReadUInt16()); } int ffff = 0; if (count % 2 != 0) { ffff = br.ReadUInt16(); } } ///////////// collmodc } // для массива внутри модели //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 if (uvs_offset_int_list.Count > 0) { br.BaseStream.Position = mesh.BaseStreamPosition + uvs_offset_int_list[0] + 8; int BlockSizeU0 = br.ReadInt32(); br.ReadInt32(); int number0 = br.ReadInt32(); // 00 00 00 00 int uvsCount = br.ReadInt32(); for (int uvc = 0; uvc < uvsCount; uvc++) { mesh.uvs0.Add(new Vector2(br)); } mesh.uvsList.Add(mesh.uvs0); } if (uvs_offset_int_list.Count > 1) { br.BaseStream.Position = mesh.BaseStreamPosition + uvs_offset_int_list[1] + 8; int BlockSizeU1 = br.ReadInt32(); br.ReadInt32(); int number1 = br.ReadInt32(); // 01 00 00 00 int uvsCount = br.ReadInt32(); for (int uvc = 0; uvc < uvsCount; uvc++) { mesh.uvs1.Add(new Vector2(br)); } mesh.uvsList.Add(mesh.uvs1); } uvs_offset_int_list.Clear(); // обязательно очищаем для другой модели } // для каждой модели } // binary reader //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 string name = file.Replace(".cellgrup", ""); library_geometries lgeom = new library_geometries() // создаём библиотеку мешей { geometry = new geometry[Models.Count] // в библиотеке геометрии Models.Count мешей }; ///////////////////////////////////////////////////////////////////////////////////////////////// int qqq = 0; // шагаем по списку геометрий в файле foreach (var mesh in Models) // для каждой модели { //----------------------------------------------------------------------------------------------- //{ создаём массив координат для вершин модели float_array xyz_N_array = new float_array() // массив для координат { count = (ulong)mesh.positionList.Count * 3, id = "mesh_" + mesh.index + "_positions_array" }; float_coords = new List <double>(); foreach (var fl in mesh.positionList) { float_coords.Add(fl.x); float_coords.Add(fl.y); float_coords.Add(fl.z); } xyz_N_array.Values = float_coords.ToArray(); //---------------------------------- source pos_source = new source() // источник для координат { Item = xyz_N_array, id = "mesh_" + mesh.index + "_positions", technique_common = new sourceTechnique_common() { accessor = new accessor() { count = (ulong)mesh.positionList.Count, offset = 0L, source = "#" + xyz_N_array.id, stride = 3L, param = new param[] { new param() { name = "X", type = "float" }, new param() { name = "Y", type = "float" }, new param() { name = "Z", type = "float" } } } } }; //} //----------------------------------------------------------------------------------------------- /* * //{ создаём массив координат для нормалей модели * * float_array xyz_Normals = new float_array() * { * count = (ulong)mesh.normalsList.Count * 3; * id = "mesh_" + mesh.index + "_normals_array"; * } * * float_coords = new List<double>(); * * foreach(var fl in mesh.positionList) * { * float_coords.Add(fl.x); * float_coords.Add(fl.y); * float_coords.Add(fl.z); * } * * xyz_Normals.Values = float_coords.ToArray(); * * //---------------------------------- * * source norm_source = new source() * { * Item = xyz_N_array, * id = "mesh_" + mesh.index + "_positions", * * technique_common = new sourceTechnique_common() * { * accessor = new accessor() * { * count = (ulong)mesh.positionList.Count, * offset = 0L, * source = "#" + xyz_N_array.id, * stride = 3L, * * param = new param[] * { * new param() { name = "X", type = "float" }, * new param() { name = "Y", type = "float" }, * new param() { name = "Z", type = "float" } * } * } * } * }; * //} */ //----------------------------------------------------------------------------------------------- vertices v = new vertices() // вершины = часть объекта mesh { id = "mesh_" + mesh.index + "_vertices", input = new InputLocal[] { new InputLocal() // пока что только коорднаты { semantic = "POSITION", source = "#" + pos_source.id } } }; //----------------------------------------------------------------------------------------------- int faceNumber = 0; foreach (var q in mesh.subMeshFaces) { foreach (var qq in q) { faceNumber++; } } triangles tres = new triangles() // треугольники = часть объекта mesh { count = (ulong)faceNumber, input = new InputLocalOffset[] { new InputLocalOffset() // пока что только для координат { semantic = "VERTEX", offset = 0L, source = "#" + v.id } } }; //---------------------------------- StringBuilder all_TRI = new StringBuilder(); foreach (var q in mesh.subMeshFaces) { foreach (var qq in q) { string str = qq.vi0 + " " + qq.vi1 + " " + qq.vi2 + " "; all_TRI.Append(str); } } tres.p = all_TRI.ToString(); //----------------------------------------------------------------------------------------------- mesh m = new mesh() // создаём объект меша { vertices = v, source = new source[1] // пока что только 1 источник для position { pos_source }, Items = new object[1] // для треугольников { tres } }; //----------------------------------------------------------------------------------------------- geometry geom = new geometry() // создаём оболочку для меши { id = "mesh_" + mesh.index, // задаём ей имя mesh_№ Item = m }; lgeom.geometry[qqq++] = geom; } // для каждой модели в файле cellgrup создаём блоки с геометрией //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 library_visual_scenes lvs = new library_visual_scenes(); // создаём библиотеку сцен visual_scene vs = new visual_scene() // создаём сцену, вроде всегда одна { id = "MyScene", // обзываем её node = new node[Models.Count] // добавляем узлы для моделей на сцене }; //=============================================================================================== qqq = 0; // шагаем по списку мешей, создаём им ноды, задаём расположение foreach (var mesh in Models) { //---------------------------------- node n = new node() { id = "mesh" + mesh.index, instance_geometry = new instance_geometry[] { new instance_geometry() { url = "#" + lgeom.geometry[qqq].id } } }; //---------------------------------- n.ItemsElementName = new ItemsChoiceType2[5] { ItemsChoiceType2.translate, ItemsChoiceType2.rotate, ItemsChoiceType2.rotate, ItemsChoiceType2.rotate, ItemsChoiceType2.scale }; //---------------------------------- float xx = 0.0f; float yy = 0.0f; float zz = 0.0f; float rx = 0.0f; float ry = 0.0f; float rz = 0.0f; for (int ccc = 0; ccc < cellinst_List.Count; ccc++) { if (mesh.index == cellinst_List[ccc].number) { xx = cellinst_List[ccc].position.x; yy = cellinst_List[ccc].position.y; zz = cellinst_List[ccc].position.z; rx = cellinst_List[ccc].rotation.x; ry = cellinst_List[ccc].rotation.y; rz = cellinst_List[ccc].rotation.z; } } for (int ccc = 0; ccc < cellmark_List.Count; ccc++) { if (mesh.index == cellmark_List[ccc].number1) { xx = cellmark_List[ccc].position.x; yy = cellmark_List[ccc].position.y; zz = cellmark_List[ccc].position.z; rx = cellmark_List[ccc].rotation.x; ry = cellmark_List[ccc].rotation.y; rz = cellmark_List[ccc].rotation.z; } } //---------------------------------- n.Items = new object[5] { new TargetableFloat3() { sid = "location", // translate Values = new double[3] { xx, yy, zz } }, new rotate() { sid = "rotationX", Values = new double[4] { 0, 0, 1, rz *57.5 } }, // Z new rotate() { sid = "rotationY", Values = new double[4] { 0, 1, 0, ry *57.5 } }, // Y почему такой "угол" ? new rotate() { sid = "rotationZ", Values = new double[4] { 1, 0, 0, rx *57.5 } }, // X new TargetableFloat3() { sid = "scale", Values = new double[3] { 1, 1, 1 } } }; //---------------------------------- vs.node[qqq] = n; qqq++; } // для каждой модели в файле cellgrup //----------------------------------------------------------------------------------------------- lvs.visual_scene = new visual_scene[1] // создаём массив для сцен { vs // добавляем visual_scene в library_visual_scenes }; //----------------------------------------------------------------------------------------------- COLLADA collada = new COLLADA() { asset = new asset() { up_axis = UpAxisType.Z_UP }, Items = new object[] // для библиотеки мешей и сцен { lgeom, // присваиваем колладе библиотеку геометрию lvs // в массив Item добавляем библиотеку сцен }, scene = new COLLADAScene() { instance_visual_scene = new InstanceWithExtra() { url = "#" + vs.id } } }; //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 collada.Save(name + ".dae"); Models.Clear(); cellinst_List.Clear(); cellmark_List.Clear(); //88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 } // для каждого cellgrup файла } // void Main()
internal DAEGeometry(DAELoaderNode loader, geometry geo) { if (geo.Item == null || !(geo.Item is mesh)) { // empty or not supported geometry return; } mesh m = geo.Item as mesh; // load sources Dictionary <string, MeshSource> sources = new Dictionary <string, MeshSource>(); foreach (source src in m.source) { if (src.Item is float_array) { float_array values = src.Item as float_array; int stride = (int)src.technique_common.accessor.stride; sources.Add(src.id, new MeshSource(values.Values, stride)); } } // load positions foreach (InputLocal input in m.vertices.input) { if (input.semantic.Equals("POSITION")) { sources.Add(m.vertices.id, sources[DAEUtils.GetUrl(input.source).Id]); break; } } // load primitives foreach (var item in m.Items) { // load triangles if (item is triangles) { triangles tris = item as triangles; DAEVertexDescription[] vertices = new DAEVertexDescription[tris.count * 3]; int[] p = DAEUtils.StringToIntArray(tris.p); int stepSize = p.Length / ((int)tris.count * 3); foreach (InputLocalOffset input in tris.input) { SetVertices(input, p, stepSize, sources, vertices); } if (!ContainsTangents(tris.input)) { GenerateMeshTangents(vertices); } _triangles.Add(new DAETriangles(loader, vertices, tris.material)); } else if (item is polylist) { polylist polys = item as polylist; int[] polyVertexCounts = DAEUtils.StringToIntArray(polys.vcount); int vertexCount = 0; int triCount = 0; for (int i = 0; i < polyVertexCounts.Length; i++) { vertexCount += polyVertexCounts[i]; triCount += polyVertexCounts[i] - 2; } DAEVertexDescription[] polyVertices = new DAEVertexDescription[vertexCount]; int[] p = DAEUtils.StringToIntArray(polys.p); int stepSize = p.Length / vertexCount; foreach (InputLocalOffset input in polys.input) { SetVertices(input, p, stepSize, sources, polyVertices); } // triangulation DAEVertexDescription[] triVertices = new DAEVertexDescription[triCount * 3]; int triVertexIdx = 0; int polyVertexIdx = 0; for (int i = 0; i < polyVertexCounts.Length; i++) { int triVertex = 0; for (int k = 0; k < polyVertexCounts[i]; k++) { if (triVertex == 3) { triVertex = 1; k--; // repeat first vertex triVertices[triVertexIdx++] = polyVertices[polyVertexIdx]; } triVertices[triVertexIdx++] = polyVertices[polyVertexIdx + k]; triVertex++; } // skip to next polygon polyVertexIdx += polyVertexCounts[i]; } if (!ContainsTangents(polys.input)) { GenerateMeshTangents(triVertices); } _triangles.Add(new DAETriangles(loader, triVertices, polys.material)); } } }
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { COLLADA model = new COLLADA(); // init new model.asset = new asset(); model.asset.contributor[1] = new assetContributor(); model.asset.contributor[0] = new assetContributor(); model.asset.unit = new assetUnit(); model.asset.up_axis = new UpAxisType(); model.Items = new object[1]; // asset model.asset.contributor[0].author = "caimagic"; model.asset.contributor[0].authoring_tool = "FBX COLLADA exporter"; model.asset.contributor[0].comments = "hello world"; model.asset.unit.meter = 0.01; model.asset.unit.name = "centimer"; model.asset.up_axis = UpAxisType.Y_UP; // library_geometries library_geometries library_geom = new library_geometries(); library_geom.geometry[1] = new geometry(); library_geom.geometry[0] = new geometry(); geometry geom = new geometry(); mesh geomMesh = new mesh(); geomMesh.source[3] = new source(); geomMesh.source[0] = new source(); geomMesh.source[1] = new source(); geomMesh.source[2] = new source(); float_array position_float_array = new float_array(); float_array normal_float_array = new float_array(); float_array uv_float_array = new float_array(); sourceTechnique_common position_technique_common = new sourceTechnique_common(); sourceTechnique_common normal_technique_common = new sourceTechnique_common(); sourceTechnique_common uv_technique_common = new sourceTechnique_common(); position_float_array.id = "Plane001-POSITION-array"; position_float_array.count = 9; //根据count创建一个数组 position_float_array.Values = new double[position_float_array.count]; position_float_array.Values[0] = -49.719101f; position_float_array.Values[1] = -41.011238f; position_float_array.Values[2] = 0.000000f; position_float_array.Values[3] = 49.719101f; position_float_array.Values[4] = -41.011238f; position_float_array.Values[5] = 0.000000f; position_float_array.Values[6] = -49.719101f; position_float_array.Values[7] = 41.011238f; position_float_array.Values[8] = 0.000000f; position_technique_common.accessor = new accessor(); /* * 创建数组的几种形式 * double[] array = new double[10]; * double[] array = { 0.0, 1.1, 2.2}; * double[] array = new double[5] { 99, 98, 92, 97, 95}; * double[] array = new double[ ] { 99, 98, 92, 97, 95}; * double[] another_array = array;*/ position_technique_common.accessor.param = new param[3]; position_technique_common.accessor.param[0] = new param(); position_technique_common.accessor.param[1] = new param(); position_technique_common.accessor.param[2] = new param(); position_technique_common.accessor.source = "#" + position_float_array.id; position_technique_common.accessor.count = 3; position_technique_common.accessor.stride = 3; position_technique_common.accessor.param[0].name = "X"; position_technique_common.accessor.param[0].type = "float"; position_technique_common.accessor.param[1].name = "Y"; position_technique_common.accessor.param[1].type = "float"; position_technique_common.accessor.param[2].name = "Z"; position_technique_common.accessor.param[2].type = "float"; normal_float_array.id = "Plane001-Normal0-array"; normal_float_array.count = 9; normal_float_array.Values = new double[normal_float_array.count]; normal_float_array.Values[0] = 0.0f; normal_float_array.Values[1] = 0.0f; normal_float_array.Values[2] = 1.0f; normal_float_array.Values[3] = 0.0f; normal_float_array.Values[4] = 0.0f; normal_float_array.Values[5] = 1.0f; normal_float_array.Values[6] = 0.0f; normal_float_array.Values[7] = 0.0f; normal_float_array.Values[8] = 1.0f; normal_technique_common.accessor = new accessor(); normal_technique_common.accessor.param = new param[3]; normal_technique_common.accessor.param[0] = new param(); normal_technique_common.accessor.param[1] = new param(); normal_technique_common.accessor.param[2] = new param(); normal_technique_common.accessor.source = "#" + normal_float_array.id; normal_technique_common.accessor.count = 3; normal_technique_common.accessor.stride = 3; normal_technique_common.accessor.param[0].name = "X"; normal_technique_common.accessor.param[0].type = "float"; normal_technique_common.accessor.param[1].name = "Y"; normal_technique_common.accessor.param[1].type = "float"; normal_technique_common.accessor.param[2].name = "Z"; normal_technique_common.accessor.param[2].type = "float"; uv_float_array.id = "Plane001-UV0-array"; uv_float_array.count = 6; uv_float_array.Values = new double[uv_float_array.count]; uv_float_array.Values[0] = 1.0000f; uv_float_array.Values[1] = 0.0000f; uv_float_array.Values[2] = 0.0000f; uv_float_array.Values[3] = 0.0000f; uv_float_array.Values[4] = 1.0000f; uv_float_array.Values[5] = 1.0000f; uv_technique_common.accessor = new accessor(); uv_technique_common.accessor.param = new param[2]; uv_technique_common.accessor.param[0] = new param(); uv_technique_common.accessor.param[1] = new param(); uv_technique_common.accessor.source = "#" + uv_float_array.id; uv_technique_common.accessor.count = 3; uv_technique_common.accessor.stride = 2; uv_technique_common.accessor.param[0].name = "S"; uv_technique_common.accessor.param[0].type = "float"; uv_technique_common.accessor.param[1].name = "T"; uv_technique_common.accessor.param[1].type = "float"; geomMesh.source[0].id = "Plane001-POSITION"; geomMesh.source[0].Item = position_float_array; geomMesh.source[0].technique_common = position_technique_common; geomMesh.source[1].id = "Plane001-Normal0"; geomMesh.source[1].Item = normal_float_array; geomMesh.source[1].technique_common = normal_technique_common; geomMesh.source[2].id = "Plane001-UV0"; geomMesh.source[2].Item = uv_float_array; geomMesh.source[2].technique_common = uv_technique_common; geomMesh.vertices = new vertices(); geomMesh.vertices.input[0] = new InputLocal(); geomMesh.vertices.input[0].semantic = "POSITION"; geomMesh.vertices.input[0].source = "#Plane001-POSITION"; geomMesh.vertices.id = "Plane001-VERTEX"; triangles meshTriangle = new triangles(); meshTriangle.count = 1; meshTriangle.input = new InputLocalOffset[3]; meshTriangle.input[0] = new InputLocalOffset(); meshTriangle.input[1] = new InputLocalOffset(); meshTriangle.input[2] = new InputLocalOffset(); meshTriangle.input[0].semantic = "VERTEX"; meshTriangle.input[0].offset = 0; meshTriangle.input[0].source = "#Plane001-VERTEX"; meshTriangle.input[1].semantic = "NORMAL"; meshTriangle.input[1].offset = 1; meshTriangle.input[1].source = "#Plane001-Normal0"; meshTriangle.input[2].semantic = "TEXCOORD"; meshTriangle.input[2].offset = 2; meshTriangle.input[2].set = 0; meshTriangle.input[2].source = "#Plane001-UV0"; string p = ""; int[] pArray = new int[9]; pArray[0] = 0; pArray[1] = 0; pArray[2] = 0; pArray[3] = 1; pArray[4] = 1; pArray[5] = 1; pArray[6] = 2; pArray[7] = 2; pArray[8] = 2; foreach (var data in pArray) { if (data is int) { p += " " + data.ToString(); } } meshTriangle.p = p; geomMesh.Items = new object[1]; geomMesh.Items[0] = new object(); geomMesh.Items[0] = meshTriangle; geom.Item = geomMesh; geom.id = "Plane001-lib"; geom.name = "Plane001Mesh"; library_geom.geometry[0] = geom; // library_visual_scenes library_visual_scenes lib_visual_scene = new library_visual_scenes(); lib_visual_scene.visual_scene = new visual_scene[1]; lib_visual_scene.visual_scene[0] = new visual_scene(); visual_scene visaul = new visual_scene(); visaul.node = new node[1]; visaul.node[0] = new node(); visaul.node[0].name = "Triangle001"; visaul.node[0].id = "Triangle001"; visaul.node[0].sid = "Triangle001"; visaul.node[0].instance_geometry = new instance_geometry[1]; visaul.node[0].instance_geometry[0] = new instance_geometry(); visaul.node[0].instance_geometry[0].url = "#Plane001-lib"; visaul.node[0].extra = new extra[1]; visaul.node[0].extra[0] = new extra(); visaul.node[0].extra[0].technique = new technique[1]; visaul.node[0].extra[0].technique[0] = new technique(); visaul.node[0].extra[0].technique[0].profile = "FCOLLADA"; visaul.name = "cube"; visaul.id = "cube"; lib_visual_scene.visual_scene[0] = visaul; model.Items = new object[2]; model.Items[0] = library_geom; model.Items[1] = lib_visual_scene; model.scene = new COLLADAScene(); model.scene.instance_visual_scene = new InstanceWithExtra(); model.scene.instance_visual_scene.url = "#" + visaul.id; model.Save("C:\\ProgramData\\Autodesk\\revit\\Addins\\2020\\dd.dae"); return(0); }
private static void ParseVertexSource(ref STVertex vertex, ColladaScene scene, source source, int numTexCoordChannels, int numColorChannels, int stride, int index, int set, string semantic) { float_array array = source.Item as float_array; switch (semantic) { case "VERTEX": case "POSITION": vertex.Position = new Vector3( (float)array.Values[index + 0], (float)array.Values[index + 1], (float)array.Values[index + 2]); vertex.Position = ApplyUintScaling(scene, vertex.Position); if (scene.UpAxisType == UpAxisType.Z_UP) { vertex.Position = new Vector3( vertex.Position.X, vertex.Position.Z, -vertex.Position.Y); } break; case "NORMAL": vertex.Normal = new Vector3( (float)array.Values[index + 0], (float)array.Values[index + 1], (float)array.Values[index + 2]); if (scene.UpAxisType == UpAxisType.Z_UP) { vertex.Normal = new Vector3( vertex.Normal.X, vertex.Normal.Z, -vertex.Normal.Y); } break; case "TEXCOORD": vertex.TexCoords[set] = new Vector2( (float)array.Values[index + 0], (float)array.Values[index + 1]); break; case "COLOR": float R = 1, G = 1, B = 1, A = 1; if (stride >= 1) { R = (float)array.Values[index + 0]; } if (stride >= 2) { G = (float)array.Values[index + 1]; } if (stride >= 3) { B = (float)array.Values[index + 2]; } if (stride >= 4) { A = (float)array.Values[index + 3]; } vertex.Colors[set] = new Vector4(R, G, B, A); break; } //We need to make sure the axis is converted to Z up /* switch (scene.UpAxisType) * { * case UpAxisType.X_UP: * break; * case UpAxisType.Y_UP: * Vector3 pos = vertex.Position; * Vector3 nrm = vertex.Normal; * // vertex.Position = new Vector3(pos.X, pos.Z, pos.Y); * // vertex.Normal = new Vector3(nrm.X, nrm.Z, nrm.Y); * break; * }*/ }
public void Export(RootEntity[] entities, string selectedPath) { for (int i = 0; i < entities.Length; i++) { var entity = entities[i]; var modelCount = entity.ChildEntities.Length; var geometries = new library_geometries { geometry = new geometry[modelCount] }; var visualSceneNodes = new node[modelCount]; const string visualSceneName = "visual-scene"; var visualScenes = new library_visual_scenes { visual_scene = new[] { new visual_scene { id = visualSceneName, name = visualSceneName, node = visualSceneNodes } } }; for (int j = 0; j < modelCount; j++) { var model = (ModelEntity)entity.ChildEntities[j]; var modelName = string.Format("model-{0}-lib", j); var materialName = string.Format("{0}-material", modelName); var triangleCount = model.Triangles.Count(); var elementGroupCount = triangleCount * 3; var elementCount = elementGroupCount * 3; var acessorParams = new[] { new param { name = "X", type = "float" }, new param { name = "Y", type = "float" }, new param { name = "Z", type = "float" } }; #region Position var positionArrayName = string.Format("{0}-positions-array", modelName); var positionAccessor = new accessor { count = (ulong)elementGroupCount, offset = 0, source = string.Format("#{0}", positionArrayName), stride = 3, param = acessorParams }; var positionTechnique = new sourceTechnique_common { accessor = positionAccessor }; var positionArrayValues = new double[elementCount]; var positionArray = new float_array { id = positionArrayName, count = (ulong)elementCount, Values = positionArrayValues }; var positionName = string.Format("{0}-positions", modelName); var positionSource = new source { id = positionName, name = "position", Item = positionArray, technique_common = positionTechnique }; #endregion #region Normal var normalArrayName = string.Format("{0}-normals-array", modelName); var normalAccessor = new accessor { count = (ulong)elementGroupCount, offset = 0, source = string.Format("#{0}", normalArrayName), stride = 3, param = acessorParams }; var normalTechinique = new sourceTechnique_common { accessor = normalAccessor }; var normalArrayValues = new double[elementCount]; var normalArray = new float_array { id = normalArrayName, count = (ulong)elementCount, Values = normalArrayValues }; var normalName = string.Format("{0}-normals", modelName); var normalSource = new source { id = normalName, name = "normal", Item = normalArray, technique_common = normalTechinique }; #endregion #region Processing var triangleIndices = new StringBuilder(); for (int l = 0; l < model.Triangles.Length; l++) { var triangle = model.Triangles[l]; for (var k = 0; k < 3; k++) { var elementIndex = l * 3 + k; var vertex = triangle.Vertices[k]; var normal = triangle.Normals[k]; var color = triangle.Colors[k]; var uv = triangle.Uv[k]; positionArrayValues[elementIndex] = vertex.X; positionArrayValues[elementIndex + 1] = vertex.Y; positionArrayValues[elementIndex + 2] = vertex.Z; normalArrayValues[elementIndex] = normal.X; normalArrayValues[elementIndex + 1] = normal.Y; normalArrayValues[elementIndex + 2] = normal.Z; triangleIndices.Append(elementIndex); triangleIndices.Append(" "); } } #endregion #region Vertices var verticesName = string.Format("{0}-vertices", modelName); var triangles = new triangles { count = (ulong)triangleCount, material = materialName, input = new[] { new InputLocalOffset { offset = 0, semantic = "VERTEX", source = string.Format("#{0}", verticesName) }//, //new InputLocalOffset //{ // offset = 1, // semantic = "NORMAL", // source = string.Format("#{0}", normalName) //} }, p = triangleIndices.ToString() }; #endregion #region Mesh var mesh = new mesh { source = new[] { positionSource, normalSource }, vertices = new vertices { id = verticesName, input = new[] { new InputLocal { semantic = "POSITION", source = string.Format("#{0}", positionName) } } }, Items = new object[] { triangles } }; #endregion #region Geometry var geometryName = string.Format("{0}-geometry", modelName); var geometry = new geometry { id = geometryName, name = geometryName, Item = mesh }; geometries.geometry[j] = geometry; #endregion #region Visual Node var visualSceneNodeName = string.Format("{0}-node", modelName); visualSceneNodes[j] = new node { name = visualSceneNodeName, id = visualSceneNodeName, instance_geometry = new[] { new instance_geometry { url = string.Format("#{0}", geometryName) } } }; #endregion } var collada = new COLLADA { Items = new Object[] { geometries, visualScenes }, scene = new COLLADAScene { instance_visual_scene = new InstanceWithExtra { url = string.Format("#{0}", visualSceneName) } } }; var fileName = string.Format("{0}/dae{1}.dae", selectedPath, i); collada.Save(fileName); } }
// return mesh id private string CreateMeshWithSubmeshes(Mesh mesh, List <string> materialNames) { string id = ""; if (meshLookup.TryGetValue(mesh, out id)) { return(id); } var geometry = new geometry(); geometries.Add(geometry); id = CreateId(); geometry.id = id; var m = new mesh(); geometry.Item = m; m.source = new source[] { new source(), // position new source(), // normal new source(), // uvs }; m.source[0].id = CreateId(); var fa = new float_array(); fa.id = CreateId(); fa.Values = ToDoubleArray(mesh.vertices); fa.count = (ulong)fa.Values.Length; m.source[0].Item = fa; m.source[0].technique_common = new sourceTechnique_common(); m.source[0].technique_common.accessor = new accessor(); m.source[0].technique_common.accessor.count = fa.count / 3; m.source[0].technique_common.accessor.source = "#" + fa.id; m.source[0].technique_common.accessor.stride = 3; m.source[0].technique_common.accessor.param = new[] { new param(), new param(), new param() }; m.source[0].technique_common.accessor.param[0].name = "X"; m.source[0].technique_common.accessor.param[0].type = "float"; m.source[0].technique_common.accessor.param[1].name = "Y"; m.source[0].technique_common.accessor.param[1].type = "float"; m.source[0].technique_common.accessor.param[2].name = "Z"; m.source[0].technique_common.accessor.param[2].type = "float"; m.source[1].id = CreateId(); fa = new float_array(); fa.id = CreateId(); fa.Values = ToDoubleArray(mesh.normals); fa.count = (ulong)fa.Values.Length; m.source[1].Item = fa; m.source[1].technique_common = new sourceTechnique_common(); m.source[1].technique_common.accessor = new accessor(); m.source[1].technique_common.accessor.count = fa.count / 3; m.source[1].technique_common.accessor.source = "#" + fa.id; m.source[1].technique_common.accessor.stride = 3; m.source[1].technique_common.accessor.param = new[] { new param(), new param(), new param() }; m.source[1].technique_common.accessor.param[0].name = "X"; m.source[1].technique_common.accessor.param[0].type = "float"; m.source[1].technique_common.accessor.param[1].name = "Y"; m.source[1].technique_common.accessor.param[1].type = "float"; m.source[1].technique_common.accessor.param[2].name = "Z"; m.source[1].technique_common.accessor.param[2].type = "float"; m.source[2].id = CreateId(); fa = new float_array(); fa.id = CreateId(); fa.Values = ToDoubleArray(mesh.uv); fa.count = (ulong)fa.Values.Length; m.source[2].Item = fa; m.source[2].technique_common = new sourceTechnique_common(); m.source[2].technique_common.accessor = new accessor(); m.source[2].technique_common.accessor.count = fa.count / 2; m.source[2].technique_common.accessor.source = "#" + fa.id; m.source[2].technique_common.accessor.stride = 2; m.source[2].technique_common.accessor.param = new[] { new param(), new param() }; m.source[2].technique_common.accessor.param[0].name = "X"; m.source[2].technique_common.accessor.param[0].type = "float"; m.source[2].technique_common.accessor.param[1].name = "Y"; m.source[2].technique_common.accessor.param[1].type = "float"; m.vertices = new vertices(); m.vertices.id = CreateId(); m.vertices.input = new InputLocal[] { new InputLocal(), // position }; m.vertices.input[0].semantic = "POSITION"; m.vertices.input[0].source = "#" + m.source[0].id; var submeshes = new List <object>(); for (int i = 0; i < mesh.subMeshCount; i++) { var triangles = new List <int>(); var stringWriter = new StringWriter(); var t = mesh.GetTriangles(i); triangles.AddRange(t); for (int j = 0; j < t.Length; j = j + 3) { // index for position, normal and texcoord stringWriter.Write("{0} ", t[j]); stringWriter.Write("{0} ", t[j]); stringWriter.Write("{0} ", t[j]); stringWriter.Write("{0} ", t[j + 1]); stringWriter.Write("{0} ", t[j + 1]); stringWriter.Write("{0} ", t[j + 1]); stringWriter.Write("{0} ", t[j + 2]); stringWriter.Write("{0} ", t[j + 2]); stringWriter.Write("{0} ", t[j + 2]); } var tris = new triangles(); tris.count = (ulong)(triangles.Count / 3); tris.material = materialNames[i]; tris.input = new InputLocalOffset[] { new InputLocalOffset(), new InputLocalOffset(), new InputLocalOffset() }; tris.input[0].offset = 0; tris.input[0].semantic = "VERTEX"; tris.input[0].source = "#" + m.vertices.id; tris.p = stringWriter.ToString(); tris.input[1].offset = 1; tris.input[1].semantic = "NORMAL"; tris.input[1].source = "#" + m.source[1].id; tris.input[2].offset = 2; tris.input[2].semantic = "TEXCOORD"; tris.input[2].source = "#" + m.source[2].id; tris.input[2].set = 0; submeshes.Add(tris); } m.Items = submeshes.ToArray(); meshLookup[mesh] = id; return(id); }
public static ColladaSource FromCollada(source src) { var source = new ColladaSource(); source.id = src.id; var accessor = src.technique_common.accessor; // TODO: check src.#ID? float_array floats = null; Name_array names = null; if (src.Item is float_array) { floats = src.Item as float_array; // Workaround for empty arrays being null if (floats.Values == null) { floats.Values = new double[] { } } ; if ((int)floats.count != floats.Values.Length || floats.count < accessor.stride * accessor.count + accessor.offset) { throw new ParsingException("Float source data size mismatch. Check source and accessor item counts."); } } else if (src.Item is Name_array) { names = src.Item as Name_array; // Workaround for empty arrays being null if (names.Values == null) { names.Values = new string[] { } } ; if ((int)names.count != names.Values.Length || names.count < accessor.stride * accessor.count + accessor.offset) { throw new ParsingException("Name source data size mismatch. Check source and accessor item counts."); } } else { throw new ParsingException("Unsupported source data format."); } var paramOffset = 0; foreach (var param in accessor.param) { if (param.name == null) { param.name = "default"; } if (param.type == "float" || param.type == "double") { var items = new List <Single>((int)accessor.count); var offset = (int)accessor.offset; for (var i = 0; i < (int)accessor.count; i++) { items.Add((float)floats.Values[offset + paramOffset]); offset += (int)accessor.stride; } source.FloatParams.Add(param.name, items); } else if (param.type == "float4x4") { var items = new List <Matrix4>((int)accessor.count); var offset = (int)accessor.offset; for (var i = 0; i < (int)accessor.count; i++) { var itemOff = offset + paramOffset; var mat = new Matrix4( (float)floats.Values[itemOff + 0], (float)floats.Values[itemOff + 1], (float)floats.Values[itemOff + 2], (float)floats.Values[itemOff + 3], (float)floats.Values[itemOff + 4], (float)floats.Values[itemOff + 5], (float)floats.Values[itemOff + 6], (float)floats.Values[itemOff + 7], (float)floats.Values[itemOff + 8], (float)floats.Values[itemOff + 9], (float)floats.Values[itemOff + 10], (float)floats.Values[itemOff + 11], (float)floats.Values[itemOff + 12], (float)floats.Values[itemOff + 13], (float)floats.Values[itemOff + 14], (float)floats.Values[itemOff + 15] ); items.Add(mat); offset += (int)accessor.stride; } source.MatrixParams.Add(param.name, items); } else if (param.type.ToLower() == "name") { var items = new List <String>((int)accessor.count); var offset = (int)accessor.offset; for (var i = 0; i < (int)accessor.count; i++) { items.Add(names.Values[offset + paramOffset]); offset += (int)accessor.stride; } source.NameParams.Add(param.name, items); } else { throw new ParsingException("Unsupported accessor param type: " + param.type); } paramOffset++; } return(source); } }
protected mesh CreateCaseMesh(BoxProperties caseProperties) { // build box Box box = new Box(0, caseProperties); // build list of vertices / normals / UVs ulong vertexCount = 0, normalCount = 0, uvCount = 0; List <double> doubleArrayPosition = new List <double>(), doubleArrayNormal = new List <double>(), doubleArrayUV = new List <double>(); foreach (Vector3D p in box.PointsSmallOffset) { doubleArrayPosition.Add(p.X); doubleArrayPosition.Add(p.Y); doubleArrayPosition.Add(p.Z); ++vertexCount; } foreach (Vector3D n in box.Normals) { doubleArrayNormal.Add(n.X); doubleArrayNormal.Add(n.Y); doubleArrayNormal.Add(n.Z); ++normalCount; } foreach (Vector2D uv in box.UVs) { doubleArrayUV.Add(uv.X); doubleArrayUV.Add(uv.Y); ++uvCount; } mesh caseMesh = new mesh(); // position source source casePositionSource = new source() { id = "case_position", name = "case_position" }; float_array farrayPosition = new float_array { id = "case_position_float_array", count = (ulong)doubleArrayPosition.Count, Values = doubleArrayPosition.ToArray() }; casePositionSource.technique_common = new sourceTechnique_common() { accessor = new accessor() { stride = 3, count = vertexCount, source = "#case_position_float_array", param = new param[] { new param() { name = "X", type = "float" }, new param() { name = "Y", type = "float" }, new param() { name = "Z", type = "float" } } } }; casePositionSource.Item = farrayPosition; // normal source source casePositionNormal = new source() { id = "case_normal", name = "case_normal" }; float_array farrayNormal = new float_array { id = "case_normal_float_array", count = (ulong)doubleArrayNormal.Count, Values = doubleArrayNormal.ToArray() }; casePositionNormal.technique_common = new sourceTechnique_common() { accessor = new accessor() { stride = 3, count = normalCount, source = "#case_normal_float_array", param = new param[] { new param() { name = "X", type = "float" }, new param() { name = "Y", type = "float" }, new param() { name = "Z", type = "float" } } } }; casePositionNormal.Item = farrayNormal; // uv source source casePositionUV = new source() { id = "case_UV", name = "pallet_UV" }; float_array farrayUV = new float_array { id = "case_UV_float_array", count = (ulong)doubleArrayUV.Count, Values = doubleArrayUV.ToArray() }; casePositionUV.technique_common = new sourceTechnique_common() { accessor = new accessor() { stride = 2, count = vertexCount, source = "#case_UV_float_array", param = new param[] { new param() { name = "S", type = "float" }, new param() { name = "T", type = "float" } } } }; casePositionUV.Item = farrayUV; // insert sources caseMesh.source = new source[] { casePositionSource, casePositionNormal, casePositionUV }; // vertices InputLocal verticesInput = new InputLocal() { semantic = "POSITION", source = "#case_position" }; caseMesh.vertices = new vertices() { id = "case_vertex", input = new InputLocal[] { verticesInput } }; List <object> trianglesList = new List <object>(); // build list of triangles foreach (HalfAxis.HAxis axis in HalfAxis.All) { triangles trianglesCase = new triangles() { material = string.Format("materialCase{0}", (uint)axis), count = 2 }; trianglesCase.input = new InputLocalOffset[] { new InputLocalOffset() { semantic = "VERTEX", source = "#case_vertex", offset = 0 } , new InputLocalOffset() { semantic = "NORMAL", source = "#case_normal", offset = 1 } , new InputLocalOffset() { semantic = "TEXCOORD", source = "#case_UV", offset = 2, set = 0, setSpecified = true } }; string triangle_string = string.Empty; foreach (TriangleIndices tr in box.TrianglesByFace(axis)) { triangle_string += tr.ConvertToString(0); } trianglesCase.p = triangle_string; trianglesList.Add(trianglesCase); } // build list of lines lines linesCase = new lines() { material = "materialCaseLines", count = 12, input = new InputLocalOffset[] { new InputLocalOffset() { semantic = "VERTEX", source = "#case_vertex", offset = 0 } }, p = "0 1 1 2 2 3 3 0 4 5 5 6 6 7 7 4 0 4 1 5 2 6 3 7" }; trianglesList.Add(linesCase); caseMesh.Items = trianglesList.ToArray(); return(caseMesh); }
private void GeometrySourcePositions(int documentAndMaterialIdHash, IList <ModelGeometry> geometries, string nodename) { float_array position_float_array = new float_array(); float_array normal_float_array = new float_array(); float_array uv_float_array = new float_array(); sourceTechnique_common position_technique_common = new sourceTechnique_common(); sourceTechnique_common normal_technique_common = new sourceTechnique_common(); sourceTechnique_common uv_technique_common = new sourceTechnique_common(); Func <ModelGeometry, int> getCount; if ((getCount = common.T_PointCount) == null) { getCount = common.T_PointCount = new Func <ModelGeometry, int>(common.T.GetPointCount); } //这是统计geometries - {0} - Pooints - count 数值的和 //应该统计 某项中 Pooints的和 //[0] 算是一个几何体,我们要得到几何体下面的Potints的数量,然后乘以3 得到坐标的数量。 // geometries // [0]:物体模型 // Points: 点对象 // [0]:包含XYZ的坐标 int num = geometries.Sum(getCount); // 现在我有了一个数据模型,我要对这个数据模型进行操作!!! // geometries - geometry - mesh - source - float_array // 思路,迭代geometries列表,从索引为 0 的第一个ModelGeometry对象geometry获取属性为Point的数量,乘以3得到坐标数量。 var geometriesPonits = geometries.Select(t => t.Points).ToList(); int num1 = geometriesPonits.Count; library_geometries library_Geometries = new library_geometries { geometry = new geometry[geometries.Count] //创建library_geometries中存在的多个geometry对象数组 }; mesh[] geomMesh = new mesh[geometries.Count]; //setting source //geomMesh.source[0].id = "geom-" + documentAndMaterialIdHash + "-positions"; //position_float_array.id = "geom-" + documentAndMaterialIdHash + "-positions-array"; position_float_array.count = (ulong)(num * 3);//这里有问题3876了都 using (IEnumerator <ModelGeometry> enumerator = geometries.GetEnumerator()) { while (enumerator.MoveNext()) { ModelGeometry geometry = enumerator.Current; if (!geometry.Transform.IsIdentity) { Parallel.For(0, geometry.Points.Count, delegate(int iPoint) { geometry.Points[iPoint] = geometry.Transform.OfPoint(geometry.Points[iPoint]); }); } for (int i = 0; i < geometry.Points.Count; i++) { XYZ xYZ = geometry.Points[i]; position_float_array.Values = new double[] { xYZ.X, xYZ.Y, xYZ.Z }; // TODO } } } position_technique_common.accessor = new accessor(); position_technique_common.accessor.param = new param[3]; position_technique_common.accessor.param[0] = new param(); position_technique_common.accessor.param[1] = new param(); position_technique_common.accessor.param[2] = new param(); position_technique_common.accessor.source = "#" + position_float_array.id; position_technique_common.accessor.count = 3; position_technique_common.accessor.stride = 3; position_technique_common.accessor.param[0].name = "X"; position_technique_common.accessor.param[0].type = "float"; position_technique_common.accessor.param[1].name = "Y"; position_technique_common.accessor.param[1].type = "float"; position_technique_common.accessor.param[2].name = "Z"; position_technique_common.accessor.param[2].type = "float"; }
internal Animation.KeyPartsUsed SetKeys(string bone, List <float> times, List <MeshLib.KeyFrame> keys, library_visual_scenes scenes, List <MeshLib.KeyFrame> axisAngleKeys) { Animation.KeyPartsUsed ret = 0; foreach (channel chan in mChannels) { //extract the node name and address int sidx = chan.target.IndexOf('/'); string sid = chan.target.Substring(0, sidx); node n = AnimForm.LookUpNode(scenes, sid); if (n == null) { continue; } if (bone != n.name) { continue; } //grab sampler key string sampKey = chan.source; //strip # sampKey = sampKey.Substring(1); sampler samp = mSamplers[sampKey]; string srcInp = GetSourceForSemantic(samp, "INPUT"); string srcOut = GetSourceForSemantic(samp, "OUTPUT"); string srcC1 = GetSourceForSemantic(samp, "IN_TANGENT"); string srcC2 = GetSourceForSemantic(samp, "OUT_TANGENT"); float_array chanTimes = mSources[srcInp].Item as float_array; float_array chanValues = mSources[srcOut].Item as float_array; List <float> outValues = new List <float>(); int numChanKeys = chanValues.Values.Length; numChanKeys /= (int)mSources[srcOut].technique_common.accessor.stride; Debug.Assert(numChanKeys == (int)chanTimes.count); //grab values for this channel //along the overall list of times for (int tidx = 0; tidx < times.Count; tidx++) { outValues.AddRange(LerpValue(times[tidx], chanTimes, chanValues, (int)mSources[srcOut].technique_common.accessor.stride)); } int slashIndex = chan.target.IndexOf("/"); string nodeID = chan.target.Substring(0, slashIndex); string nodeElement = chan.target.Substring(slashIndex + 1); //see if the element has an additional address string addr = null; int dotIdx = nodeElement.IndexOf('.'); if (dotIdx != -1) { addr = nodeElement.Substring(dotIdx + 1); nodeElement = nodeElement.Substring(0, dotIdx); } node targeted = AnimForm.LookUpNode(scenes, nodeID); int idx = AnimForm.GetNodeItemIndex(targeted, nodeElement); if (idx == -1) { continue; //bad anim stuffs? } if (targeted.ItemsElementName[idx] == ItemsChoiceType2.lookat) { Debug.Assert(false); //haven't dealt with this one yet } else if (targeted.ItemsElementName[idx] == ItemsChoiceType2.matrix) { //this doesn't really work yet List <Matrix> mats = AnimForm.GetMatrixListFromFloatList(outValues); for (int v = 0; v < mats.Count; v++) { mats[v].Decompose(out keys[v].mScale, out keys[v].mRotation, out keys[v].mPosition); } ret |= Animation.KeyPartsUsed.All; } else if (targeted.ItemsElementName[idx] == ItemsChoiceType2.rotate) { if (addr == null) { //I'm guessing these would be true quaternions //I don't really support that, as I store the //usual axis angle stuff I've seen in a quaternion //and then later fix it up to be a real quaternion Debug.Assert(false); } else if (addr == "ANGLE") { Debug.Assert(targeted.Items[idx] is rotate); rotate rot = targeted.Items[idx] as rotate; if (rot.Values[0] > 0.999f) { for (int v = 0; v < outValues.Count; v++) { float val = outValues[v]; keys[v].mRotation.X = val; if (!axisAngleKeys.Contains(keys[v])) { axisAngleKeys.Add(keys[v]); } } ret |= Animation.KeyPartsUsed.RotateX; } else if (rot.Values[1] > 0.999f) { for (int v = 0; v < outValues.Count; v++) { float val = outValues[v]; keys[v].mRotation.Y = val; if (!axisAngleKeys.Contains(keys[v])) { axisAngleKeys.Add(keys[v]); } } ret |= Animation.KeyPartsUsed.RotateY; } else if (rot.Values[2] > 0.999f) { for (int v = 0; v < outValues.Count; v++) { float val = outValues[v]; keys[v].mRotation.Z = val; if (!axisAngleKeys.Contains(keys[v])) { axisAngleKeys.Add(keys[v]); } } ret |= Animation.KeyPartsUsed.RotateZ; } else { Debug.Assert(false); //broken! } } } else if (targeted.ItemsElementName[idx] == ItemsChoiceType2.scale) { if (addr == null) { //I haven't seen this happen, but I'm guessing it //would be vector3s for (int v = 0; v < outValues.Count; v += 3) { keys[v / 3].mScale.X = outValues[v]; keys[v / 3].mScale.Y = outValues[v + 1]; keys[v / 3].mScale.Z = outValues[v + 2]; } ret |= Animation.KeyPartsUsed.ScaleX; ret |= Animation.KeyPartsUsed.ScaleY; ret |= Animation.KeyPartsUsed.ScaleZ; } else if (addr == "X") { for (int v = 0; v < outValues.Count; v++) { float val = outValues[v]; keys[v].mScale.X = val; } ret |= Animation.KeyPartsUsed.ScaleX; } else if (addr == "Y") { for (int v = 0; v < outValues.Count; v++) { float val = outValues[v]; keys[v].mScale.Y = val; } ret |= Animation.KeyPartsUsed.ScaleY; } else if (addr == "Z") { for (int v = 0; v < outValues.Count; v++) { float val = outValues[v]; keys[v].mScale.Z = val; } ret |= Animation.KeyPartsUsed.ScaleZ; } } else if (targeted.ItemsElementName[idx] == ItemsChoiceType2.skew) { Debug.Assert(false); //haven't dealt with this one yet } else if (targeted.ItemsElementName[idx] == ItemsChoiceType2.translate) { if (addr == null) { //the values are vector3s in this case for (int v = 0; v < outValues.Count; v += 3) { keys[v / 3].mPosition.X = outValues[v]; keys[v / 3].mPosition.Y = outValues[v + 1]; keys[v / 3].mPosition.Z = outValues[v + 2]; } ret |= Animation.KeyPartsUsed.TranslateX; ret |= Animation.KeyPartsUsed.TranslateY; ret |= Animation.KeyPartsUsed.TranslateZ; } else if (addr == "X") { for (int v = 0; v < outValues.Count; v++) { float val = outValues[v]; keys[v].mPosition.X = val; } ret |= Animation.KeyPartsUsed.TranslateX; } else if (addr == "Y") { for (int v = 0; v < outValues.Count; v++) { float val = outValues[v]; keys[v].mPosition.Y = val; } ret |= Animation.KeyPartsUsed.TranslateY; } else if (addr == "Z") { for (int v = 0; v < outValues.Count; v++) { float val = outValues[v]; keys[v].mPosition.Z = val; } ret |= Animation.KeyPartsUsed.TranslateZ; } } } return(ret); }
protected mesh CreatePalletMesh(PalletProperties palletProperties) { // build pallet object Pallet pallet = new Pallet(palletProperties); // build list of boxes List <Box> listBoxes = pallet.BuildListOfBoxes(); // build list of vertices / normals / UVs ulong vertexCount = 0, normalCount = 0, uvCount = 0, triangleCount = 0, boxCount = 0; string triangle_string = string.Empty; List <double> doubleArrayPosition = new List <double>(), doubleArrayNormal = new List <double>(), doubleArrayUV = new List <double>(); foreach (Box box in listBoxes) { foreach (Vector3D p in box.Points) { doubleArrayPosition.Add(p.X); doubleArrayPosition.Add(p.Y); doubleArrayPosition.Add(p.Z); ++vertexCount; } foreach (Vector3D n in box.Normals) { doubleArrayNormal.Add(n.X); doubleArrayNormal.Add(n.Y); doubleArrayNormal.Add(n.Z); ++normalCount; } foreach (Vector2D uv in box.UVs) { doubleArrayUV.Add(uv.X); doubleArrayUV.Add(uv.Y); ++uvCount; } foreach (TriangleIndices tr in box.Triangles) { triangle_string += tr.ConvertToString(boxCount); ++triangleCount; } ++boxCount; } mesh palletMesh = new mesh(); // position source source palletPositionSource = new source() { id = "pallet_position", name = "pallet_position" }; float_array farrayPosition = new float_array { id = "pallet_position_float_array", count = (ulong)doubleArrayPosition.Count, Values = doubleArrayPosition.ToArray() }; palletPositionSource.technique_common = new sourceTechnique_common() { accessor = new accessor() { stride = 3, count = vertexCount, source = "#pallet_position_float_array", param = new param[] { new param() { name = "X", type = "float" }, new param() { name = "Y", type = "float" }, new param() { name = "Z", type = "float" } } } }; palletPositionSource.Item = farrayPosition; // normal source source palletPositionNormal = new source() { id = "pallet_normal", name = "pallet_normal" }; float_array farrayNormal = new float_array { id = "pallet_normal_float_array", count = (ulong)doubleArrayNormal.Count, Values = doubleArrayNormal.ToArray() }; palletPositionNormal.technique_common = new sourceTechnique_common() { accessor = new accessor() { stride = 3, count = normalCount, source = "#pallet_normal_float_array", param = new param[] { new param() { name = "X", type = "float" }, new param() { name = "Y", type = "float" }, new param() { name = "Z", type = "float" } } } }; palletPositionNormal.Item = farrayNormal; // uv source source palletPositionUV = new source() { id = "pallet_UV", name = "pallet_UV" }; float_array farrayUV = new float_array { id = "pallet_UV_float_array", count = (ulong)doubleArrayUV.Count, Values = doubleArrayUV.ToArray() }; palletPositionUV.technique_common = new sourceTechnique_common() { accessor = new accessor() { stride = 2, count = vertexCount, source = "#pallet_UV_float_array", param = new param[] { new param() { name = "S", type = "float" }, new param() { name = "T", type = "float" } } } }; palletPositionUV.Item = farrayUV; // insert sources palletMesh.source = new source[] { palletPositionSource, palletPositionNormal, palletPositionUV }; // vertices InputLocal verticesInput = new InputLocal() { semantic = "POSITION", source = "#pallet_position" }; palletMesh.vertices = new vertices() { id = "pallet_vertex", input = new InputLocal[] { verticesInput } }; triangles trianglesPallet = new triangles() { material = "materialPallet", count = triangleCount }; trianglesPallet.input = new InputLocalOffset[] { new InputLocalOffset() { semantic = "VERTEX", source = "#pallet_vertex", offset = 0 } , new InputLocalOffset() { semantic = "NORMAL", source = "#pallet_normal", offset = 1 } , new InputLocalOffset() { semantic = "TEXCOORD", source = "#pallet_UV", offset = 2, set = 0, setSpecified = true } }; trianglesPallet.p = triangle_string; palletMesh.Items = new object[] { trianglesPallet }; return(palletMesh); }
public static void ExportIOModelAsDAE(string FileName, IOModel m) { COLLADA colladaFile = new COLLADA(); List <geometry> list_geometries = new List <geometry>(m.Meshes.Count); if (m.HasMeshes) { foreach (IOMesh iomesh in m.Meshes) { geometry g = new geometry(); g.name = iomesh.Name; g.id = iomesh.Name + $"_{m.Meshes.IndexOf(iomesh)}"; List <double> list_positions = new List <double>(); List <double> list_normals = new List <double>(); List <double> list_uvs = new List <double>(); List <double> list_colors = new List <double>(); foreach (IOVertex v in iomesh.Vertices) { list_positions.Add(v.Position.X); list_positions.Add(v.Position.Y); list_positions.Add(v.Position.Z); list_normals.Add(v.Normal.X); list_normals.Add(v.Normal.Y); list_normals.Add(v.Normal.Z); list_uvs.Add(v.UV0.X); list_uvs.Add(v.UV0.Y); } // Position source source_position = new source(); { float_array floats = new float_array(); floats.count = (ulong)list_positions.Count; floats.id = g.id + "_pos_arr"; floats.Values = list_positions.ToArray(); source_position = CreateSource(list_positions.Count, 3, floats.id, floats, new param[] { new param() { name = "X", type = "float" }, new param() { name = "Y", type = "float" }, new param() { name = "Z", type = "float" } }); } // Normal source source_normal = new source(); { float_array floats = new float_array(); floats.count = (ulong)list_normals.Count; floats.id = g.id + "_nrm_arr"; floats.Values = list_normals.ToArray(); source_normal = CreateSource(list_normals.Count, 3, floats.id, floats, new param[] { new param() { name = "X", type = "float" }, new param() { name = "Y", type = "float" }, new param() { name = "Z", type = "float" } }); } // UV0 source source_uv0 = new source(); { float_array floats = new float_array(); floats.count = (ulong)list_uvs.Count; floats.id = g.id + "_uv0_arr"; floats.Values = list_uvs.ToArray(); source_uv0 = CreateSource(list_uvs.Count, 2, floats.id, floats, new param[] { new param() { name = "S", type = "float" }, new param() { name = "T", type = "float" } }); } // vertices vertices vertices = new vertices(); vertices.id = g.id + "_verts"; vertices.input = new InputLocal[] { new InputLocal() { source = "#" + source_position.id, semantic = "POSITION" }, new InputLocal() { source = "#" + source_normal.id, semantic = "NORMAL" }, new InputLocal() { source = "#" + source_uv0.id, semantic = "TEXCOORD" } }; // triangles triangles triangles = new triangles(); triangles.count = (ulong)iomesh.Indices.Count; triangles.input = new InputLocalOffset[] { new InputLocalOffset() { offset = 0, semantic = "VERTEX", source = "#" + vertices.id } }; triangles.p = string.Join(" ", iomesh.Indices); // creating mesh mesh geomesh = new mesh(); geomesh.source = new source[] { source_position, source_normal, source_uv0 }; geomesh.Items = new object[] { triangles }; geomesh.vertices = vertices; g.Item = geomesh; list_geometries.Add(g); } } library_geometries lib_geometry = new library_geometries(); lib_geometry.geometry = list_geometries.ToArray(); // controllers List <controller> list_controller = new List <controller>(); if (m.HasMeshes && m.HasSkeleton) { // create lists List <source> skinSources = new List <source>(); List <string> boneNames = new List <string>(); List <double> InverseBinds = new List <double>(); foreach (RBone b in m.Skeleton.Bones) { boneNames.Add(b.Name); InverseBinds.AddRange(new double[] { b.InvWorldTransform.M11, b.InvWorldTransform.M21, b.InvWorldTransform.M31, b.InvWorldTransform.M41, b.InvWorldTransform.M12, b.InvWorldTransform.M22, b.InvWorldTransform.M32, b.InvWorldTransform.M42, b.InvWorldTransform.M13, b.InvWorldTransform.M23, b.InvWorldTransform.M33, b.InvWorldTransform.M43, b.InvWorldTransform.M14, b.InvWorldTransform.M24, b.InvWorldTransform.M34, b.InvWorldTransform.M44, }); } // setup controllers foreach (IOMesh iomesh in m.Meshes) { controller controller = new controller() { id = iomesh.Name + "_" + m.Meshes.IndexOf(iomesh) + "_controller" }; list_controller.Add(controller); // create source for weights List <double> weights = new List <double>(); List <int> bones = new List <int>(); List <int> boneCount = new List <int>(); StringBuilder build_v = new StringBuilder(); foreach (IOVertex v in iomesh.Vertices) { int bcount = 0; if (v.BoneWeights.X > 0) { if (!weights.Contains(v.BoneWeights.X)) { weights.Add(v.BoneWeights.X); } build_v.Append($"{(int)v.BoneIndices.X} {weights.IndexOf(v.BoneWeights.X)} "); bcount++; } if (v.BoneWeights.Y > 0) { if (!weights.Contains(v.BoneWeights.Y)) { weights.Add(v.BoneWeights.Y); } build_v.Append($"{(int)v.BoneIndices.Y} {weights.IndexOf(v.BoneWeights.Y)} "); bcount++; } if (v.BoneWeights.Z > 0) { if (!weights.Contains(v.BoneWeights.Z)) { weights.Add(v.BoneWeights.Z); } build_v.Append($"{(int)v.BoneIndices.Z} {weights.IndexOf(v.BoneWeights.Z)} "); bcount++; } if (v.BoneWeights.W > 0) { if (!weights.Contains(v.BoneWeights.W)) { weights.Add(v.BoneWeights.W); } build_v.Append($"{(int)v.BoneIndices.W} {weights.IndexOf(v.BoneWeights.W)} "); bcount++; } boneCount.Add(bcount); } // skin Name_array arr_name = new Name_array(); arr_name.count = (ulong)boneNames.Count; arr_name.id = controller.id + "joints"; arr_name.Values = boneNames.ToArray(); source source_skin = CreateSource(boneNames.Count, 1, arr_name.id, arr_name, new param[] { new param() { name = "JOINT", type = "name" } }); // bind float_array arr_bind = new float_array(); arr_bind.count = (ulong)InverseBinds.Count; arr_bind.id = controller.id + "binds"; arr_bind.Values = InverseBinds.ToArray(); source source_binds = CreateSource(InverseBinds.Count, 16, arr_bind.id, arr_bind, new param[] { new param() { name = "TRANSFORM", type = "float4x4" } }); // weight source source_weight = new source(); { float_array floats = new float_array(); floats.count = (ulong)weights.Count; floats.id = controller.id + "_weights"; floats.Values = weights.ToArray(); source_weight = CreateSource(weights.Count, 1, floats.id, floats, new param[] { new param() { name = "WEIGHT", type = "float" }, }); } skin skin = new skin(); skin.source1 = "#" + iomesh.Name + $"_{m.Meshes.IndexOf(iomesh)}"; skin.source = new source[] { source_skin, source_binds, source_weight }; skin.joints = new skinJoints() { input = new InputLocal[] { new InputLocal() { semantic = "JOINT", source = "#" + source_skin.id }, new InputLocal() { semantic = "INV_BIND_MATRIX", source = "#" + source_binds.id } } }; //skin weights skin.vertex_weights = new skinVertex_weights(); skin.vertex_weights.count = (ulong)iomesh.Vertices.Count; skin.vertex_weights.input = new InputLocalOffset[] { new InputLocalOffset() { semantic = "JOINT", source = "#" + source_skin.id, offset = 0 }, new InputLocalOffset() { semantic = "WEIGHT", source = "#" + source_weight.id, offset = 1 } }; skin.vertex_weights.vcount = string.Join(" ", boneCount); skin.vertex_weights.v = build_v.ToString(); controller.Item = skin; } } library_controllers lib_controllers = new library_controllers(); lib_controllers.controller = list_controller.ToArray(); // scene nodes List <node> scene_nodes = new List <node>(); int visual_index = 0; if (m.HasSkeleton) { Dictionary <RBone, node> boneToNode = new Dictionary <RBone, node>(); foreach (RBone b in m.Skeleton.Bones) { // create bone node node node = new node(); node.name = b.Name; node.id = "bone" + visual_index++; node.sid = b.Name; node.type = NodeType.JOINT; // add transform matrix mat = new matrix() { Values = new double[] { b.Transform.M11, b.Transform.M21, b.Transform.M31, b.Transform.M41, b.Transform.M12, b.Transform.M22, b.Transform.M32, b.Transform.M42, b.Transform.M13, b.Transform.M23, b.Transform.M33, b.Transform.M43, b.Transform.M14, b.Transform.M24, b.Transform.M34, b.Transform.M44, } }; node.ItemsElementName = new ItemsChoiceType2[] { ItemsChoiceType2.matrix }; node.Items = new object[] { mat }; // deal with parenting boneToNode.Add(b, node); if (b.ParentID == -1) { scene_nodes.Add(node); } else { if (boneToNode[m.Skeleton.Bones[b.ParentID]].node1 == null) { boneToNode[m.Skeleton.Bones[b.ParentID]].node1 = new node[0]; } node[] parentnode = boneToNode[m.Skeleton.Bones[b.ParentID]].node1; Array.Resize <node>(ref parentnode, parentnode.Length + 1); parentnode[parentnode.Length - 1] = node; boneToNode[m.Skeleton.Bones[b.ParentID]].node1 = parentnode; } } } if (m.HasMeshes) { foreach (IOMesh iomesh in m.Meshes) { node node = new node() { id = "mesh" + visual_index++, name = iomesh.Name, type = NodeType.NODE }; if (m.HasSkeleton) { instance_controller controller = new instance_controller() { url = iomesh.Name + "_" + m.Meshes.IndexOf(iomesh) + "_controller" }; controller.skeleton = new string[] { "#bone0" }; node.instance_controller = new instance_controller[] { controller }; } scene_nodes.Add(node); } } // visual scene root library_visual_scenes scenes = new library_visual_scenes(); scenes.visual_scene = new visual_scene[] { new visual_scene() { id = "visualscene0", name = "rdmscene" } }; scenes.visual_scene[0].node = scene_nodes.ToArray(); // scene COLLADAScene scene = new COLLADAScene(); scene.instance_visual_scene = new InstanceWithExtra() { url = "#visualscene0" }; // putting it all together colladaFile.Items = new object[] { lib_geometry, lib_controllers, scenes }; colladaFile.scene = scene; colladaFile.Save(FileName); }
public static void AddSkinnedModelWithAnimations(ref Skin SkinChunk, ref SkeletonCTTR SkeletonChunk, ref Shader[] ShaderChunks)//, ref Animation[] AnimChunks) { List <uint> IndexList = new List <uint>(); cachedGeoms.geometry = new geometry[SkinChunk.NumPrimGroups]; for (int primgroups = 0; primgroups < SkinChunk.NumPrimGroups; primgroups++) { cachedGeoms.geometry[primgroups] = new geometry(); cachedGeoms.geometry[primgroups].id = "geometry" + primgroups; cachedGeoms.geometry[primgroups].name = "geometry" + primgroups; mesh newMesh = new Collada141.mesh(); newMesh.vertices = new vertices(); newMesh.vertices.id = "geometry" + primgroups + "-vertices"; newMesh.vertices.name = "geometry" + primgroups + "-vertices"; newMesh.vertices.input = new InputLocal[1]; newMesh.vertices.input[0] = new InputLocal(); newMesh.vertices.input[0].semantic = "POSITION"; newMesh.vertices.input[0].source = "#geometry" + primgroups + "-positions"; //newMesh.vertices.input[1] = new InputLocal(); //newMesh.vertices.input[1].semantic = "TEXCOORD"; //newMesh.vertices.input[1].source = "#geometry" + primgroups + "-texcoords"; //newMesh.vertices.input[2].semantic = "COLOR"; //newMesh.vertices.input[2].source = "#geometry0-colors"; newMesh.source = new source[3]; newMesh.source[0] = new source(); newMesh.source[0].id = "geometry" + primgroups + "-positions"; float_array geom_positions = new float_array(); geom_positions.id = "geometry" + primgroups + "-positions-array"; PositionList posList = SkinChunk.GetChildren <PrimitiveGroupCTTR>()[primgroups].GetChildren <PositionList>()[0]; geom_positions.count = (ulong)posList.Positions.Length * 3; geom_positions.Values = new double[geom_positions.count]; for (ulong i = 0; i < geom_positions.count / 3; i++) { if (i % 3 == 0) { geom_positions.Values[i] = posList.Positions[i / 3].X; } else if (i % 3 == 1) { geom_positions.Values[i] = posList.Positions[i / 3].Y; } else { geom_positions.Values[i] = posList.Positions[i / 3].Z; } } newMesh.source[0].Item = geom_positions; newMesh.source[0].technique_common = new sourceTechnique_common(); newMesh.source[0].technique_common.accessor = new accessor(); newMesh.source[0].technique_common.accessor.source = "#" + geom_positions.id; newMesh.source[0].technique_common.accessor.count = geom_positions.count / 3; newMesh.source[0].technique_common.accessor.stride = 3; newMesh.source[0].technique_common.accessor.param = new param[3] { new param(), new param(), new param(), }; newMesh.source[0].technique_common.accessor.param[0].name = "X"; newMesh.source[0].technique_common.accessor.param[0].type = "float"; newMesh.source[0].technique_common.accessor.param[1].name = "Y"; newMesh.source[0].technique_common.accessor.param[1].type = "float"; newMesh.source[0].technique_common.accessor.param[2].name = "Z"; newMesh.source[0].technique_common.accessor.param[2].type = "float"; newMesh.source[1] = new source(); newMesh.source[1].id = "geometry" + primgroups + "-mesh-normals"; float_array geom_normals = new float_array(); geom_normals.id = "geometry" + primgroups + "-mesh-map-array"; NormalList normals = SkinChunk.GetChildren <PrimitiveGroupCTTR>()[primgroups].GetChildren <NormalList>()[0]; geom_normals.count = (ulong)normals.Normals.Length * 3; geom_normals.Values = new double[geom_normals.count]; for (ulong i = 0; i < geom_normals.count; i++) { if (i % 3 == 0) { geom_normals.Values[i] = normals.Normals[i / 3].X; } else if (i % 3 == 1) { geom_normals.Values[i] = normals.Normals[i / 3].Y; } else { geom_normals.Values[i] = normals.Normals[i / 3].Z; } } newMesh.source[1].Item = geom_normals; newMesh.source[1].technique_common = new sourceTechnique_common(); newMesh.source[1].technique_common.accessor = new accessor(); newMesh.source[1].technique_common.accessor.source = "#" + geom_normals.id; newMesh.source[1].technique_common.accessor.count = geom_positions.count / 3; newMesh.source[1].technique_common.accessor.stride = 3; newMesh.source[1].technique_common.accessor.param = new param[3] { new param(), new param(), new param(), }; newMesh.source[1].technique_common.accessor.param[0].name = "X"; newMesh.source[1].technique_common.accessor.param[0].type = "float"; newMesh.source[1].technique_common.accessor.param[1].name = "Y"; newMesh.source[1].technique_common.accessor.param[1].type = "float"; newMesh.source[1].technique_common.accessor.param[2].name = "Z"; newMesh.source[1].technique_common.accessor.param[2].type = "float"; newMesh.source[2] = new source(); newMesh.source[2].id = "geometry" + primgroups + "-mesh-map-0"; float_array geom_texcoords = new float_array(); geom_texcoords.id = "geometry" + primgroups + "-mesh-map-array"; UVList UV = SkinChunk.GetChildren <PrimitiveGroupCTTR>()[primgroups].GetChildren <UVList>()[0]; geom_texcoords.count = (ulong)UV.UVs.Length * 2; geom_texcoords.Values = new double[geom_texcoords.count]; for (ulong i = 0; i < geom_texcoords.count; i++) { ulong pos = i / 2; geom_texcoords.Values[i] = UV.UVs[pos].X; i++; geom_texcoords.Values[i] = UV.UVs[pos].Y; } newMesh.source[2].Item = geom_texcoords; newMesh.source[2].technique_common = new sourceTechnique_common(); newMesh.source[2].technique_common.accessor = new accessor(); newMesh.source[2].technique_common.accessor.source = "#" + geom_texcoords.id; newMesh.source[2].technique_common.accessor.count = geom_texcoords.count / 2; newMesh.source[2].technique_common.accessor.stride = 2; newMesh.source[2].technique_common.accessor.param = new param[2] { new param(), new param(), }; newMesh.source[2].technique_common.accessor.param[0].name = "S"; newMesh.source[2].technique_common.accessor.param[0].type = "float"; newMesh.source[2].technique_common.accessor.param[1].name = "T"; newMesh.source[2].technique_common.accessor.param[1].type = "float"; /* * newMesh.source[3].id = "geometry" + primgroups + "-colors-Col"; * float_array geom_colors = new float_array(); * geom_colors.id = "geometry" + primgroups + "-colors-Col-array"; * ColourList colors = SkinChunk.GetChildren<PrimitiveGroupCTTR>()[primgroups].GetChildren<ColourList>()[0]; * geom_colors.count = (ulong)colors.Colours.Length * 3; * geom_colors.Values = new double[geom_colors.count]; * for (ulong i = 0; i < geom_colors.count / 3; i++) * { * if (i % 3 == 0) * { * geom_colors.Values[i] = colors.Colours[i]; * } * else if (i % 3 == 1) * { * geom_colors.Values[i] = colors.Colours[i / 3]; * } * else * { * geom_colors.Values[i] = colors.Colours[i / 3]; * } * } * * newMesh.source[3].Item = geom_colors; * newMesh.source[3].technique_common = new sourceTechnique_common(); * newMesh.source[3].technique_common.accessor = new accessor(); * newMesh.source[3].technique_common.accessor.source = geom_colors.id; * newMesh.source[3].technique_common.accessor.count = geom_colors.count / 3; * newMesh.source[3].technique_common.accessor.stride = 3; * newMesh.source[3].technique_common.accessor.param = new param[3]; * newMesh.source[3].technique_common.accessor.param[0].name = "R"; * newMesh.source[3].technique_common.accessor.param[0].type = "float"; * newMesh.source[3].technique_common.accessor.param[1].name = "G"; * newMesh.source[3].technique_common.accessor.param[1].type = "float"; * newMesh.source[3].technique_common.accessor.param[2].name = "B"; * newMesh.source[3].technique_common.accessor.param[2].type = "float"; */ polylist meshTriangles = new polylist(); meshTriangles.material = ""; meshTriangles.count = (ulong)SkinChunk.GetChildren <PrimitiveGroupCTTR>()[primgroups].GetChildren <IndexList>()[0].Indices.Length / 4; meshTriangles.input = new InputLocalOffset[3]; meshTriangles.input[0] = new InputLocalOffset(); meshTriangles.input[0].semantic = "VERTEX"; meshTriangles.input[0].source = "#" + newMesh.vertices.id; meshTriangles.input[0].offset = 0; meshTriangles.input[1] = new InputLocalOffset(); meshTriangles.input[1].semantic = "NORMAL"; meshTriangles.input[1].source = "#" + "geometry" + primgroups + "-mesh-normals"; meshTriangles.input[1].offset = 1; meshTriangles.input[2] = new InputLocalOffset(); meshTriangles.input[2].semantic = "TEXCOORD"; meshTriangles.input[2].source = "#" + "geometry" + primgroups + "-mesh-map-0"; meshTriangles.input[2].offset = 2; meshTriangles.input[2].set = 0; string packed_primitives = ""; for (int i = 0; i < SkinChunk.GetChildren <PrimitiveGroupCTTR>()[primgroups].GetChildren <IndexList>()[0].Indices.Length; i++) { packed_primitives += SkinChunk.GetChildren <PrimitiveGroupCTTR>()[primgroups].GetChildren <IndexList>()[0].Indices[i]; packed_primitives += " "; } string packed_vcount = ""; for (int i = 0; i < SkinChunk.GetChildren <PrimitiveGroupCTTR>()[primgroups].GetChildren <IndexList>()[0].Indices.Length / 3; i++) { packed_vcount += "3 "; } meshTriangles.vcount = packed_vcount; meshTriangles.p = packed_primitives; newMesh.Items = new object[1]; newMesh.Items[0] = meshTriangles; cachedGeoms.geometry[primgroups].Item = newMesh; for (int i = 0; i < SkinChunk.GetChildren <PrimitiveGroupCTTR>()[primgroups].GetChildren <IndexList>()[0].Indices.Length; i++) { IndexList.Add(SkinChunk.GetChildren <PrimitiveGroupCTTR>()[primgroups].GetChildren <IndexList>()[0].Indices[i]); } } cachedMats.material = new material[ShaderChunks.Length]; List <string> shader_tex = new List <string>(); for (int mat = 0; mat < ShaderChunks.Length; mat++) { cachedMats.material[mat] = new material(); cachedMats.material[mat].id = "mat" + ShaderChunks[mat].Name; cachedMats.material[mat].name = ShaderChunks[mat].Name; cachedMats.material[mat].instance_effect = new instance_effect(); cachedMats.material[mat].instance_effect.url = "#" + ShaderChunks[mat].Name; //effect name if (ShaderChunks[mat].GetChildren <ShaderTextureParam>().Length > 0) { if (!shader_tex.Contains(ShaderChunks[mat].GetChildren <ShaderTextureParam>()[0].Value)) { shader_tex.Add(ShaderChunks[mat].GetChildren <ShaderTextureParam>()[0].Value); } } } cachedImages.image = new image[shader_tex.Count]; for (int i = 0; i < cachedImages.image.Length; i++) { cachedImages.image[i] = new image(); cachedImages.image[i].id = "image" + shader_tex[i]; //fx_surface_init_from_common init_from = new fx_surface_init_from_common(); //init_from.Value = shader_tex[i]; //cachedImages.image[i].Item = init_from; } cachedEffects.effect = new effect[ShaderChunks.Length]; for (int mat = 0; mat < ShaderChunks.Length; mat++) { cachedEffects.effect[mat] = new effect(); cachedEffects.effect[mat].id = ShaderChunks[mat].Name; cachedEffects.effect[mat].name = ShaderChunks[mat].Name; cachedEffects.effect[mat].newparam = new fx_newparam_common[2]; cachedEffects.effect[mat].newparam[0] = new fx_newparam_common(); cachedEffects.effect[mat].newparam[0].sid = "Image-surface"; cachedEffects.effect[mat].newparam[0].surface = new fx_surface_common(); cachedEffects.effect[mat].newparam[0].surface.type = fx_surface_type_enum.Item2D; cachedEffects.effect[mat].newparam[0].surface.init_from = new fx_surface_init_from_common[1]; cachedEffects.effect[mat].newparam[0].surface.init_from[0] = new fx_surface_init_from_common(); cachedEffects.effect[mat].newparam[0].surface.init_from[0].Value = ShaderChunks[mat].Name; cachedEffects.effect[mat].newparam[0].surface.format = "A8R8G8B8"; cachedEffects.effect[mat].newparam[1] = new fx_newparam_common(); cachedEffects.effect[mat].newparam[1].sid = "Image-sampler"; cachedEffects.effect[mat].newparam[1].sampler2D = new fx_sampler2D_common(); cachedEffects.effect[mat].newparam[1].sampler2D.source = "Image-surface"; cachedEffects.effect[mat].newparam[1].sampler2D.wrap_s = fx_sampler_wrap_common.CLAMP; cachedEffects.effect[mat].newparam[1].sampler2D.wrap_t = fx_sampler_wrap_common.CLAMP; cachedEffects.effect[mat].newparam[1].sampler2D.minfilter = fx_sampler_filter_common.NEAREST; cachedEffects.effect[mat].newparam[1].sampler2D.magfilter = fx_sampler_filter_common.NEAREST; cachedEffects.effect[mat].newparam[1].sampler2D.mipfilter = fx_sampler_filter_common.NEAREST; cachedEffects.effect[mat].Items = new effectFx_profile_abstractProfile_COMMON[1]; cachedEffects.effect[mat].Items[0] = new effectFx_profile_abstractProfile_COMMON(); cachedEffects.effect[mat].Items[0].technique = new effectFx_profile_abstractProfile_COMMONTechnique(); cachedEffects.effect[mat].Items[0].technique.sid = "common"; effectFx_profile_abstractProfile_COMMONTechniquePhong common_phong = new effectFx_profile_abstractProfile_COMMONTechniquePhong(); common_color_or_texture_typeTexture textureType = new common_color_or_texture_typeTexture(); textureType.texture = "Image-sampler"; textureType.texcoord = "tc"; common_phong.diffuse = new common_color_or_texture_type(); common_phong.diffuse.Item = textureType; common_phong.transparent = new common_transparent_type(); common_phong.transparent.Item = textureType; cachedEffects.effect[mat].Items[0].technique.Item = common_phong; } cachedControllers.controller = new controller[SkinChunk.NumPrimGroups]; for (int a = 0; a < SkinChunk.NumPrimGroups; a++) { cachedControllers.controller[a] = new controller(); cachedControllers.controller[a].id = SkinChunk.Name + a; cachedControllers.controller[a].name = SkinChunk.Name + a; skin ControllerSkin = new skin(); ControllerSkin.source1 = "#geometry" + a; ControllerSkin.source = new source[3]; ControllerSkin.source[0] = new source(); ControllerSkin.source[0].id = "controller" + a + "-joints"; Name_array Joints_Names = new Name_array(); Joints_Names.id = "controller" + a + "-joints-array"; Joints_Names.count = (ulong)SkeletonChunk.GetChildren <SkeletonJointCTTR>().Length; Joints_Names.Values = new string[Joints_Names.count]; for (ulong i = 0; i < Joints_Names.count; i++) { Joints_Names.Values[i] = SkeletonChunk.GetChildren <SkeletonJointCTTR>()[i].Name; } ControllerSkin.source[0].Item = Joints_Names; ControllerSkin.source[0].technique_common = new sourceTechnique_common(); ControllerSkin.source[0].technique_common.accessor = new accessor(); ControllerSkin.source[0].technique_common.accessor.source = "#" + Joints_Names.id; ControllerSkin.source[0].technique_common.accessor.count = Joints_Names.count; ControllerSkin.source[0].technique_common.accessor.param = new param[1] { new param() }; ControllerSkin.source[0].technique_common.accessor.param[0].name = "JOINT"; ControllerSkin.source[0].technique_common.accessor.param[0].type = "Name"; ControllerSkin.source[1] = new source(); ControllerSkin.source[1].id = "controller" + a + "-bind_poses"; float_array Bind_Poses = new float_array(); Bind_Poses.id = "controller" + a + "-bind_poses-array"; Bind_Poses.count = (ulong)SkeletonChunk.GetChildren <SkeletonJointCTTR>().Length * 16; Bind_Poses.Values = new double[Bind_Poses.count]; int bind_pose_pos = 0; for (ulong i = 0; i < Joints_Names.count; i++) { Bind_Poses.Values[bind_pose_pos] = SkeletonChunk.GetChildren <SkeletonJointCTTR>()[i].RestPose.M11; bind_pose_pos++; Bind_Poses.Values[bind_pose_pos] = SkeletonChunk.GetChildren <SkeletonJointCTTR>()[i].RestPose.M12; bind_pose_pos++; Bind_Poses.Values[bind_pose_pos] = SkeletonChunk.GetChildren <SkeletonJointCTTR>()[i].RestPose.M13; bind_pose_pos++; Bind_Poses.Values[bind_pose_pos] = SkeletonChunk.GetChildren <SkeletonJointCTTR>()[i].RestPose.M14; bind_pose_pos++; Bind_Poses.Values[bind_pose_pos] = SkeletonChunk.GetChildren <SkeletonJointCTTR>()[i].RestPose.M21; bind_pose_pos++; Bind_Poses.Values[bind_pose_pos] = SkeletonChunk.GetChildren <SkeletonJointCTTR>()[i].RestPose.M22; bind_pose_pos++; Bind_Poses.Values[bind_pose_pos] = SkeletonChunk.GetChildren <SkeletonJointCTTR>()[i].RestPose.M23; bind_pose_pos++; Bind_Poses.Values[bind_pose_pos] = SkeletonChunk.GetChildren <SkeletonJointCTTR>()[i].RestPose.M24; bind_pose_pos++; Bind_Poses.Values[bind_pose_pos] = SkeletonChunk.GetChildren <SkeletonJointCTTR>()[i].RestPose.M31; bind_pose_pos++; Bind_Poses.Values[bind_pose_pos] = SkeletonChunk.GetChildren <SkeletonJointCTTR>()[i].RestPose.M32; bind_pose_pos++; Bind_Poses.Values[bind_pose_pos] = SkeletonChunk.GetChildren <SkeletonJointCTTR>()[i].RestPose.M33; bind_pose_pos++; Bind_Poses.Values[bind_pose_pos] = SkeletonChunk.GetChildren <SkeletonJointCTTR>()[i].RestPose.M34; bind_pose_pos++; Bind_Poses.Values[bind_pose_pos] = SkeletonChunk.GetChildren <SkeletonJointCTTR>()[i].RestPose.M41; bind_pose_pos++; Bind_Poses.Values[bind_pose_pos] = SkeletonChunk.GetChildren <SkeletonJointCTTR>()[i].RestPose.M42; bind_pose_pos++; Bind_Poses.Values[bind_pose_pos] = SkeletonChunk.GetChildren <SkeletonJointCTTR>()[i].RestPose.M43; bind_pose_pos++; Bind_Poses.Values[bind_pose_pos] = SkeletonChunk.GetChildren <SkeletonJointCTTR>()[i].RestPose.M44; bind_pose_pos++; } ControllerSkin.source[1].Item = Bind_Poses; ControllerSkin.source[1].technique_common = new sourceTechnique_common(); ControllerSkin.source[1].technique_common.accessor = new accessor(); ControllerSkin.source[1].technique_common.accessor.source = "#" + Bind_Poses.id; ControllerSkin.source[1].technique_common.accessor.count = Bind_Poses.count; ControllerSkin.source[1].technique_common.accessor.param = new param[1] { new param() }; ControllerSkin.source[1].technique_common.accessor.param[0].name = "TRANSFORM"; ControllerSkin.source[1].technique_common.accessor.param[0].type = "float4x4"; ControllerSkin.source[2] = new source(); ControllerSkin.source[2].id = "controller" + a + "-weights"; float_array Weights_Array = new float_array(); Weights_Array.id = "controller" + a + "-weights-array"; Weights_Array.count = Joints_Names.count; Weights_Array.Values = new double[Joints_Names.count]; for (int i = 0; i < Weights_Array.Values.Length; i++) { Weights_Array.Values[i] = 1; } ControllerSkin.source[2].Item = Weights_Array; ControllerSkin.source[2].technique_common = new sourceTechnique_common(); ControllerSkin.source[2].technique_common.accessor = new accessor(); ControllerSkin.source[2].technique_common.accessor.source = "#" + Weights_Array.id; ControllerSkin.source[2].technique_common.accessor.count = Weights_Array.count; ControllerSkin.source[2].technique_common.accessor.param = new param[1] { new param() }; ControllerSkin.source[2].technique_common.accessor.param[0].name = "WEIGHT"; ControllerSkin.source[2].technique_common.accessor.param[0].type = "float"; ControllerSkin.joints = new skinJoints(); ControllerSkin.joints.input = new InputLocal[2] { new InputLocal(), new InputLocal() }; ControllerSkin.joints.input[0].semantic = "JOINT"; ControllerSkin.joints.input[0].source = "#" + ControllerSkin.source[0].id; ControllerSkin.joints.input[1].semantic = "INV_BIND_MATRIX"; ControllerSkin.joints.input[1].source = "#" + ControllerSkin.source[1].id; ControllerSkin.vertex_weights = new skinVertex_weights(); ControllerSkin.vertex_weights.count = (ulong)IndexList.Count; ControllerSkin.vertex_weights.input = new InputLocalOffset[2] { new InputLocalOffset(), new InputLocalOffset() }; ControllerSkin.vertex_weights.input[0].semantic = "JOINT"; ControllerSkin.vertex_weights.input[0].source = "#" + ControllerSkin.source[0].id; ControllerSkin.vertex_weights.input[0].offset = 0; ControllerSkin.vertex_weights.input[1].semantic = "WEIGHT"; ControllerSkin.vertex_weights.input[1].source = "#" + ControllerSkin.source[2].id; ControllerSkin.vertex_weights.input[1].offset = 1; string vertex_vcount = ""; for (int i = 0; i < IndexList.Count; i++) { vertex_vcount += "1 "; } ControllerSkin.vertex_weights.vcount = vertex_vcount; string index_list_str = ""; for (int i = 0; i < IndexList.Count; i++) { index_list_str += IndexList[i] + " "; } ControllerSkin.vertex_weights.v = index_list_str; cachedControllers.controller[a].Item = ControllerSkin; } cachedVscenes.visual_scene = new visual_scene[1] { new visual_scene() }; cachedVscenes.visual_scene[0].id = "Scene0"; cachedVscenes.visual_scene[0].name = "Scene0"; cachedVscenes.visual_scene[0].node = new node[SkinChunk.NumPrimGroups + 1]; cachedVscenes.visual_scene[0].node[0] = new node(); //cachedVscenes.visual_scene[0].node[0].Items = new object[1]; //cachedVscenes.visual_scene[0].node[0].Items[0] = new matrix(); for (int i = 0; i < SkeletonChunk.Children.Count; i++) { SkeletonJointCTTR joint = (SkeletonJointCTTR)SkeletonChunk.Children[i]; if (joint.SkeletonParent == 0) { //cachedVscenes.visual_scene[0].node[0].node1 = new node[10]; } } cachedVscenes.visual_scene[0].node[0].id = SkeletonChunk.Name; cachedVscenes.visual_scene[0].node[0].type = NodeType.JOINT; //todo: joints node tree // SkeletonParent - 0 means root, the rest is chunk child index // SkeletonJointCTTR.BindPose matrix as transform matrix? for (int i = 1; i < SkinChunk.NumPrimGroups + 1; i++) { cachedVscenes.visual_scene[0].node[i] = new node(); cachedVscenes.visual_scene[0].node[i].id = "node" + i; cachedVscenes.visual_scene[0].node[i].name = "polygon" + i; cachedVscenes.visual_scene[0].node[i].type = NodeType.NODE; cachedVscenes.visual_scene[0].node[i].instance_controller = new instance_controller[1] { new instance_controller() }; cachedVscenes.visual_scene[0].node[i].instance_controller[0].url = "#" + cachedControllers.controller[i - 1].id; cachedVscenes.visual_scene[0].node[i].instance_controller[0].skeleton = new string[1] { "#" + cachedVscenes.visual_scene[0].node[0].id }; cachedVscenes.visual_scene[0].node[i].instance_controller[0].bind_material = new bind_material(); cachedVscenes.visual_scene[0].node[i].instance_controller[0].bind_material.technique_common = new instance_material[1] { new instance_material() }; cachedVscenes.visual_scene[0].node[i].instance_controller[0].bind_material.technique_common[0].symbol = "#" + cachedMats.material[0].id; cachedVscenes.visual_scene[0].node[i].instance_controller[0].bind_material.technique_common[0].target = "#" + cachedMats.material[0].id; cachedVscenes.visual_scene[0].node[i].instance_controller[0].bind_material.technique_common[0].bind_vertex_input = new instance_materialBind_vertex_input[1] { new instance_materialBind_vertex_input() }; cachedVscenes.visual_scene[0].node[i].instance_controller[0].bind_material.technique_common[0].bind_vertex_input[0].semantic = "tc"; cachedVscenes.visual_scene[0].node[i].instance_controller[0].bind_material.technique_common[0].bind_vertex_input[0].input_semantic = "TEXCOORD"; } //not working: // - vertex weights error out // - mesh comes out wrong //animclips //anims }
// return mesh id private string CreateMesh(Mesh mesh) { string id = ""; if (meshLookup.TryGetValue(mesh, out id)) { return(id); } var geometry = new geometry(); geometries.Add(geometry); id = CreateId(); geometry.id = id; var m = new mesh(); geometry.Item = m; m.source = new source[] { new source(), // position new source(), // normal new source(), // uvs }; m.source[0].id = CreateId(); var fa = new float_array(); fa.id = CreateId(); fa.Values = ToDoubleArray(mesh.vertices); fa.count = (ulong)fa.Values.Length; m.source[0].Item = fa; m.source[0].technique_common = new sourceTechnique_common(); m.source[0].technique_common.accessor = new accessor(); m.source[0].technique_common.accessor.count = fa.count / 3; m.source[0].technique_common.accessor.source = "#" + fa.id; m.source[0].technique_common.accessor.stride = 3; m.source[0].technique_common.accessor.param = new[] { new param(), new param(), new param() }; m.source[0].technique_common.accessor.param[0].name = "X"; m.source[0].technique_common.accessor.param[0].type = "float"; m.source[0].technique_common.accessor.param[1].name = "Y"; m.source[0].technique_common.accessor.param[1].type = "float"; m.source[0].technique_common.accessor.param[2].name = "Z"; m.source[0].technique_common.accessor.param[2].type = "float"; m.source[1].id = CreateId(); fa = new float_array(); fa.id = CreateId(); fa.Values = ToDoubleArray(mesh.normals); fa.count = (ulong)fa.Values.Length; m.source[1].Item = fa; m.source[1].technique_common = new sourceTechnique_common(); m.source[1].technique_common.accessor = new accessor(); m.source[1].technique_common.accessor.count = fa.count / 3; m.source[1].technique_common.accessor.source = "#" + fa.id; m.source[1].technique_common.accessor.stride = 3; m.source[1].technique_common.accessor.param = new[] { new param(), new param(), new param() }; m.source[1].technique_common.accessor.param[0].name = "X"; m.source[1].technique_common.accessor.param[0].type = "float"; m.source[1].technique_common.accessor.param[1].name = "Y"; m.source[1].technique_common.accessor.param[1].type = "float"; m.source[1].technique_common.accessor.param[2].name = "Z"; m.source[1].technique_common.accessor.param[2].type = "float"; m.source[2].id = CreateId(); fa = new float_array(); fa.id = CreateId(); fa.Values = ToDoubleArray(mesh.uv); fa.count = (ulong)fa.Values.Length; m.source[2].Item = fa; m.source[2].technique_common = new sourceTechnique_common(); m.source[2].technique_common.accessor = new accessor(); m.source[2].technique_common.accessor.count = fa.count / 2; m.source[2].technique_common.accessor.source = "#" + fa.id; m.source[2].technique_common.accessor.stride = 2; m.source[2].technique_common.accessor.param = new[] { new param(), new param() }; m.source[2].technique_common.accessor.param[0].name = "X"; m.source[2].technique_common.accessor.param[0].type = "float"; m.source[2].technique_common.accessor.param[1].name = "Y"; m.source[2].technique_common.accessor.param[1].type = "float"; m.vertices = new vertices(); m.vertices.id = CreateId(); m.vertices.input = new InputLocal[] { new InputLocal(), // position new InputLocal(), // normal new InputLocal() // uvs }; m.vertices.input[0].semantic = "POSITION"; m.vertices.input[0].source = "#" + m.source[0].id; m.vertices.input[1].semantic = "NORMAL"; m.vertices.input[1].source = "#" + m.source[1].id; m.vertices.input[2].semantic = "TEXCOORD"; m.vertices.input[2].source = "#" + m.source[2].id; var triangles = new List <int>(); var stringWriter = new StringWriter(); for (int i = 0; i < mesh.subMeshCount; i++) { var t = mesh.GetTriangles(i); triangles.AddRange(t); for (int j = 0; j < t.Length; j = j + 3) { stringWriter.Write("{0} ", t[j]); stringWriter.Write("{0} ", t[j + 1]); stringWriter.Write("{0} ", t[j + 2]); } } var tris = new triangles(); tris.count = (ulong)(triangles.Count / 3); tris.material = defaultMaterialName; tris.input = new InputLocalOffset[] { new InputLocalOffset(), //new InputLocalOffset(), //new InputLocalOffset() }; tris.input[0].offset = 0; tris.input[0].semantic = "VERTEX"; tris.input[0].source = "#" + m.vertices.id; // <input semantic="TEXCOORD" source="#Cube-mesh-map-0" offset="2" set="0"/> /*tris.input[1].offset = 1; * tris.input[1].semantic = "NORMAL"; * tris.input[1].source= "#"+m.source[1].id; * * tris.input[2].offset = 2; * tris.input[2].semantic = "TEXCOORD"; * tris.input[2].source= "#"+m.source[2].id; * tris.input[2].set = 0; * tris.input[2].setSpecified = true;*/ tris.p = stringWriter.ToString(); m.Items = new object[] { tris }; meshLookup[mesh] = id; return(id); }