/// <summary> /// Build an object once at a time, to be reiterated until false is returned. /// </summary> /// <param name="parentObj">Game object to which the new objects will be attached</param> /// <param name="mats">Materials from the previously loaded library</param> /// <returns>Return true until no more objects can be added, then false.</returns> protected bool BuildNextObject(GameObject parentObj, Dictionary <string, Material> mats) { // if all the objects were built stop here if (buildStatus.objCount >= currDataSet.objectList.Count) { return(false); } // get the next object in the list DataSet.ObjectData objData = currDataSet.objectList[buildStatus.objCount]; if (buildStatus.newObject) { if (buildStatus.objCount == 0 && objData.name == "default") { buildStatus.currObjGameObject = parentObj; } else { buildStatus.currObjGameObject = new GameObject(); buildStatus.currObjGameObject.transform.parent = parentObj.transform; buildStatus.currObjGameObject.name = objData.name; // restore the scale if the parent was rescaled buildStatus.currObjGameObject.transform.localScale = Vector3.one; } buildStatus.subObjParent = buildStatus.currObjGameObject; //if (od.Name != "default") go.name = od.Name; //Debug.Log("Object: " + objData.name); buildStatus.newObject = false; buildStatus.subObjCount = 0; buildStatus.idxCount = 0; buildStatus.grpIdx = 0; buildStatus.grpFaceIdx = 0; buildStatus.meshPartIdx = 0; buildStatus.totFaceIdxCount = 0; buildStatus.numGroups = Mathf.Max(1, objData.faceGroups.Count); } bool splitLargeMeshes = true; #if UNITY_2017_3_OR_NEWER // GPU support for 32 bit indices is not guaranteed on all platforms; // for example Android devices with Mali-400 GPU do not support them. // This check is performed in Using32bitIndices(). // If nothing is rendered on your device problably Using32bitIndices() must be updated. if (Using32bitIndices()) { splitLargeMeshes = false; } #endif bool splitGrp = false; DataSet.FaceGroupData grp = new DataSet.FaceGroupData(); grp.name = objData.faceGroups[buildStatus.grpIdx].name; grp.materialName = objData.faceGroups[buildStatus.grpIdx].materialName; // data for sub-object DataSet.ObjectData subObjData = new DataSet.ObjectData(); subObjData.hasNormals = objData.hasNormals; subObjData.hasColors = objData.hasColors; HashSet <int> vertIdxSet = new HashSet <int>(); bool conv2sided = buildOptions != null && buildOptions.convertToDoubleSided; int maxIdx4mesh = conv2sided ? MAX_INDICES_LIMIT_FOR_A_MESH / 2 : MAX_INDICES_LIMIT_FOR_A_MESH; // copy blocks of face indices to each sub-object data for (int f = buildStatus.grpFaceIdx; f < objData.faceGroups[buildStatus.grpIdx].faces.Count; f++) { // if large meshed must be split and // if passed the max num of vertices and not at the last iteration if (splitLargeMeshes && (vertIdxSet.Count / 3 > MAX_VERT_COUNT / 3 || subObjData.allFaces.Count / 3 > maxIdx4mesh / 3)) { // split the group across more objects splitGrp = true; buildStatus.grpFaceIdx = f; Debug.LogWarningFormat("Maximum vertex number for a mesh exceeded.\nSplitting object {0} (group {1}, starting from index {2})...", grp.name, buildStatus.grpIdx, f); break; } DataSet.FaceIndices fi = objData.faceGroups[buildStatus.grpIdx].faces[f]; subObjData.allFaces.Add(fi); grp.faces.Add(fi); vertIdxSet.Add(fi.vertIdx); } if (splitGrp || buildStatus.meshPartIdx > 0) { buildStatus.meshPartIdx++; } // create an empty (group) object in case the group has been splitted if (buildStatus.meshPartIdx == 1) { GameObject grpObj = new GameObject(); grpObj.transform.SetParent(buildStatus.currObjGameObject.transform, false); grpObj.name = grp.name; buildStatus.subObjParent = grpObj; } // add a suffix to the group name in case the group has been splitted if (buildStatus.meshPartIdx > 0) { grp.name = buildStatus.subObjParent.name + "_MeshPart" + buildStatus.meshPartIdx; } subObjData.name = grp.name; // add the group to the sub object data subObjData.faceGroups.Add(grp); // update the start index buildStatus.idxCount += subObjData.allFaces.Count; if (!splitGrp) { buildStatus.grpFaceIdx = 0; buildStatus.grpIdx++; } buildStatus.totFaceIdxCount += subObjData.allFaces.Count; GameObject subobj = ImportSubObject(buildStatus.subObjParent, subObjData, mats); if (subobj == null) { Debug.LogWarningFormat("Error loading sub object n.{0}.", buildStatus.subObjCount); } //else Debug.LogFormat( "Imported face indices: {0} to {1}", buildStatus.totFaceIdxCount - sub_od.AllFaces.Count, buildStatus.totFaceIdxCount ); buildStatus.subObjCount++; if (buildStatus.totFaceIdxCount >= objData.allFaces.Count || buildStatus.grpIdx >= objData.faceGroups.Count) { if (buildStatus.totFaceIdxCount != objData.allFaces.Count) { Debug.LogWarningFormat("Imported face indices: {0} of {1}", buildStatus.totFaceIdxCount, objData.allFaces.Count); return(false); } buildStatus.objCount++; buildStatus.newObject = true; } return(true); }
/// <summary> /// Build an object once at a time, to be reiterated until false is returned. /// </summary> /// <param name="parentObj">Game object to which the new objects will be attached</param> /// <param name="mats">Materials from the previously loaded library</param> /// <returns>Return true until no more objects can be added, then false.</returns> protected bool BuildNextObject(GameObject parentObj, Dictionary <string, Material> mats) { if (buildStatus.objCount >= currDataSet.objectList.Count) { return(false); } DataSet.ObjectData objData = currDataSet.objectList[buildStatus.objCount]; if (buildStatus.newObject) { if (buildStatus.objCount == 0 && objData.name == "default") { buildStatus.currObjGameObject = parentObj; } else { buildStatus.currObjGameObject = new GameObject(); buildStatus.currObjGameObject.transform.parent = parentObj.transform; buildStatus.currObjGameObject.name = objData.name; // restore the scale if the parent was rescaled buildStatus.currObjGameObject.transform.localScale = Vector3.one; } buildStatus.subObjParent = buildStatus.currObjGameObject; //if (od.Name != "default") go.name = od.Name; //Debug.Log("Object: " + objData.name); buildStatus.newObject = false; buildStatus.subObjCount = 0; buildStatus.idxCount = 0; buildStatus.grpIdx = 0; buildStatus.grpFaceIdx = 0; buildStatus.meshPartIdx = 0; buildStatus.totFaceIdxCount = 0; buildStatus.numGroups = Mathf.Max(1, objData.faceGroups.Count); } // data for sub-object DataSet.ObjectData subObjData = new DataSet.ObjectData(); subObjData.hasNormals = objData.hasNormals; HashSet <int> vertIdxSet = new HashSet <int>(); bool splitGrp = false; DataSet.FaceGroupData grp = new DataSet.FaceGroupData(); grp.name = objData.faceGroups[buildStatus.grpIdx].name; grp.materialName = objData.faceGroups[buildStatus.grpIdx].materialName; // copy blocks of face indices to each sub-object data for (int f = buildStatus.grpFaceIdx; f < objData.faceGroups[buildStatus.grpIdx].faces.Count; f++) { // if passed the max num of vertices and not at the last iteration if (vertIdxSet.Count / 3 > MAX_VERT_COUNT / 3 || subObjData.allFaces.Count / 3 > MAX_INDICES_LIMIT_FOR_A_MESH / 3) { // split the group across more objects splitGrp = true; buildStatus.grpFaceIdx = f; Debug.LogWarningFormat("Maximum vertex number for a mesh exceeded.\nSplitting object {0} ({1}th group, starting from index {2})...", grp.name, buildStatus.grpIdx, f); break; } DataSet.FaceIndices fi = objData.faceGroups[buildStatus.grpIdx].faces[f]; subObjData.allFaces.Add(fi); grp.faces.Add(fi); vertIdxSet.Add(fi.vertIdx); } if (splitGrp || buildStatus.meshPartIdx > 0) { buildStatus.meshPartIdx++; } // create an empty (group) object in case the group has been splitted if (buildStatus.meshPartIdx == 1) { GameObject grpObj = new GameObject(); grpObj.transform.SetParent(buildStatus.currObjGameObject.transform, false); grpObj.name = grp.name; buildStatus.subObjParent = grpObj; } // add a suffix to the group name in case the group has been splitted if (buildStatus.meshPartIdx > 0) { grp.name = buildStatus.subObjParent.name + "_MeshPart" + buildStatus.meshPartIdx; } subObjData.name = grp.name; // add the group to the sub object data subObjData.faceGroups.Add(grp); // update the start index buildStatus.idxCount += subObjData.allFaces.Count; if (!splitGrp) { buildStatus.grpFaceIdx = 0; buildStatus.grpIdx++; } buildStatus.totFaceIdxCount += subObjData.allFaces.Count; GameObject subobj = ImportSubObject(buildStatus.subObjParent, subObjData, mats); if (subobj == null) { Debug.LogWarningFormat("Error loading sub object n.{0}.", buildStatus.subObjCount); } //else Debug.LogFormat( "Imported face indices: {0} to {1}", buildStatus.totFaceIdxCount - sub_od.AllFaces.Count, buildStatus.totFaceIdxCount ); buildStatus.subObjCount++; if (buildStatus.totFaceIdxCount >= objData.allFaces.Count || buildStatus.grpIdx >= objData.faceGroups.Count) { if (buildStatus.totFaceIdxCount != objData.allFaces.Count) { Debug.LogWarningFormat("Imported face indices: {0} of {1}", buildStatus.totFaceIdxCount, objData.allFaces.Count); return(false); } buildStatus.objCount++; buildStatus.newObject = true; } return(true); }