void Start() { mesh = new Mesh(); renderer.BakeMesh(mesh); collider.sharedMesh = mesh; }
public void Build(bool buildPrefab = false) { // Building Model for (int i = 0; i < numFaces; i++) { for (int j = 0; j < faces[i].verticesCount; j++) { if (tim != null) { float u = faces[i].uv[j].x / tim.width; float v = faces[i].uv[j].y / tim.height; faces[i].uv[j] = (new Vector2(u, v)); } else { faces[i].uv[j] = Vector2.zero; } } } Mesh shapeMesh = new Mesh(); List <Vector3> meshVertices = new List <Vector3>(); List <int> meshTriangles = new List <int>(); List <Vector2> meshTrianglesUV = new List <Vector2>(); List <BoneWeight> meshWeights = new List <BoneWeight>(); List <Color32> meshColors = new List <Color32>(); for (int i = 0; i < faces.Count; i++) { //Debug.Log("faces["+i+"] .type : " + faces[i].type + " || .size : " + faces[i].size + " || .side : " + faces[i].side + " || .alpha : " + faces[i].alpha); if (faces[i].type == 0x2C || faces[i].type == 0x3C) { if (faces[i].side != 4) { meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[0]].position); meshWeights.Add(vertices[faces[i].vertices[0]].boneWeight); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[1]].position); meshWeights.Add(vertices[faces[i].vertices[1]].boneWeight); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[2]].position); meshWeights.Add(vertices[faces[i].vertices[2]].boneWeight); meshTrianglesUV.Add(faces[i].uv[0]); meshTrianglesUV.Add(faces[i].uv[1]); meshTrianglesUV.Add(faces[i].uv[2]); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[3]].position); meshWeights.Add(vertices[faces[i].vertices[3]].boneWeight); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[2]].position); meshWeights.Add(vertices[faces[i].vertices[2]].boneWeight); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[1]].position); meshWeights.Add(vertices[faces[i].vertices[1]].boneWeight); meshTrianglesUV.Add(faces[i].uv[3]); meshTrianglesUV.Add(faces[i].uv[2]); meshTrianglesUV.Add(faces[i].uv[1]); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[2]].position); meshWeights.Add(vertices[faces[i].vertices[2]].boneWeight); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[1]].position); meshWeights.Add(vertices[faces[i].vertices[1]].boneWeight); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[0]].position); meshWeights.Add(vertices[faces[i].vertices[0]].boneWeight); meshTrianglesUV.Add(faces[i].uv[2]); meshTrianglesUV.Add(faces[i].uv[1]); meshTrianglesUV.Add(faces[i].uv[0]); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[1]].position); meshWeights.Add(vertices[faces[i].vertices[1]].boneWeight); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[2]].position); meshWeights.Add(vertices[faces[i].vertices[2]].boneWeight); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[3]].position); meshWeights.Add(vertices[faces[i].vertices[3]].boneWeight); meshTrianglesUV.Add(faces[i].uv[1]); meshTrianglesUV.Add(faces[i].uv[2]); meshTrianglesUV.Add(faces[i].uv[3]); if (excpFaces) { // we have colored vertices meshColors.Add(faces[i].colors[0]); meshColors.Add(faces[i].colors[1]); meshColors.Add(faces[i].colors[2]); meshColors.Add(faces[i].colors[3]); meshColors.Add(faces[i].colors[2]); meshColors.Add(faces[i].colors[1]); meshColors.Add(faces[i].colors[2]); meshColors.Add(faces[i].colors[1]); meshColors.Add(faces[i].colors[0]); meshColors.Add(faces[i].colors[1]); meshColors.Add(faces[i].colors[2]); meshColors.Add(faces[i].colors[3]); } } else { meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[0]].position); meshWeights.Add(vertices[faces[i].vertices[0]].boneWeight); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[1]].position); meshWeights.Add(vertices[faces[i].vertices[1]].boneWeight); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[2]].position); meshWeights.Add(vertices[faces[i].vertices[2]].boneWeight); meshTrianglesUV.Add(faces[i].uv[0]); meshTrianglesUV.Add(faces[i].uv[1]); meshTrianglesUV.Add(faces[i].uv[2]); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[3]].position); meshWeights.Add(vertices[faces[i].vertices[3]].boneWeight); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[2]].position); meshWeights.Add(vertices[faces[i].vertices[2]].boneWeight); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[1]].position); meshWeights.Add(vertices[faces[i].vertices[1]].boneWeight); meshTrianglesUV.Add(faces[i].uv[3]); meshTrianglesUV.Add(faces[i].uv[2]); meshTrianglesUV.Add(faces[i].uv[1]); if (excpFaces) { // we have colored vertices meshColors.Add(faces[i].colors[0]); meshColors.Add(faces[i].colors[1]); meshColors.Add(faces[i].colors[2]); meshColors.Add(faces[i].colors[3]); meshColors.Add(faces[i].colors[2]); meshColors.Add(faces[i].colors[1]); } } } else if (faces[i].type == 0x24 || faces[i].type == 0x34) { if (faces[i].side != 4) { meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[0]].position); meshWeights.Add(vertices[faces[i].vertices[0]].boneWeight); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[1]].position); meshWeights.Add(vertices[faces[i].vertices[1]].boneWeight); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[2]].position); meshWeights.Add(vertices[faces[i].vertices[2]].boneWeight); meshTrianglesUV.Add(faces[i].uv[1]); meshTrianglesUV.Add(faces[i].uv[2]); meshTrianglesUV.Add(faces[i].uv[0]); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[2]].position); meshWeights.Add(vertices[faces[i].vertices[2]].boneWeight); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[1]].position); meshWeights.Add(vertices[faces[i].vertices[1]].boneWeight); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[0]].position); meshWeights.Add(vertices[faces[i].vertices[0]].boneWeight); meshTrianglesUV.Add(faces[i].uv[0]); meshTrianglesUV.Add(faces[i].uv[2]); meshTrianglesUV.Add(faces[i].uv[1]); if (excpFaces) { // we have colored vertices meshColors.Add(faces[i].colors[0]); meshColors.Add(faces[i].colors[1]); meshColors.Add(faces[i].colors[2]); meshColors.Add(faces[i].colors[2]); meshColors.Add(faces[i].colors[1]); meshColors.Add(faces[i].colors[0]); } } else { meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[0]].position); meshWeights.Add(vertices[faces[i].vertices[0]].boneWeight); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[1]].position); meshWeights.Add(vertices[faces[i].vertices[1]].boneWeight); meshTriangles.Add(meshVertices.Count); meshVertices.Add(vertices[faces[i].vertices[2]].position); meshWeights.Add(vertices[faces[i].vertices[2]].boneWeight); meshTrianglesUV.Add(faces[i].uv[1]); meshTrianglesUV.Add(faces[i].uv[2]); meshTrianglesUV.Add(faces[i].uv[0]); if (excpFaces) { // we have colored vertices meshColors.Add(faces[i].colors[0]); meshColors.Add(faces[i].colors[1]); meshColors.Add(faces[i].colors[2]); } } } } shapeMesh.name = FileName + "_mesh"; shapeMesh.vertices = meshVertices.ToArray(); shapeMesh.triangles = meshTriangles.ToArray(); shapeMesh.uv = meshTrianglesUV.ToArray(); shapeMesh.boneWeights = meshWeights.ToArray(); if (excpFaces) { shapeMesh.colors32 = meshColors.ToArray(); } if (tim != null) { texture = tim.textures[0]; texture.filterMode = FilterMode.Trilinear; texture.anisoLevel = 4; #if UNITY_EDITOR texture.alphaIsTransparency = true; #endif texture.wrapMode = TextureWrapMode.Repeat; texture.Compress(true); } else { texture = new Texture2D(128, 128); } Material mat = null; if (excpFaces) { Shader shader = Shader.Find("Particles/Standard Unlit"); mat = new Material(shader); mat.name = string.Concat("Material_SHP_", FileName); mat.SetTexture("_MainTex", texture); mat.SetFloat("_Mode", 0); mat.SetFloat("_ColorMode", 0); mat.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); mat.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); mat.SetInt("_ZWrite", 1); mat.EnableKeyword("_ALPHATEST_ON"); mat.DisableKeyword("_ALPHABLEND_ON"); mat.DisableKeyword("_ALPHAPREMULTIPLY_ON"); mat.SetTextureScale("_MainTex", new Vector2(1, -1)); } else { Shader shader = Shader.Find("Standard"); mat = new Material(shader); mat.name = string.Concat("Material_SHP_", FileName); mat.SetTexture("_MainTex", texture); mat.SetFloat("_Mode", 1); mat.SetFloat("_Cutoff", 0.5f); mat.SetFloat("_Glossiness", 0.0f); mat.SetFloat("_SpecularHighlights", 0.0f); mat.SetFloat("_GlossyReflections", 0.0f); mat.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); mat.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); mat.SetInt("_ZWrite", 1); mat.EnableKeyword("_ALPHATEST_ON"); mat.DisableKeyword("_ALPHABLEND_ON"); mat.DisableKeyword("_ALPHAPREMULTIPLY_ON"); mat.SetTextureScale("_MainTex", new Vector2(1, -1)); } material = mat; GameObject shapeGo = new GameObject(FileName); GameObject meshGo = new GameObject(FileName + "_mesh"); meshGo.transform.parent = shapeGo.transform; Transform[] meshBones = new Transform[numBones]; Matrix4x4[] bindPoses = new Matrix4x4[numBones]; for (int i = 0; i < numBones; i++) { meshBones[i] = new GameObject(bones[i].name).transform; meshBones[i].localRotation = Quaternion.identity; bindPoses[i] = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one); if (bones[i].parentIndex == -1) { meshBones[i].parent = shapeGo.transform; meshBones[i].localPosition = Vector3.zero; } else { meshBones[i].parent = meshBones[bones[i].parentIndex]; meshBones[i].localPosition = new Vector3((float)(bones[bones[i].parentIndex].length) / 100, 0, 0); } } SkinnedMeshRenderer mr = meshGo.AddComponent <SkinnedMeshRenderer>(); mr.material = mat; mr.bones = meshBones; shapeMesh.bindposes = bindPoses; mr.rootBone = meshBones[0]; mr.sharedMesh = shapeMesh; mesh = shapeMesh; this.shapeGo = shapeGo; string modFolder = "Assets/Resources/Prefabs/Models/"; string modFilename = string.Concat(modFolder, "SHP_", FileName, ".prefab"); #if UNITY_EDITOR if (buildPrefab == true) { GameObject shpBase = shapeGo; GameObject prefab = PrefabUtility.SaveAsPrefabAsset(shpBase, modFilename); string shpId = FileName; if (shpId == "06" || shpId == "99" || shpId == "C9" || shpId == "CA") { shpId = "00"; // Ashley Shapes } if (shpId == "7C") { shpId = "02"; // Rozencrantz } if (shpId == "9B") { shpId = "03"; // Merlose } if (shpId == "98") { shpId = "83"; // Sydney } // Animations seeker Avatar ava = AvatarBuilder.BuildGenericAvatar(shpBase, "bone_0"); ava.name = FileName + "_Ava"; AssetDatabase.AddObjectToAsset(ava, modFilename); Animator animator = shpBase.GetComponent <Animator>(); if (!animator) { animator = shpBase.AddComponent <Animator>(); } AnimatorController ac = AnimatorController.Instantiate(AssetDatabase.LoadAssetAtPath <AnimatorController>("Assets/Resources/Prefabs/DefaultAC.controller") as AnimatorController); ac.name = FileName + "_AC"; animator.runtimeAnimatorController = ac; animator.avatar = ava; AssetDatabase.AddObjectToAsset(ac, modFilename); string[] hash = FilePath.Split("/"[0]); hash[hash.Length - 1] = ""; string[] files = Directory.GetFiles(String.Join("/", hash), "*.SEQ"); bool posed = false; uint i = 0; foreach (string file in files) { List <string> topa = new List <string>(); topa.Add("_COM.SEQ"); topa.Add("_BT1.SEQ"); topa.Add("_BT2.SEQ"); topa.Add("_BT3.SEQ"); topa.Add("_BT4.SEQ"); topa.Add("_BT5.SEQ"); topa.Add("_BT6.SEQ"); topa.Add("_BT7.SEQ"); topa.Add("_BT8.SEQ"); topa.Add("_BT9.SEQ"); topa.Add("_BTA.SEQ"); hash = file.Split("/"[0]); if (hash[hash.Length - 1].StartsWith(shpId) && file.EndsWith(".SEQ")) { if (topa.Contains(hash[hash.Length - 1].Substring(2, 8))) { SEQ _seq = new SEQ(); _seq.Parse(file); if (!posed || file == shpId + "_COM.SEQ") { posed = true; _seq.FirstPoseModel(shpBase); Mesh baked = new Mesh(); baked.name = string.Concat("Baked_Mesh_SHP_", FileName); mr.BakeMesh(baked); //baked.bindposes = bindPoses; // need to recalculate this before using the baked mesh //baked.boneWeights = meshWeights.ToArray(); //mr.sharedMesh = baked; //shapeMesh.RecalculateNormals(); shapeMesh.RecalculateTangents(); shapeMesh.Optimize(); //AssetDatabase.RemoveObjectFromAsset(mesh); AssetDatabase.AddObjectToAsset(baked, modFilename); } AnimationClip[] clips = _seq.BuildAnimationClips(shpBase); AnimatorControllerLayer layer = new AnimatorControllerLayer(); layer.name = hash[hash.Length - 1].Substring(0, 6); layer.stateMachine = new AnimatorStateMachine(); layer.stateMachine.states = ac.layers[0].stateMachine.states; ac.AddLayer(hash[hash.Length - 1].Substring(0, 6)); i++; foreach (AnimationClip clip in clips) { if (clip != null) { AssetDatabase.AddObjectToAsset(clip, modFilename); AnimatorState state = ac.layers[i].stateMachine.AddState(clip.name); state.motion = clip; } } } } } if (shpBase != null) { mesh = shapeMesh; AssetDatabase.AddObjectToAsset(mesh, modFilename); AssetDatabase.AddObjectToAsset(material, modFilename); AssetDatabase.AddObjectToAsset(texture, modFilename); } //PrefabUtility.ReplacePrefab(shpBase, prefab); prefab = PrefabUtility.SaveAsPrefabAsset(shpBase, modFilename); AssetDatabase.SaveAssets(); GameObject.DestroyImmediate(shpBase); } #endif mesh = shapeMesh; }
// Update is called once per frame void Update() { skinned.BakeMesh(mesh); //Debug.Log(mesh.vertices.Length); }
void LateUpdate() { if (!Application.isPlaying || !EditorApplication.isPlayingOrWillChangePlaymode || !startRecord) { return; } currentTime += Time.deltaTime; if (currentTime > frameInterval) { currentTime -= frameInterval; } else { return; } bool isIframe = frameCnt == 0 ? true : false; if (isIframe) { tiling.SetInt("packSize", packageSize); tiling.SetInt("range", containerSize); } if (renderers != null) { Dictionary <int, TilePacker> dicPacks = new Dictionary <int, TilePacker>(); List <FragmentVertex[]> frag = new List <FragmentVertex[]>(); for (int i = 0; i < renderers.Count; i++) { SkinnedMeshRenderer smr = renderers[i]; if (smr != null) { //convert to tiled vertices Mesh tempMesh = new Mesh(); smr.BakeMesh(tempMesh); //calculate shader threads and dipatch size; int alignedNum = 16; string kernelName = "cs_main8"; int verts = tempMesh.vertices.Length; int dispatch = 2; for (int k = 0; k < alignedVerts.Length; k++) { int aligned = alignedVerts[k]; if (verts - aligned <= 0) { alignedNum = aligned; kernelName = kernelNames[k]; dispatch = dispatches[k]; break; } } Vector3[] src = new Vector3[alignedNum]; tempMesh.vertices.CopyTo(src, 0); DestroyImmediate(tempMesh); Quaternion quat = smr.transform.rotation; Vector3 pos = smr.transform.position - targetGameObject.transform.position; Vector3 scale = new Vector3(1, 1, 1); Matrix4x4 wrd = Matrix4x4.TRS(pos, quat, scale); float[] wrdMatrix = { wrd.m00, wrd.m01, wrd.m02, wrd.m03, wrd.m10, wrd.m11, wrd.m12, wrd.m13, wrd.m20, wrd.m21, wrd.m22, wrd.m23, wrd.m30, wrd.m31, wrd.m32, wrd.m33 }; if (isIframe) { tiling.SetFloats("wrdMatrix", wrdMatrix); tiling.SetInt("modelGroup", i); ComputeBuffer srcBuf = new ComputeBuffer(alignedNum, Marshal.SizeOf(typeof(Vector3))); ComputeBuffer destBuf = new ComputeBuffer(alignedNum, Marshal.SizeOf(typeof(TiledVertex))); srcBuf.SetData(src); int kernelNum = tiling.FindKernel(kernelName); tiling.SetBuffer(kernelNum, "srcBuf", srcBuf); tiling.SetBuffer(kernelNum, "destBuf", destBuf); tiling.Dispatch(kernelNum, dispatch, 1, 1); TiledVertex[] data = new TiledVertex[src.Length]; destBuf.GetData(data); srcBuf.Release(); destBuf.Release(); for (int j = 0; j < verts; j++) { TiledVertex vert = data[j]; int tx = (vert.tileID & 0xFF); int ty = (vert.tileID & 0xFF00) >> 8; int tz = (vert.tileID & 0xFF0000) >> 16; int tileID = tx + ty * packageSize + tz * (packageSize * packageSize); if (tx == 255 && ty == 255 && tz == 255) { continue; } TilePacker tile; if (!dicPacks.TryGetValue(tileID, out tile)) { tile = new TilePacker(tx, ty, tz); dicPacks.Add(tileID, tile); } ByteCoord coord = new ByteCoord(); coord.p1 = (byte)((vert.polyIndex & 0xFF)); coord.p2 = (byte)((vert.polyIndex & 0xFF00) >> 8); coord.p3 = (byte)((vert.polyIndex & 0xFF0000) >> 16); coord.x = (byte)vert.x; coord.y = (byte)vert.y; coord.z = (byte)vert.z; dicPacks[tileID].AddVertex(coord); } } else { diff.SetFloats("wrdMatrix", wrdMatrix); diff.SetFloats("oldMatrix", oldMatrix[i]); ComputeBuffer srcBuf = new ComputeBuffer(alignedNum, Marshal.SizeOf(typeof(Vector3))); ComputeBuffer oldBuf = new ComputeBuffer(alignedNum, Marshal.SizeOf(typeof(Vector3))); ComputeBuffer destBuf = new ComputeBuffer(alignedNum, Marshal.SizeOf(typeof(FragmentVertex))); srcBuf.SetData(src); oldBuf.SetData(oldVertsBuf[i]); int kernelNum = diff.FindKernel(kernelName); diff.SetBuffer(kernelNum, "srcBuf", srcBuf); diff.SetBuffer(kernelNum, "oldBuf", oldBuf); diff.SetBuffer(kernelNum, "destBuf", destBuf); diff.Dispatch(kernelNum, dispatch, 1, 1); FragmentVertex[] data = new FragmentVertex[src.Length]; destBuf.GetData(data); srcBuf.Release(); oldBuf.Release(); destBuf.Release(); frag.Add(data); } oldVertsBuf[i] = src; oldMatrix[i] = wrdMatrix; } } int packages = 0; List <byte> lPacks = new List <byte>(); if (isIframe) { linedIndices.Clear(); foreach (KeyValuePair <int, TilePacker> p in dicPacks) { packages++; TilePacker pack = p.Value; lPacks.AddRange(pack.PackToByteArray(packageSize)); linedIndices.AddRange(pack.getIndices()); } } else { for (int i = 0; i < linedIndices.Count; i++) { int meshIndex = (linedIndices[i] >> 16) & 0xFF; int vertIndex = linedIndices[i] & 0xFFFF; FragmentVertex f = frag[meshIndex][vertIndex]; byte[] val = new byte[3]; val[0] = (byte)(f.x); val[1] = (byte)(f.y); val[2] = (byte)(f.z); lPacks.AddRange(val); } } int currentBinaryLength = combinedBinary.Count; if (currentBinaryLength == 0) { tempStartTicks = DateTime.Now.Ticks; } byte[] streamData = AddHeader(lPacks.ToArray(), targetGameObject.transform.position, packages, isIframe, timeStamp); byteSize.Add(streamData.Length); combinedBinary.AddRange(streamData); timeStamp++; if (timeStamp % combinedFrames == 0 && timeStamp > 0) { long tick = timeStamp / combinedFrames - 1; long startTicks = tempStartTicks - recordStartTicks; long endTicks = DateTime.Now.Ticks - recordStartTicks; StreamInfo streamInfo = serializer.CreateStreamInfo(tick, startTicks, endTicks); serializer.Send(streamInfo, tick); string fileName = tick.ToString("000000") + ".stmv"; byte[] buffer = new byte[(byteSize.Count + 1) * sizeof(int) + combinedBinary.Count]; byteSize.Insert(0, byteSize.Count); Buffer.BlockCopy(byteSize.ToArray(), 0, buffer, 0, byteSize.Count * sizeof(int)); Buffer.BlockCopy(combinedBinary.ToArray(), 0, buffer, byteSize.Count * sizeof(int), combinedBinary.Count); //serializer.Send(ExternalTools.Compress(combinedBinary.ToArray()), "stream", fileName); serializer.Send(Lib.ExternalTools.Compress(buffer), "stream", fileName); byteSize.Clear(); combinedBinary.Clear(); } } frameCnt = (frameCnt + 1) % (subframesPerKeyframe + 1); }
void DoUpdate() { if (WrapEnabled == false || target == null || bindverts == null) //|| bindposes == null ) { return; } if (mesh == null) { SetMesh(); } if (mesh == null) { return; } if (targetIsSkin && neededVerts != null && neededVerts.Count > 0) //|| (targetIsSkin && boneweights == null) ) { if (boneweights == null || tmesh == null) { tmesh = (SkinnedMeshRenderer)target.GetComponent(typeof(SkinnedMeshRenderer)); if (tmesh != null) { if (!sourceIsSkin) { Mesh sm = tmesh.sharedMesh; bindposes = sm.bindposes; bones = tmesh.bones; boneweights = sm.boneWeights; } } } #if UNITY_5 || UNITY_2017 if (tmesh == null) { tmesh = (SkinnedMeshRenderer)target.GetComponent(typeof(SkinnedMeshRenderer)); } if (UseBakedMesh) { if (bakedmesh == null) { bakedmesh = new Mesh(); } tmesh.BakeMesh(bakedmesh); skinnedVerts = bakedmesh.vertices; } else { for (int i = 0; i < neededVerts.Count; i++) { skinnedVerts[neededVerts[i]] = GetSkinPos(neededVerts[i]); } } #else for (int i = 0; i < neededVerts.Count; i++) { skinnedVerts[neededVerts[i]] = GetSkinPos(neededVerts[i]); } #endif } Matrix4x4 stm = Matrix4x4.identity; Vector3 p = Vector3.zero; if (targetIsSkin && !sourceIsSkin) { #if UNITY_5 || UNITY_2017 if (UseBakedMesh) { stm = transform.worldToLocalMatrix * target.transform.localToWorldMatrix; // * transform.worldToLocalMatrix; } else { stm = transform.worldToLocalMatrix; // * target.transform.localToWorldMatrix; // * transform.worldToLocalMatrix; } #else stm = transform.worldToLocalMatrix; // * target.transform.localToWorldMatrix; // * transform.worldToLocalMatrix; #endif for (int i = 0; i < bindverts.Length; i++) { if (bindverts[i].verts.Count > 0) { p = Vector3.zero; float oow = 1.0f / bindverts[i].weight; int cnt = bindverts[i].verts.Count; for (int j = 0; j < cnt; j++) { MegaBindInf bi = bindverts[i].verts[j]; Vector3 p0 = skinnedVerts[bi.i0]; Vector3 p1 = skinnedVerts[bi.i1]; Vector3 p2 = skinnedVerts[bi.i2]; Vector3 cp = GetCoordMine(p0, p1, p2, bi.bary); Vector3 norm = FaceNormal(p0, p1, p2); float sq = 1.0f / Mathf.Sqrt(norm.x * norm.x + norm.y * norm.y + norm.z * norm.z); float d = (bi.dist * shrink) + gap; //cp += d * norm.x; cp.x += d * norm.x * sq; cp.y += d * norm.y * sq; cp.z += d * norm.z * sq; float bw = bi.weight * oow; if (j == 0) { p.x = cp.x * bw; p.y = cp.y * bw; p.z = cp.z * bw; } else { p.x += cp.x * bw; p.y += cp.y * bw; p.z += cp.z * bw; } //cp += ((bi.dist * shrink) + gap) * norm.normalized; //p += cp * (bi.weight / bindverts[i].weight); } Vector3 pp = stm.MultiplyPoint3x4(p); verts[i].x = pp.x + offset.x; verts[i].y = pp.y + offset.y; verts[i].z = pp.z + offset.z; //verts[i] = transform.InverseTransformPoint(p) + offset; } } } else { stm = transform.worldToLocalMatrix * target.transform.localToWorldMatrix; // * transform.worldToLocalMatrix; //Matrix4x4 tm = target.transform.localToWorldMatrix; for (int i = 0; i < bindverts.Length; i++) { if (bindverts[i].verts.Count > 0) { p = Vector3.zero; float oow = 1.0f / bindverts[i].weight; for (int j = 0; j < bindverts[i].verts.Count; j++) { MegaBindInf bi = bindverts[i].verts[j]; Vector3 p0 = target.sverts[bi.i0]; Vector3 p1 = target.sverts[bi.i1]; Vector3 p2 = target.sverts[bi.i2]; Vector3 cp = GetCoordMine(p0, p1, p2, bi.bary); Vector3 norm = FaceNormal(p0, p1, p2); float sq = 1.0f / Mathf.Sqrt(norm.x * norm.x + norm.y * norm.y + norm.z * norm.z); float d = (bi.dist * shrink) + gap; //cp += d * norm.x; cp.x += d * norm.x * sq; cp.y += d * norm.y * sq; cp.z += d * norm.z * sq; float bw = bi.weight * oow; if (j == 0) { p.x = cp.x * bw; p.y = cp.y * bw; p.z = cp.z * bw; } else { p.x += cp.x * bw; p.y += cp.y * bw; p.z += cp.z * bw; } //cp += ((bi.dist * shrink) + gap) * norm.normalized; //p += cp * (bi.weight / bindverts[i].weight); } } else { p = freeverts[i]; //startverts[i]; } Vector3 pp = stm.MultiplyPoint3x4(p); verts[i].x = pp.x + offset.x; verts[i].y = pp.y + offset.y; verts[i].z = pp.z + offset.z; //p = target.transform.TransformPoint(p); //verts[i] = transform.InverseTransformPoint(p) + offset; } } mesh.vertices = verts; RecalcNormals(); mesh.RecalculateBounds(); }
private void DoUpdate() { try { if (!gameObject || !gameObject.activeInHierarchy) { return; } bool updated = false; if (BlendShapesDirty() || NeedsTimeUpdate()) { skinnedMeshRenderer.BakeMesh(bakedMesh); bakedMesh.GetVertices(vertexList); // bakedMesh.GetNormals(normalList); updated = true; lastUpdateTime = Time.time; } foreach (int vertexId in SkinnedMeshRendererListeners.Keys) { List <SkinnedMeshUpdateFrame> frameList = frameSet[vertexId]; Vector3 verticeLocation = vertexList[vertexId]; // Vector3 normalDirection = normalList[vertexId]; SkinnedMeshRenderedVertex vertex; if (!RenderAlways) { vertex = new SkinnedMeshRenderedVertex(transform.TransformPoint(verticeLocation), Vector3.zero, verticeLocation, Vector3.zero); } else if (updated) { frameList.Add(new SkinnedMeshUpdateFrame(verticeLocation, Time.time, Vector3.zero)); if (frameList.Count > 1) { frameList[frameList.Count - 2] = new SkinnedMeshUpdateFrame(frameList[frameList.Count - 2].position, frameList[frameList.Count - 2].time, (frameList[frameList.Count - 1].position - frameList[frameList.Count - 2].position) / (frameList[frameList.Count - 1].time - frameList[frameList.Count - 2].time)); } while (frameList.Count > FrameHistoryCount) { frameList.RemoveAt(0); } vertex = new SkinnedMeshRenderedVertex(transform.TransformPoint(verticeLocation), Vector3.zero, verticeLocation, Vector3.zero); // SkinnedMeshRenderedVertex vertex = new SkinnedMeshRenderedVertex(transform.TransformPoint(verticeLocation), transform.TransformDirection(normalDirection), verticeLocation, normalDirection); } else { // Extrapolation time Vector3 extrapolatedMovement = AverageDelta(frameList); Vector3 predictedPosition = frameList[frameList.Count - 1].position + (extrapolatedMovement * (Time.time - frameList[frameList.Count - 1].time)); vertex = new SkinnedMeshRenderedVertex(transform.TransformPoint(predictedPosition), Vector3.zero, predictedPosition, Vector3.zero); } foreach (Action <SkinnedMeshRenderedVertex> listener in SkinnedMeshRendererListeners[vertexId]) { listener.Invoke(vertex); } } } catch (Exception e) { Log.LogWarning($"Error in accessory computation: {e.Message}\n{e.StackTrace}"); } }
// Use this for initialization public void Begin() { if (distributionTex == null) { return; } sampler = this.GetComponent <Sampler>(); mf = this.GetComponent <MeshFilter>(); dataExporter = this.GetComponent <ExportDataToTexture>(); if (mf != null) { mesh = mf.mesh; } else { mesh = new Mesh(); skinRenderer.BakeMesh(mesh); } scale = this.transform.localScale.magnitude / this.transform.lossyScale.magnitude; if (dataTex == null) { this.points = sampler.Sampling(); Vector3[] positionDataList = new Vector3[this.points.Length]; distributionDataList = new Vector3[positionDataList.Length]; worldPositions = new Vector3[positionDataList.Length]; for (int i = 0; i < positionDataList.Length; i++) { var p = points[i]; positionDataList[i] = new Vector3(p.index, p.x, p.y); worldPositions[i] = GetWorldPosition(p.x, p.y, p.index); if (distributionTex != null) { var uv = GetCoordinate(p.x, p.y, p.index); var distributionColor = distributionTex.GetPixel((int)(uv.x * distributionTex.width), (int)(uv.y * distributionTex.height)); distributionDataList[i] = new Vector3(distributionColor.r, distributionColor.g, distributionColor.b); } } dataExporter.SetTargetData(positionDataList, distributionDataList); } else { int length = dataTex.width; distributionDataList = new Vector3[length]; worldPositions = new Vector3[length]; var pixels = dataTex.GetPixels(); for (int i = 0; i < length; i++) { var p = dataTex.GetPixel(i, 0); if (p != null) { worldPositions[i] = GetWorldPosition(p.g, p.b, (int)p.r); } var d = dataTex.GetPixel(i, 1); distributionDataList[i] = new Vector3(d.r, d.g, d.b); } //positions = new Vector3[pixels.Length]; //for (int i = 0; i < pixels.Length; i++) //{ // var col = pixels[i]; // var p = new PointData(); // p.index = (int)col.r; // p.u = col.g; // p.v = col.b; // //Debug.Log("<color=green>" + col + "</color>"); // //positions[i] = UvToWorldPosition(p.u, p.v, p.index); //} } }
private void BakeMesh() { _skinnedMeshRenderer.BakeMesh(_mesh); }
void LateUpdate() { if (!_currentMesh) { _currentMesh = new Mesh(); } if (!_meshRenderer) { _meshRenderer = GetComponent <SkinnedMeshRenderer>(); } if (_previousFrameMesh) { // Bake the current vertex data into an array and load the previous vertex data into another one. _meshRenderer.BakeMesh(_currentMesh); _currentMesh.UploadMeshData(false); Vector3[] currentVertices = _currentMesh.vertices; Vector3[] previousVertices = _previousFrameMesh.vertices; // If there's acceleration information, create a new array to store it. if (_accelerationColors == null) { _accelerationColors = new Vector3[_currentMesh.vertices.Length]; } Vector3[] vertexDisplacement = new Vector3[currentVertices.Length]; List <Color> colors = new List <Color>(); for (int i = 0; i < currentVertices.Length; i++) { // Calculate how much has that vertex has being displaced in the last frame. vertexDisplacement[i] = previousVertices[i] - _meshRenderer.localToWorldMatrix.MultiplyPoint(currentVertices[i]); // Add that movement to the acceleration colors (and clamp it). _accelerationColors[i] = Vector3.ClampMagnitude(_accelerationColors[i] + vertexDisplacement[i] / 10, 1); colors.Add(new Color(_accelerationColors[i].x, _accelerationColors[i].y, _accelerationColors[i].z, 1)); } // Pass the acceleration information as input for the vertex colors. _meshRenderer.sharedMesh.SetColors(colors); _meshRenderer.sharedMesh.UploadMeshData(false); } // Bake the current mesh to be used in next frames. if (!_previousFrameMesh) { _previousFrameMesh = new Mesh(); } _meshRenderer.BakeMesh(_previousFrameMesh); // Setup the RWBuffer we're gonna use to effiicently apply the current transformation matrix to all the vertices. ComputeBuffer buffer = new ComputeBuffer(_previousFrameMesh.vertices.Length, 3 * sizeof(float)); buffer.SetData(_previousFrameMesh.vertices); // Setup the variables that the command buffer will use. int kernel = shader.FindKernel("CSMain"); shader.SetBuffer(kernel, "vertexPositions", buffer); shader.SetVector("Position", transform.position); shader.SetVector("MV0", _meshRenderer.localToWorldMatrix.GetRow(0)); shader.SetVector("MV1", _meshRenderer.localToWorldMatrix.GetRow(1)); shader.SetVector("MV2", _meshRenderer.localToWorldMatrix.GetRow(2)); shader.SetVector("MV3", _meshRenderer.localToWorldMatrix.GetRow(3)); // Dispatch it. shader.Dispatch(kernel, _previousFrameMesh.vertices.Length, 1, 1); // Retrieve the data and upload the previous mesh. Vector3[] data = new Vector3[_previousFrameMesh.vertices.Length]; buffer.GetData(data); buffer.Release(); _previousFrameMesh.vertices = data; _previousFrameMesh.UploadMeshData(false); // Decrease the strength of the acceleration colors overtime. if (_accelerationColors != null) { for (int i = 0; i < _accelerationColors.Length; i++) { _accelerationColors[i] = Vector3.Lerp(_accelerationColors[i], Vector3.zero, Time.deltaTime * smearDecceleration * _accelerationColors[i].magnitude); } } }
void LateUpdate() { if (!isConnected || webRtcManager.connections == 0) { return; } currentTime += Time.deltaTime; if (currentTime > frameInterval) { currentTime -= frameInterval; } else { return; } bool isIframe = frameCnt == 0 ? true : false; if (isIframe) { tiling.SetInt("packSize", packageSize); tiling.SetInt("range", areaRange); } if (renderers != null) { Dictionary <int, TilePacker> dicPacks = new Dictionary <int, TilePacker>(); List <FragmentVertex[]> frag = new List <FragmentVertex[]>(); for (int i = 0; i < renderers.Length; i++) { SkinnedMeshRenderer smr = renderers[i]; if (smr != null) { //convert to tiled vertices Mesh tempMesh = new Mesh(); smr.BakeMesh(tempMesh); //calculate shader threads and dipatch size; int alignedNum = 16; string kernelName = "cs_main8"; int verts = tempMesh.vertices.Length; int dispatch = 2; for (int k = 0; k < alignedVerts.Length; k++) { int aligned = alignedVerts[k]; if (verts - aligned <= 0) { alignedNum = aligned; kernelName = kernelNames[k]; dispatch = dispatches[k]; break; } } Vector3[] src = new Vector3[alignedNum]; tempMesh.vertices.CopyTo(src, 0); DestroyImmediate(tempMesh); Quaternion quat = smr.transform.rotation; Vector3 pos = smr.transform.position - targetGameObject.transform.position; Vector3 scale = new Vector3(1, 1, 1); Matrix4x4 wrd = Matrix4x4.TRS(pos, quat, scale); float[] wrdMatrix = { wrd.m00, wrd.m01, wrd.m02, wrd.m03, wrd.m10, wrd.m11, wrd.m12, wrd.m13, wrd.m20, wrd.m21, wrd.m22, wrd.m23, wrd.m30, wrd.m31, wrd.m32, wrd.m33 }; if (isIframe) { tiling.SetFloats("wrdMatrix", wrdMatrix); tiling.SetInt("modelGroup", i); ComputeBuffer srcBuf = new ComputeBuffer( alignedNum, Marshal.SizeOf(typeof(Vector3))); ComputeBuffer destBuf = new ComputeBuffer( alignedNum, Marshal.SizeOf(typeof(TiledVertex))); srcBuf.SetData(src); int kernelNum = tiling.FindKernel(kernelName); tiling.SetBuffer(kernelNum, "srcBuf", srcBuf); tiling.SetBuffer(kernelNum, "destBuf", destBuf); tiling.Dispatch(kernelNum, dispatch, 1, 1); TiledVertex[] data = new TiledVertex[src.Length]; destBuf.GetData(data); srcBuf.Release(); destBuf.Release(); for (int j = 0; j < verts; j++) { TiledVertex vert = data[j]; int tx = (vert.tileID & 0xFF); int ty = (vert.tileID & 0xFF00) >> 8; int tz = (vert.tileID & 0xFF0000) >> 16; int tileID = tx + ty * packageSize + tz * (packageSize * packageSize); if (tx == 255 && ty == 255 && tz == 255) { continue; } TilePacker tile; if (!dicPacks.TryGetValue(tileID, out tile)) { tile = new TilePacker(tx, ty, tz); dicPacks.Add(tileID, tile); } ByteCoord coord = new ByteCoord(); coord.p1 = (byte)((vert.polyIndex & 0xFF)); coord.p2 = (byte)((vert.polyIndex & 0xFF00) >> 8); coord.p3 = (byte)((vert.polyIndex & 0xFF0000) >> 16); coord.x = (byte)vert.x; coord.y = (byte)vert.y; coord.z = (byte)vert.z; dicPacks[tileID].AddVertex(coord); } } else { diff.SetFloats("wrdMatrix", wrdMatrix); diff.SetFloats("oldMatrix", oldMatrix[i]); ComputeBuffer srcBuf = new ComputeBuffer( alignedNum, Marshal.SizeOf(typeof(Vector3))); ComputeBuffer oldBuf = new ComputeBuffer( alignedNum, Marshal.SizeOf(typeof(Vector3))); ComputeBuffer destBuf = new ComputeBuffer( alignedNum, Marshal.SizeOf(typeof(FragmentVertex))); srcBuf.SetData(src); oldBuf.SetData(oldVertsBuf[i]); int kernelNum = diff.FindKernel(kernelName); diff.SetBuffer(kernelNum, "srcBuf", srcBuf); diff.SetBuffer(kernelNum, "oldBuf", oldBuf); diff.SetBuffer(kernelNum, "destBuf", destBuf); diff.Dispatch(kernelNum, dispatch, 1, 1); FragmentVertex[] data = new FragmentVertex[src.Length]; destBuf.GetData(data); srcBuf.Release(); oldBuf.Release(); destBuf.Release(); frag.Add(data); } oldVertsBuf[i] = src; oldMatrix[i] = wrdMatrix; } } int byteCnt = 0; int packages = 0; List <byte> lPacks = new List <byte>(); if (isIframe) { linedIndices.Clear(); foreach (KeyValuePair <int, TilePacker> p in dicPacks) { packages++; TilePacker pack = p.Value; lPacks.AddRange(pack.PackToByteArray(packageSize)); linedIndices.AddRange(pack.getIndices()); } } else { for (int i = 0; i < linedIndices.Count; i++) { int meshIndex = (linedIndices[i] >> 16) & 0xFF; int vertIndex = linedIndices[i] & 0xFFFF; FragmentVertex f = frag[meshIndex][vertIndex]; byte[] val = new byte[3]; val[0] = (byte)(f.x); val[1] = (byte)(f.y); val[2] = (byte)(f.z); lPacks.AddRange(val); } } byteCnt += lPacks.Count; byte[] rawBuf = lPacks.ToArray(); byte[] compressedBuf = null; int[] prog = new int[1]; #if UNITY_WEBGL || BROTLI_NO_COMPRESS #else if (!brotli.compressBuffer(lPacks.ToArray(), ref compressedBuf, prog, quality: 8)) { Debug.Log("compress failed!"); return; } #endif webRtcManager.SendVertexStream(rawBuf, compressedBuf, targetGameObject.transform.position, packages, isIframe, timeStamp, true); timeStamp++; } frameCnt = (frameCnt + 1) % (subframesPerKeyframe + 1); }
private void TrySelect(ref Bounds selectionBounds, HashSet <GameObject> selection, FilteringArgs args, ref Bounds bounds, GameObject go, Plane[] frustumPlanes) { if (!GeometryUtility.TestPlanesAABB(frustumPlanes, bounds)) { return; } bool select; if (MethodOverride == BoxSelectionMethod.LooseFitting) { select = LooseFitting(ref selectionBounds, ref bounds); } else if (MethodOverride == BoxSelectionMethod.Vertex) { select = LooseFitting(ref selectionBounds, ref bounds); if (select && !selection.Contains(go)) { select = false; MeshFilter meshFilter = go.GetComponent <MeshFilter>(); if (meshFilter != null && meshFilter.sharedMesh != null) { Vector3[] vertices = meshFilter.sharedMesh.vertices; for (int i = 0; i < vertices.Length; ++i) { Vector3 vertex = go.transform.TransformPoint(vertices[i]); vertex = Window.Camera.WorldToScreenPoint(vertex); vertex.z = 0; if (selectionBounds.Contains(vertex)) { select = true; break; } } } else { SkinnedMeshRenderer smr = go.GetComponent <SkinnedMeshRenderer>(); if (smr != null && smr.sharedMesh != null) { Mesh bakedMesh = new Mesh(); smr.BakeMesh(bakedMesh); Matrix4x4 m = Matrix4x4.TRS(go.transform.localPosition, go.transform.localRotation, Vector3.one); if (smr.transform.parent != null) { m = m * smr.transform.parent.localToWorldMatrix; } Vector3[] vertices = bakedMesh.vertices; for (int i = 0; i < vertices.Length; ++i) { Vector3 vertex = m.MultiplyPoint(vertices[i]); vertex = Window.Camera.WorldToScreenPoint(vertex); vertex.z = 0; if (selectionBounds.Contains(vertex)) { select = true; break; } } Destroy(bakedMesh); } } } } else if (MethodOverride == BoxSelectionMethod.BoundsCenter) { select = BoundsCenter(ref selectionBounds, ref bounds); } else { select = TransformCenter(ref selectionBounds, go.transform); } if (select) { Filter(selection, args, go); } }
// This is for editing control points void OnSceneGUI() { // If we have a skin and control points then update them if (skin != null && skinnedMeshRenderer != null && skinnedMesh != null && skin.controlPoints != null && skin.controlPoints.Length > 0 && skin.points != null) { Event e = Event.current; Handles.matrix = skin.transform.localToWorldMatrix; EditorGUI.BeginChangeCheck(); Ray r = HandleUtility.GUIPointToWorldRay(e.mousePosition); Vector2 mousePos = r.origin; float selectDistance = HandleUtility.GetHandleSize(mousePos) * baseSelectDistance; if (e.type == EventType.MouseDrag) { skin.editingPoints = true; } else if (e.type == EventType.MouseUp) { skin.editingPoints = false; } #region Draw vertex handles Handles.color = handleColor; Mesh mesh = new Mesh(); skinnedMeshRenderer.BakeMesh(mesh); Vector3[] vertices = new Vector3[mesh.vertexCount]; for (int i = 0; i < mesh.vertexCount; i++) { vertices[i] = mesh.vertices[i]; } Vector3[] newVertices = new Vector3[skinnedMeshRenderer.sharedMesh.vertexCount]; newVertices = skinnedMeshRenderer.sharedMesh.vertices; for (int i = 0; i < skin.controlPoints.Length; i++) { if (Handles.Button(vertices[i], Quaternion.identity, selectDistance, selectDistance, Handles.CircleHandleCap)) { selectedIndex = i; } if (selectedIndex == i) { EditorGUI.BeginChangeCheck(); Vector3 offset = vertices[i] - skin.transform.TransformPoint(skin.points.GetPoint(skin.controlPoints[i])); skin.controlPoints[i].position = skin.transform.InverseTransformPoint(Handles.DoPositionHandle(skin.transform.TransformPoint(skin.points.GetPoint(skin.controlPoints[i])) + offset, Quaternion.identity) - offset); if (EditorGUI.EndChangeCheck()) { skin.points.SetPoint(skin.controlPoints[i]); Undo.RecordObject(skin, "Changed Control Point"); Undo.RecordObject(skin.points, "Changed Control Point"); EditorUtility.SetDirty(this); } } if (skin.editingPoints) { newVertices[i] = skin.points.GetPoint(skin.controlPoints[i]); } } if (skin.editingPoints) { skinnedMeshRenderer.sharedMesh.vertices = newVertices; } #endregion } }
void CubeBakeMeshToCollider() { smRenderer.BakeMesh(playerBakedMesh); }
public static GameObject Skinned2Mesh(Transform zombie) { SkinnedMeshRenderer[] skinnedMeshes = zombie.GetComponentsInChildren <SkinnedMeshRenderer>(); List <CombineInstance> combineList = new List <CombineInstance>(); GameObject parent = new GameObject(); parent.name = zombie.name + "_Splitter" + Random.Range(0, 1000); MeshRenderer meshRenderer = parent.AddComponent <MeshRenderer>(); MeshFilter mshFilter = parent.AddComponent <MeshFilter>(); //if (skinnedMeshes.Length == 1) //{ // Debug.LogWarning("single mesh"); // Mesh mesh = new Mesh(); // skinnedMeshes[0].BakeMesh(mesh); // mshFilter.mesh = mesh; // meshRenderer.material = GameObject.Instantiate(skinnedMeshes[0].material); //} //else { bool isInitMaterial = false; for (int a = 0; a < skinnedMeshes.Length; a++) { SkinnedMeshRenderer skinRenderer = skinnedMeshes[a]; if (skinRenderer.enabled == false) { continue; } if (!isInitMaterial) { isInitMaterial = true; meshRenderer.material = GameObject.Instantiate(skinRenderer.material); } CombineInstance combine = new CombineInstance(); Mesh mesh = new Mesh(); skinRenderer.BakeMesh(mesh); combine.mesh = mesh; combine.transform = Matrix4x4.TRS(zombie.position, zombie.rotation, Vector3.one);// zombie.localToWorldMatrix; combineList.Add(combine); } mshFilter.mesh.CombineMeshes(combineList.ToArray(), true, true); //parent.SetActive(true); while (combineList.Count > 0) { GameObject.Destroy(combineList[0].mesh); combineList.RemoveAt(0); } } //if (skinnedMeshes.Length == 1) //{ // parent.transform.position = zombie.position; // parent.transform.rotation = zombie.rotation; //} return(parent); }
public static bool CreateAnimTex(Animation animation, SkinnedMeshRenderer skinnedMeshRenderer, AnimationClip clip, int width, int vertexCount, int animFrameCount, float maxSize, int accuracy, out Texture2D animTex) { if (vertexCount == 0 || animFrameCount == 0) { animTex = null; return(false); } if (animation.GetClip(clip.name) != null) { animation.RemoveClip(clip.name); } animation.AddClip(clip, clip.name); animation.Play(clip.name); // 开始采样 int lines = Mathf.CeilToInt((float)vertexCount * animFrameCount * accuracy / width); Texture2D result = new Texture2D(width, lines, TextureFormat.RGB24, false); result.filterMode = FilterMode.Point; result.wrapMode = TextureWrapMode.Clamp; Color[] colors = new Color[width * lines]; for (int i = 0; i < animFrameCount; i++) { float time = (float)i / (animFrameCount - 1); animation[clip.name].normalizedTime = time; animation.Sample(); Mesh mesh = new Mesh(); skinnedMeshRenderer.BakeMesh(mesh); var vertices = mesh.vertices; for (int j = 0; j < vertexCount; j++) { Color color = new Color(); var v = vertices[j]; color.r = v.x / maxSize * 0.5f + 0.5f; color.g = v.y / maxSize * 0.5f + 0.5f; color.b = v.z / maxSize * 0.5f + 0.5f; if (accuracy == 1) { colors[i * vertexCount + j] = color; } else if (accuracy == 2) { Color color1, color2; Split(color, out color1, out color2); colors[(i * vertexCount + j) * 2] = color1; colors[(i * vertexCount + j) * 2 + 1] = color2; } else { Color color1, color2, color3; Split(color, out color1, out color2, out color3); colors[(i * vertexCount + j) * accuracy] = color1; colors[(i * vertexCount + j) * accuracy + 1] = color2; colors[(i * vertexCount + j) * accuracy + 2] = color3; } } } result.SetPixels(colors); result.Apply(); animTex = result; return(true); }
void Update() { m_SkinnedMeshRenderer.BakeMesh(m_Mesh); m_Baker.BakeSDF(); m_Vfx.SetTexture("WalkingSDF", m_Baker.SdfTexture); }
private void Update() { if (siruAmount == 0f && !cyu.kissing) { return; } //Due to Unity limitation, "startColor" cannot be called directly from particleSystem.main, so create new temporary variable "mn" var mn = particleSystem.main; mn.startColor = cyu.flags.gaugeFemale < 70.0 ? new Color(1f, 1f, 1f, 1f) : (ParticleSystem.MinMaxGradient) new Color(1f, 0.62f, 0.85f); //Due to Unity limitation, "rateOverTime" cannot be called directly from particleSystem.emission, so create new temporary variable "em" var em = particleSystem.emission; em.rateOverTime = 2f * GetVoiceValue(); if (cyu.kissing && Vector3.SqrMagnitude(tail.transform.position - head.transform.position) < itoDistance) { siruAmount += Time.deltaTime * 0.05f; } else if (itoBreaking) { siruAmount -= Time.deltaTime * 0.5f; } else { siruAmount -= Time.deltaTime * 0.05f; } if (siruAmount > 0f && Vector3.SqrMagnitude(tail.transform.position - head.transform.position) > itoBreakDistance) { BreakIto(); } siruAmount = Mathf.Clamp(siruAmount, 0.0f, 1f); Mesh mesh = new Mesh(); tangRenderer.BakeMesh(mesh); Vector3 vector3 = mesh.vertices[tangVertexIndex]; head.position = tangRenderer.transform.position + tangRenderer.transform.rotation * vector3; tail.position = siruTarget.transform.position; if (itoBreaking) { itoTimer -= Time.deltaTime; int index = posList.Count - 2; if (index > 0) { tail.position = posList[index]; if (itoTimer < 0f || siruAmount <= 0f) { itoBreaking = false; siruAmount = 0.0f; } } float y = top.position.y; top.position = Vector3.Lerp(head.position, tail.position, 10f * Time.deltaTime); top.position = new Vector3(top.position.x, y - Time.deltaTime * 0.3f, top.position.z); } else { top.position = Vector3.Lerp(head.position, tail.position, 10f * Time.deltaTime) - new Vector3(0.0f, 0.5f * Vector3.SqrMagnitude(head.position - tail.position), 0.0f); } OnLineDraw(); }
public string SmrToObjString(SkinnedMeshRenderer smr) { StringBuilder re = new StringBuilder(); var mesh = new Mesh(); smr.BakeMesh(mesh); //var vertices = ObjManager.GetRealVertices(smr); foreach (var V in mesh.vertices) { var v = smr.transform.TransformPoint(V); re.Append(string.Format("v {0} {1} {2}\r\n", v.x, v.y, v.z)); } re.Append("\r\n"); foreach (var VN in mesh.normals) { var vn = smr.transform.TransformDirection(VN); re.Append(string.Format("vn {0} {1} {2}\r\n", vn.x, vn.y, vn.z)); } re.Append("\r\n"); foreach (var vt in mesh.uv) { re.Append(string.Format("vt {0} {1}\r\n", vt.x, vt.y)); } re.Append("\r\n"); re.Append("o " + smr.name + "\r\n"); re.Append("\r\n"); var triangles = mesh.triangles; string uv0 = ""; string uv1 = ""; string uv2 = ""; string normal0 = ""; string normal1 = ""; string normal2 = ""; Debug.Log("mesh.uv.length: " + mesh.uv.Length); Debug.Log("mesh.normals.length: " + mesh.normals.Length); for (int i = 0; i < triangles.Length; i += 3) { if (mesh.uv.Length != 0) { uv0 = (triangles[i] + uvOffset + 1).ToString(); uv1 = (triangles[i + 1] + uvOffset + 1).ToString(); uv2 = (triangles[i + 2] + uvOffset + 1).ToString(); } else { uv0 = ""; uv1 = ""; uv2 = ""; } if (mesh.normals.Length != 0) { normal0 = (triangles[i] + normalOffset + 1).ToString(); normal1 = (triangles[i + 1] + normalOffset + 1).ToString(); normal2 = (triangles[i + 2] + normalOffset + 1).ToString(); } else { normal0 = ""; normal1 = ""; normal2 = ""; } re.Append(string.Format("f {0}/{1}/{2} ", triangles[i + 1] + vertexOffset + 1, uv1, normal1)); re.Append(string.Format(" {0}/{1}/{2} ", triangles[i] + vertexOffset + 1, uv0, normal0)); re.Append(string.Format(" {0}/{1}/{2}\r\n", triangles[i + 2] + vertexOffset + 1, uv2, normal2)); //re.Append(string.Format("f {1}/{1}/{1} {0}/{0}/{0} {2}/{2}/{2}\r\n", triangles[i] + 1 + vertexOffset, triangles[i + 1] + 1 + normalOffset, triangles[i + 2] + 1 + uvOffset)); } vertexOffset += mesh.vertices.Length; normalOffset += mesh.normals.Length; uvOffset += mesh.uv.Length; return(re.ToString()); }
bool CaptureSkinnedMeshRenderer(ref MeshData dst, SkinnedMeshRenderer smr, GetMessage mes, ref Mesh mesh) { mesh = smr.sharedMesh; if (mesh == null) { return(false); } if (!mes.bakeSkin && !mesh.isReadable) { Debug.LogWarning("Mesh " + smr.name + " is not readable and be ignored"); return(false); } Cloth cloth = smr.GetComponent <Cloth>(); if (cloth != null && mes.bakeCloth) { CaptureMesh(ref dst, mesh, cloth, mes.flags, smr.sharedMaterials); } if (mes.bakeSkin) { Mesh tmp = new Mesh(); smr.BakeMesh(tmp); CaptureMesh(ref dst, tmp, null, mes.flags, smr.sharedMaterials); } else { CaptureMesh(ref dst, mesh, null, mes.flags, smr.sharedMaterials); // bones if (mes.flags.getBones) { dst.SetBonePaths(this, smr.bones); dst.bindposes = mesh.bindposes; NativeArray <byte> bonesPerVertex = mesh.GetBonesPerVertex(); NativeArray <BoneWeight1> weights = mesh.GetAllBoneWeights(); dst.WriteBoneWeightsV(ref bonesPerVertex, ref weights); } // blendshapes if (mes.flags.getBlendShapes && mesh.blendShapeCount > 0) { Vector3[] v = new Vector3[mesh.vertexCount]; Vector3[] n = new Vector3[mesh.vertexCount]; Vector3[] t = new Vector3[mesh.vertexCount]; for (int bi = 0; bi < mesh.blendShapeCount; ++bi) { BlendShapeData bd = dst.AddBlendShape(mesh.GetBlendShapeName(bi)); bd.weight = smr.GetBlendShapeWeight(bi); int frameCount = mesh.GetBlendShapeFrameCount(bi); for (int fi = 0; fi < frameCount; ++fi) { mesh.GetBlendShapeFrameVertices(bi, fi, v, n, t); float w = mesh.GetBlendShapeFrameWeight(bi, fi); bd.AddFrame(w, v, n, t); } } } } return(true); }
void ReActive() { m_SkinnedMeshRenderer.BakeMesh(m_MeshFilter.mesh); this.gameObject.SetActive(true); }
void PlayerBakeMeshToCollider() { SMRenderer.BakeMesh(playerBakedMesh); gameObject.GetComponent <MeshCollider>().sharedMesh = playerBakedMesh; }
static Mesh BakeToMesh(CustomPartInfo partInfo, AppearData appearData) { SkinnedMeshRenderer smr = partInfo.Smr; if (string.IsNullOrEmpty(partInfo.ModelName) || smr.sharedMesh.blendShapeCount == 0) { return(smr.sharedMesh); } EMorphItem indexStart = EMorphItem.Max; EMorphItem indexEnd = EMorphItem.Max; if (partInfo.ModelName.Contains("head")) { indexStart = EMorphItem.MinFace; indexEnd = EMorphItem.MaxFace; } else if (partInfo.ModelName.Contains("torso")) { indexStart = EMorphItem.MinUpperbody; indexEnd = EMorphItem.MaxUpperbody; } else if (partInfo.ModelName.Contains("legs")) { indexStart = EMorphItem.MinLowerbody; indexEnd = EMorphItem.MaxLowerbody; } else if (partInfo.ModelName.Contains("feet")) { indexStart = EMorphItem.MinFoot; indexEnd = EMorphItem.MaxFoot; } else if (partInfo.ModelName.Contains("hand")) { indexStart = EMorphItem.MinHand; indexEnd = EMorphItem.MaxHand; } if (indexStart != indexEnd) { _tmpWeightIdxs.Clear(); _tmpWeightVals.Clear(); for (int i = (int)indexStart; i < (int)indexEnd; i++) { float w = appearData.GetWeight((EMorphItem)i) * 100f; int index = i - (int)indexStart; if (w > 0f) { index = index * 2; } else { w = -w; index = index * 2 + 1; } if (smr.sharedMesh.blendShapeCount > index) { _tmpWeightIdxs.Add(index); _tmpWeightVals.Add(smr.GetBlendShapeWeight(index)); smr.SetBlendShapeWeight(index, w); } } Mesh msh = PeekTmpMesh(); smr.BakeMesh(msh); msh.boneWeights = smr.sharedMesh.boneWeights; msh.bindposes = smr.sharedMesh.bindposes; if (_tmpWeightIdxs.Count > 0) { for (int i = 0; i < _tmpWeightIdxs.Count; i++) { smr.SetBlendShapeWeight(_tmpWeightIdxs[i], _tmpWeightVals[i]); } } return(msh); } return(smr.sharedMesh); }
/// Check render on current gameObject. \n /// Initialise m_mesh reference. public void InitMesh() { Material[] materials; if (Application.isPlaying) { materials = renderer.materials; } else { materials = renderer.sharedMaterials; } if (m_initialShaders == null || (m_initialShaders.Length != materials.Length)) { m_initialShaders = new Shader[materials.Length]; for (int i = 0; i < m_initialShaders.Length; ++i) { m_initialShaders[i] = materials[i].shader; } } m_meshCopy = false; MeshFilter mf = GetComponent <MeshFilter> (); if (mf) { if (Application.isPlaying) { m_mesh = mf.mesh; } else { m_mesh = mf.sharedMesh; } } SkinnedMeshRenderer smr = GetComponent <SkinnedMeshRenderer>(); if (smr) { if (Application.isPlaying) { m_mesh = smr.sharedMesh; } else { m_mesh = Instantiate(smr.sharedMesh) as Mesh; smr.BakeMesh(m_mesh); m_meshCopy = true; } } /* * SpriteRenderer sr = GetComponent<SpriteRenderer>(); * if (sr) * { * if (Application.isPlaying) * m_mesh = sr.sprite.vertices; * else * { * m_mesh = Instantiate(smr.sharedMesh) as Mesh; * smr.BakeMesh(m_mesh); * m_meshCopy = true; * } * }*/ DisableMotion(); }
void Start() { Vector3 l_position = transform.position; Quaternion l_rotation = transform.rotation; Vector3 l_scale = transform.localScale; transform.position = Vector3.zero; transform.rotation = Quaternion.identity; transform.localScale = Vector3.one; List <Transform> bones = new List <Transform>(); List <BoneWeight> boneWeights = new List <BoneWeight>(); List <CombineInstance> combineInstances = new List <CombineInstance>(); int numSubmeshes = 0; for (int i = 0; i < spriteMeshInstances.Length; i++) { SpriteMeshInstance spriteMeshInstance = spriteMeshInstances[i]; if (spriteMeshInstance.cachedSkinnedRenderer) { numSubmeshes += spriteMeshInstance.mesh.subMeshCount; } } int[] meshIndex = new int[numSubmeshes]; int boneOffset = 0; for (int i = 0; i < m_SpriteMeshInstances.Length; ++i) { SpriteMeshInstance spriteMeshInstance = spriteMeshInstances[i]; if (spriteMeshInstance.cachedSkinnedRenderer) { SkinnedMeshRenderer skinnedMeshRenderer = spriteMeshInstance.cachedSkinnedRenderer; BoneWeight[] meshBoneweight = spriteMeshInstance.sharedMesh.boneWeights; // May want to modify this if the renderer shares bones as unnecessary bones will get added. for (int j = 0; j < meshBoneweight.Length; ++j) { BoneWeight bw = meshBoneweight[j]; BoneWeight bWeight = bw; bWeight.boneIndex0 += boneOffset; bWeight.boneIndex1 += boneOffset; bWeight.boneIndex2 += boneOffset; bWeight.boneIndex3 += boneOffset; boneWeights.Add(bWeight); } boneOffset += spriteMeshInstance.bones.Count; Transform[] meshBones = skinnedMeshRenderer.bones; for (int j = 0; j < meshBones.Length; j++) { Transform bone = meshBones[j]; bones.Add(bone); } CombineInstance combineInstance = new CombineInstance(); Mesh mesh = new Mesh(); skinnedMeshRenderer.BakeMesh(mesh); mesh.uv = spriteMeshInstance.spriteMesh.sprite.uv; combineInstance.mesh = mesh; meshIndex[i] = combineInstance.mesh.vertexCount; combineInstance.transform = skinnedMeshRenderer.localToWorldMatrix; combineInstances.Add(combineInstance); skinnedMeshRenderer.gameObject.SetActive(false); } } List <Matrix4x4> bindposes = new List <Matrix4x4>(); for (int b = 0; b < bones.Count; b++) { bindposes.Add(bones[b].worldToLocalMatrix * transform.worldToLocalMatrix); } SkinnedMeshRenderer combinedSkinnedRenderer = gameObject.AddComponent <SkinnedMeshRenderer>(); combinedSkinnedRenderer.sharedMesh = new Mesh(); combinedSkinnedRenderer.sharedMesh.CombineMeshes(combineInstances.ToArray(), true, true); combinedSkinnedRenderer.bones = bones.ToArray(); combinedSkinnedRenderer.sharedMesh.boneWeights = boneWeights.ToArray(); combinedSkinnedRenderer.sharedMesh.bindposes = bindposes.ToArray(); combinedSkinnedRenderer.sharedMesh.RecalculateBounds(); combinedSkinnedRenderer.materials = spriteMeshInstances[0].sharedMaterials; transform.position = l_position; transform.rotation = l_rotation; transform.localScale = l_scale; }
// Update is called once per frame void Update() { skinnedMeshRenderer.BakeMesh(mesh); }
public void AddDecal(Transform origin, Vector3 point, Material decalMaterial, float size = 0.2f, float rotation = 0, float normalFactor = 0, float offset = 0.1f, float depth = 1) { m_DecalCount++; if (m_DecalCount > m_MaxDecals) { Destroy(m_DecalList[0]); m_DecalList.RemoveAt(0); m_DecalCount--; } m_UVRot = rotation; m_NormalFactor = normalFactor; m_Depth = depth; m_Dir = origin.forward; // project from a close point from the hit point Matrix4x4 v = Matrix4x4.Inverse(Matrix4x4.TRS(point - m_Dir * offset, origin.rotation, new Vector3(1, 1, -1))); // project from origin (need a high depth value) // Matrix4x4 v = Matrix4x4.Inverse(Matrix4x4.TRS(origin.position, origin.rotation, new Vector3(1, 1, -1))); Matrix4x4 p = Matrix4x4.Ortho(-size, size, -size, size, 0.0001f, depth); m_VP = p * v; // get decalmesh Mesh decalMesh = Mesh.Instantiate(m_SkiMesh.sharedMesh); // get a snapshot of the mesh to test against Mesh bakeMesh = new Mesh(); m_SkiMesh.BakeMesh(bakeMesh); // get vertices that are going to be tested m_Vertices = bakeMesh.vertices; // uvs Vector2[] uvs = decalMesh.uv; // process each submesh for (int subMesh = 0; subMesh < decalMesh.subMeshCount; subMesh++) { List <int> triangleList = new List <int>(); int[] triangles = decalMesh.GetTriangles(subMesh); // check each triangle against view Frustum for (int i = 0; i < triangles.Length; i += 3) { if (isInsideFrustum(triangles[i], triangles[i + 1], triangles[i + 2], ref uvs)) { triangleList.Add(triangles[i]); triangleList.Add(triangles[i + 1]); triangleList.Add(triangles[i + 2]); } } if (triangleList.Count < 3) { continue; } decalMesh.SetTriangles(triangleList.ToArray(), subMesh); } decalMesh.uv = uvs; // create go GameObject decalGO = new GameObject("decal"); decalGO.transform.parent = m_SkiMesh.transform; // create skinned mesh SkinnedMeshRenderer decalSkinRend = decalGO.AddComponent <SkinnedMeshRenderer>(); decalSkinRend.quality = m_DecalQuality; decalSkinRend.shadowCastingMode = ShadowCastingMode.Off; decalSkinRend.sharedMesh = decalMesh; decalSkinRend.bones = m_SkiMesh.bones; decalSkinRend.rootBone = m_SkiMesh.rootBone; decalSkinRend.sharedMaterial = decalMaterial; m_DecalList.Add(decalGO); Destroy(bakeMesh); }
void AddClone() { List <CombineInstance> comInsts = new List <CombineInstance>(); SkinnedMeshRenderer[] renderers = GetComponentsInChildren <SkinnedMeshRenderer>(); for (int i = 0; i < renderers.Length; ++i) { SkinnedMeshRenderer renderer = renderers[i]; if (!renderer.enabled || renderer.sharedMesh == null) { continue; } Mesh mesh = new Mesh(); renderer.BakeMesh(mesh); for (int j = renderer.sharedMesh.subMeshCount - 1; j >= 0; --j) { CombineInstance inst = new CombineInstance() { mesh = mesh, subMeshIndex = j, transform = renderers[i].transform.localToWorldMatrix }; comInsts.Add(inst); } } if (!mOnlySkinnedMesh) { MeshFilter[] filters = GetComponentsInChildren <MeshFilter>(); for (int i = 0; i < filters.Length; ++i) { MeshFilter filter = filters[i]; if (filter.sharedMesh == null) { continue; } MeshRenderer renderer = filter.GetComponent <MeshRenderer>(); if (renderer == null || !renderer.enabled) { continue; } for (int j = filter.sharedMesh.subMeshCount - 1; j >= 0; --j) { CombineInstance inst = new CombineInstance() { mesh = filter.sharedMesh, subMeshIndex = j, transform = renderers[i].transform.localToWorldMatrix }; comInsts.Add(inst); } } } if (comInsts.Count <= 0) { return; } Mesh comMesh = new Mesh(); comMesh.CombineMeshes(comInsts.ToArray(), true, true); CloneInfo clone = new CloneInfo() { mMesh = comMesh, mProp = new MaterialPropertyBlock(), mCreateTime = Time.realtimeSinceStartup }; mCloneList.Add(clone); if (mCloneList.Count > mMaxNum) { RemoveClone(); } }
void getSnapshot() { SkinnedMR.BakeMesh(staticMesh); }
/// <summary> /// Gets all the meshes and outputs to a string (even grabbing the child of each gameObject if includeChildren is true /// </summary> /// <returns>The mesh to string.</returns> /// <param name="gameObj">GameObject Parent.</param> /// <param name="materials">Every Material in the parent that can be accessed.</param> /// <param name="objects">The StringBuidler to create objects for the FBX file.</param> /// <param name="connections">The StringBuidler to create connections for the FBX file.</param> /// <param name="parentObject">Parent object, if left null this is the top parent.</param> /// <param name="parentModelId">Parent model id, 0 if top parent.</param> public static long GetMeshToString(GameObject gameObj, Material[] materials, ref StringBuilder objects, ref StringBuilder connections, GameObject parentObject = null, long parentModelId = 0, bool includeChildren = true, bool disableRotationAndScale = false) { StringBuilder tempObjectSb = new StringBuilder(); StringBuilder tempConnectionsSb = new StringBuilder(); long geometryId = GetRandomFBXId(); long modelId = GetRandomFBXId(); // Sees if there is a skinned mesh renderer or regular mesh. Skinned meshes are baked into whatever pose they have and are exported MeshFilter filter = gameObj.GetComponent <MeshFilter>(); SkinnedMeshRenderer skinnedMesh = gameObj.GetComponent <SkinnedMeshRenderer>(); Mesh meshToExport = new Mesh(); if (filter != null) { meshToExport = filter.sharedMesh; } else if (skinnedMesh != null) { meshToExport = new Mesh(); skinnedMesh.BakeMesh(meshToExport); } if (meshToExport == null) { Debug.LogError("Couldn't find a filter name"); } string meshName = gameObj.name; // A NULL parent means that the gameObject is at the top string isMesh = "Null"; if (meshToExport != null) { meshName = meshToExport.name; isMesh = "Mesh"; } if (meshName == "") { meshName = "Skinned Mesh " + Random.Range(0, 1000000); } if (parentModelId == 0) { tempConnectionsSb.AppendLine("\t;Model::" + meshName + ", Model::RootNode"); } else { tempConnectionsSb.AppendLine("\t;Model::" + meshName + ", Model::USING PARENT"); } tempConnectionsSb.AppendLine("\tC: \"OO\"," + modelId + "," + parentModelId); tempConnectionsSb.AppendLine(); tempObjectSb.AppendLine("\tModel: " + modelId + ", \"Model::" + gameObj.name + "\", \"" + isMesh + "\" {"); tempObjectSb.AppendLine("\t\tVersion: 232"); tempObjectSb.AppendLine("\t\tProperties70: {"); tempObjectSb.AppendLine("\t\t\tP: \"RotationOrder\", \"enum\", \"\", \"\",4"); tempObjectSb.AppendLine("\t\t\tP: \"RotationActive\", \"bool\", \"\", \"\",1"); tempObjectSb.AppendLine("\t\t\tP: \"InheritType\", \"enum\", \"\", \"\",1"); tempObjectSb.AppendLine("\t\t\tP: \"ScalingMax\", \"Vector3D\", \"Vector\", \"\",0,0,0"); tempObjectSb.AppendLine("\t\t\tP: \"DefaultAttributeIndex\", \"int\", \"Integer\", \"\",0"); // ===== Local Translation Offset ========= Vector3 position = gameObj.transform.localPosition; tempObjectSb.Append("\t\t\tP: \"Lcl Translation\", \"Lcl Translation\", \"\", \"A+\","); // Append the X Y Z coords to the system tempObjectSb.AppendFormat("{0},{1},{2}", position.x * -1, position.y, position.z); tempObjectSb.AppendLine(); // Rotates the object correctly from Unity space if (disableRotationAndScale == false) { Vector3 localRotation = gameObj.transform.localEulerAngles; tempObjectSb.AppendFormat("\t\t\tP: \"Lcl Rotation\", \"Lcl Rotation\", \"\", \"A+\",{0},{1},{2}", localRotation.x, localRotation.y * -1, -1 * localRotation.z); } else { tempObjectSb.AppendFormat("\t\t\tP: \"Lcl Rotation\", \"Lcl Rotation\", \"\", \"A+\",{0},{1},{2}", 0, 0, 0); } tempObjectSb.AppendLine(); // Adds the local scale of this object if (disableRotationAndScale == false) { Vector3 localScale = gameObj.transform.localScale; tempObjectSb.AppendFormat("\t\t\tP: \"Lcl Scaling\", \"Lcl Scaling\", \"\", \"A\",{0},{1},{2}", localScale.x, localScale.y, localScale.z); } else { tempObjectSb.AppendFormat("\t\t\tP: \"Lcl Scaling\", \"Lcl Scaling\", \"\", \"A\",{0},{1},{2}", 1, 1, 1); } tempObjectSb.AppendLine(); tempObjectSb.AppendLine("\t\t\tP: \"currentUVSet\", \"KString\", \"\", \"U\", \"map1\""); tempObjectSb.AppendLine("\t\t}"); tempObjectSb.AppendLine("\t\tShading: T"); tempObjectSb.AppendLine("\t\tCulling: \"CullingOff\""); tempObjectSb.AppendLine("\t}"); // Adds in geometry if it exists, if it it does not exist, this is a empty gameObject file and skips over this if (meshToExport != null) { Mesh mesh = meshToExport; // ================================= // General Geometry Info // ================================= // Generate the geometry information for the mesh created tempObjectSb.AppendLine("\tGeometry: " + geometryId + ", \"Geometry::\", \"Mesh\" {"); // ===== WRITE THE VERTICIES ===== Vector3[] verticies = mesh.vertices; int vertCount = mesh.vertexCount * 3; // <= because the list of points is just a list of comma seperated values, we need to multiply by three tempObjectSb.AppendLine("\t\tVertices: *" + vertCount + " {"); tempObjectSb.Append("\t\t\ta: "); for (int i = 0; i < verticies.Length; i++) { if (i > 0) { tempObjectSb.Append(","); } // Points in the verticies. We also reverse the x value because Unity has a reverse X coordinate tempObjectSb.AppendFormat("{0},{1},{2}", verticies[i].x * -1, verticies[i].y, verticies[i].z); } tempObjectSb.AppendLine(); tempObjectSb.AppendLine("\t\t} "); // ======= WRITE THE TRIANGLES ======== int triangleCount = mesh.triangles.Length; int[] triangles = mesh.triangles; tempObjectSb.AppendLine("\t\tPolygonVertexIndex: *" + triangleCount + " {"); // Write triangle indexes tempObjectSb.Append("\t\t\ta: "); for (int i = 0; i < triangleCount; i += 3) { if (i > 0) { tempObjectSb.Append(","); } // To get the correct normals, must rewind the triangles since we flipped the x direction tempObjectSb.AppendFormat("{0},{1},{2}", triangles[i], triangles[i + 2], (triangles[i + 1] * -1) - 1); // <= Tells the poly is ended } tempObjectSb.AppendLine(); tempObjectSb.AppendLine("\t\t} "); tempObjectSb.AppendLine("\t\tGeometryVersion: 124"); tempObjectSb.AppendLine("\t\tLayerElementNormal: 0 {"); tempObjectSb.AppendLine("\t\t\tVersion: 101"); tempObjectSb.AppendLine("\t\t\tName: \"\""); tempObjectSb.AppendLine("\t\t\tMappingInformationType: \"ByPolygonVertex\""); tempObjectSb.AppendLine("\t\t\tReferenceInformationType: \"Direct\""); // ===== WRITE THE NORMALS ========== Vector3[] normals = mesh.normals; tempObjectSb.AppendLine("\t\t\tNormals: *" + (triangleCount * 3) + " {"); tempObjectSb.Append("\t\t\t\ta: "); for (int i = 0; i < triangleCount; i += 3) { if (i > 0) { tempObjectSb.Append(","); } // To get the correct normals, must rewind the normal triangles like the triangles above since x was flipped Vector3 newNormal = normals[triangles[i]]; tempObjectSb.AppendFormat("{0},{1},{2},", newNormal.x * -1, // Switch normal as is tradition newNormal.y, newNormal.z); newNormal = normals[triangles[i + 2]]; tempObjectSb.AppendFormat("{0},{1},{2},", newNormal.x * -1, // Switch normal as is tradition newNormal.y, newNormal.z); newNormal = normals[triangles[i + 1]]; tempObjectSb.AppendFormat("{0},{1},{2}", newNormal.x * -1, // Switch normal as is tradition newNormal.y, newNormal.z); } tempObjectSb.AppendLine(); tempObjectSb.AppendLine("\t\t\t}"); tempObjectSb.AppendLine("\t\t}"); // ===== WRITE THE COLORS ===== bool containsColors = mesh.colors.Length == verticies.Length; if (containsColors) { Color[] colors = mesh.colors; Dictionary <Color, int> colorTable = new Dictionary <Color, int>(); // reducing amount of data by only keeping unique colors. int idx = 0; // build index table of all the different colors present in the mesh for (int i = 0; i < colors.Length; i++) { if (!colorTable.ContainsKey(colors[i])) { colorTable[colors[i]] = idx; idx++; } } tempObjectSb.AppendLine("\t\tLayerElementColor: 0 {"); tempObjectSb.AppendLine("\t\t\tVersion: 101"); tempObjectSb.AppendLine("\t\t\tName: \"Col\""); tempObjectSb.AppendLine("\t\t\tMappingInformationType: \"ByPolygonVertex\""); tempObjectSb.AppendLine("\t\t\tReferenceInformationType: \"IndexToDirect\""); tempObjectSb.AppendLine("\t\t\tColors: *" + colorTable.Count * 4 + " {"); tempObjectSb.Append("\t\t\t\ta: "); bool first = true; foreach (KeyValuePair <Color, int> color in colorTable) { if (!first) { tempObjectSb.Append(","); } tempObjectSb.AppendFormat("{0},{1},{2},{3}", color.Key.r, color.Key.g, color.Key.b, color.Key.a); first = false; } tempObjectSb.AppendLine(); tempObjectSb.AppendLine("\t\t\t\t}"); // Color index tempObjectSb.AppendLine("\t\t\tColorIndex: *" + triangles.Length + " {"); tempObjectSb.Append("\t\t\t\ta: "); for (int i = 0; i < triangles.Length; i += 3) { if (i > 0) { tempObjectSb.Append(","); } // Triangles need to be fliped for the x flip int index1 = triangles[i]; int index2 = triangles[i + 2]; int index3 = triangles[i + 1]; // Find the color index related to that vertice index index1 = colorTable[colors[index1]]; index2 = colorTable[colors[index2]]; index3 = colorTable[colors[index3]]; tempObjectSb.AppendFormat("{0},{1},{2}", index1, index2, index3); } tempObjectSb.AppendLine(); tempObjectSb.AppendLine("\t\t\t}"); tempObjectSb.AppendLine("\t\t}"); } else { Debug.LogWarning("Mesh contains " + mesh.vertices.Length + " vertices for " + mesh.colors.Length + " colors. Skip color export"); } // ================ UV CREATION ========================= // -- UV 1 Creation int uvLength = mesh.uv.Length; Vector2[] uvs = mesh.uv; tempObjectSb.AppendLine("\t\tLayerElementUV: 0 {"); // the Zero here is for the first UV map tempObjectSb.AppendLine("\t\t\tVersion: 101"); tempObjectSb.AppendLine("\t\t\tName: \"map1\""); tempObjectSb.AppendLine("\t\t\tMappingInformationType: \"ByPolygonVertex\""); tempObjectSb.AppendLine("\t\t\tReferenceInformationType: \"IndexToDirect\""); tempObjectSb.AppendLine("\t\t\tUV: *" + uvLength * 2 + " {"); tempObjectSb.Append("\t\t\t\ta: "); for (int i = 0; i < uvLength; i++) { if (i > 0) { tempObjectSb.Append(","); } tempObjectSb.AppendFormat("{0},{1}", uvs[i].x, uvs[i].y); } tempObjectSb.AppendLine(); tempObjectSb.AppendLine("\t\t\t\t}"); // UV tile index coords tempObjectSb.AppendLine("\t\t\tUVIndex: *" + triangleCount + " {"); tempObjectSb.Append("\t\t\t\ta: "); for (int i = 0; i < triangleCount; i += 3) { if (i > 0) { tempObjectSb.Append(","); } // Triangles need to be fliped for the x flip int index1 = triangles[i]; int index2 = triangles[i + 2]; int index3 = triangles[i + 1]; tempObjectSb.AppendFormat("{0},{1},{2}", index1, index2, index3); } tempObjectSb.AppendLine(); tempObjectSb.AppendLine("\t\t\t}"); tempObjectSb.AppendLine("\t\t}"); // -- UV 2 Creation // TODO: Add UV2 Creation here // -- Smoothing // TODO: Smoothing doesn't seem to do anything when importing. This maybe should be added. -KBH // ============ MATERIALS ============= tempObjectSb.AppendLine("\t\tLayerElementMaterial: 0 {"); tempObjectSb.AppendLine("\t\t\tVersion: 101"); tempObjectSb.AppendLine("\t\t\tName: \"\""); tempObjectSb.AppendLine("\t\t\tMappingInformationType: \"ByPolygon\""); tempObjectSb.AppendLine("\t\t\tReferenceInformationType: \"IndexToDirect\""); int totalFaceCount = 0; // So by polygon means that we need 1/3rd of how many indicies we wrote. int numberOfSubmeshes = mesh.subMeshCount; StringBuilder submeshesSb = new StringBuilder(); // For just one submesh, we set them all to zero if (numberOfSubmeshes == 1) { int numFaces = triangles.Length / 3; for (int i = 0; i < numFaces; i++) { submeshesSb.Append("0,"); totalFaceCount++; } } else { List <int[]> allSubmeshes = new List <int[]>(); // Load all submeshes into a space for (int i = 0; i < numberOfSubmeshes; i++) { allSubmeshes.Add(mesh.GetIndices(i)); } // TODO: Optimize this search pattern for (int i = 0; i < triangles.Length; i += 3) { for (int subMeshIndex = 0; subMeshIndex < allSubmeshes.Count; subMeshIndex++) { bool breaker = false; for (int n = 0; n < allSubmeshes[subMeshIndex].Length; n += 3) { if (triangles[i] == allSubmeshes[subMeshIndex][n] && triangles[i + 1] == allSubmeshes[subMeshIndex][n + 1] && triangles[i + 2] == allSubmeshes[subMeshIndex][n + 2]) { submeshesSb.Append(subMeshIndex.ToString()); submeshesSb.Append(","); totalFaceCount++; break; } if (breaker) { break; } } } } } tempObjectSb.AppendLine("\t\t\tMaterials: *" + totalFaceCount + " {"); tempObjectSb.Append("\t\t\t\ta: "); tempObjectSb.AppendLine(submeshesSb.ToString()); tempObjectSb.AppendLine("\t\t\t} "); tempObjectSb.AppendLine("\t\t}"); // ============= INFORMS WHAT TYPE OF LATER ELEMENTS ARE IN THIS GEOMETRY ================= tempObjectSb.AppendLine("\t\tLayer: 0 {"); tempObjectSb.AppendLine("\t\t\tVersion: 100"); tempObjectSb.AppendLine("\t\t\tLayerElement: {"); tempObjectSb.AppendLine("\t\t\t\tType: \"LayerElementNormal\""); tempObjectSb.AppendLine("\t\t\t\tTypedIndex: 0"); tempObjectSb.AppendLine("\t\t\t}"); tempObjectSb.AppendLine("\t\t\tLayerElement: {"); tempObjectSb.AppendLine("\t\t\t\tType: \"LayerElementMaterial\""); tempObjectSb.AppendLine("\t\t\t\tTypedIndex: 0"); tempObjectSb.AppendLine("\t\t\t}"); tempObjectSb.AppendLine("\t\t\tLayerElement: {"); tempObjectSb.AppendLine("\t\t\t\tType: \"LayerElementTexture\""); tempObjectSb.AppendLine("\t\t\t\tTypedIndex: 0"); tempObjectSb.AppendLine("\t\t\t}"); if (containsColors) { tempObjectSb.AppendLine("\t\t\tLayerElement: {"); tempObjectSb.AppendLine("\t\t\t\tType: \"LayerElementColor\""); tempObjectSb.AppendLine("\t\t\t\tTypedIndex: 0"); tempObjectSb.AppendLine("\t\t\t}"); } tempObjectSb.AppendLine("\t\t\tLayerElement: {"); tempObjectSb.AppendLine("\t\t\t\tType: \"LayerElementUV\""); tempObjectSb.AppendLine("\t\t\t\tTypedIndex: 0"); tempObjectSb.AppendLine("\t\t\t}"); // TODO: Here we would add UV layer 1 for ambient occlusion UV file // tempObjectSb.AppendLine("\t\t\tLayerElement: {"); // tempObjectSb.AppendLine("\t\t\t\tType: \"LayerElementUV\""); // tempObjectSb.AppendLine("\t\t\t\tTypedIndex: 1"); // tempObjectSb.AppendLine("\t\t\t}"); tempObjectSb.AppendLine("\t\t}"); tempObjectSb.AppendLine("\t}"); // Add the connection for the model to the geometry so it is attached the right mesh tempConnectionsSb.AppendLine("\t;Geometry::, Model::" + mesh.name); tempConnectionsSb.AppendLine("\tC: \"OO\"," + geometryId + "," + modelId); tempConnectionsSb.AppendLine(); // Add the connection of all the materials in order of submesh MeshRenderer meshRenderer = gameObj.GetComponent <MeshRenderer>(); if (meshRenderer != null) { Material[] allMaterialsInThisMesh = meshRenderer.sharedMaterials; for (int i = 0; i < allMaterialsInThisMesh.Length; i++) { Material mat = allMaterialsInThisMesh[i]; int referenceId = Mathf.Abs(mat.GetInstanceID()); if (mat == null) { Debug.LogError("ERROR: the game object " + gameObj.name + " has an empty material on it. This will export problematic files. Please fix and reexport"); continue; } tempConnectionsSb.AppendLine("\t;Material::" + mat.name + ", Model::" + mesh.name); tempConnectionsSb.AppendLine("\tC: \"OO\"," + referenceId + "," + modelId); tempConnectionsSb.AppendLine(); } } } if (includeChildren == true) { // Recursively add all the other objects to the string that has been built. for (int i = 0; i < gameObj.transform.childCount; i++) { GameObject childObject = gameObj.transform.GetChild(i).gameObject; HiFiFBXUnityMeshGetter.GetMeshToString(childObject, materials, ref tempObjectSb, ref tempConnectionsSb, gameObj, modelId); } } objects.Append(tempObjectSb.ToString()); connections.Append(tempConnectionsSb.ToString()); return(modelId); }
internal void Reskin2(Ragdoll ragdoll) { Matrix4x4[] bindposes = new Matrix4x4[RagdollTemplate.instance.bindposes.Length]; Matrix4x4 localToWorldMatrix = base.transform.localToWorldMatrix; for (int i = 0; i < bindposes.Length; i++) { bindposes[i] = RagdollTemplate.instance.bindposes[i] * localToWorldMatrix; } Mesh mesh = null; SkinnedMeshRenderer skinnedMeshRenderer = GetComponent <SkinnedMeshRenderer>(); if ((bool)skinnedMeshRenderer) { mesh = (meshToDestroy = new Mesh()); skinnedMeshRenderer.BakeMesh(mesh); originalRenderer = skinnedMeshRenderer; reskinnedRenderer = skinnedMeshRenderer; } else { MeshFilter component = GetComponent <MeshFilter>(); MeshRenderer component2 = component.GetComponent <MeshRenderer>(); if (component == null || component2 == null) { Debug.LogError("Trying to resking gameobject without mesh renderer", this); return; } component2.enabled = false; originalRenderer = component2; mesh = (meshToDestroy = new Mesh()); mesh.vertices = component.sharedMesh.vertices; mesh.triangles = component.sharedMesh.triangles; mesh.uv = component.sharedMesh.uv; mesh.uv2 = component.sharedMesh.uv2; mesh.normals = component.sharedMesh.normals; GameObject gameObject = new GameObject(base.name + "Skinned"); gameObject.transform.SetParent(base.transform, worldPositionStays: false); skinnedMeshRenderer = gameObject.AddComponent <SkinnedMeshRenderer>(); skinnedMeshRenderer.sharedMaterials = component2.sharedMaterials; reskinnedRenderer = skinnedMeshRenderer; } float realtimeSinceStartup = Time.realtimeSinceStartup; Vector3[] vertices = mesh.vertices; Matrix4x4 localToWorldMatrix2 = base.transform.localToWorldMatrix; for (int j = 0; j < vertices.Length; j++) { vertices[j] = localToWorldMatrix2.MultiplyPoint3x4(vertices[j]); } BoneWeight[] array = new BoneWeight[vertices.Length]; for (int k = 0; k < array.Length; k++) { array[k] = RagdollTemplate.instance.Map(vertices[k]); } Transform[] bones = ragdoll.bones; if (App.state != AppSate.Customize) { Override(ragdoll, vertices, array, ref bones, ref bindposes, localToWorldMatrix); } mesh.boneWeights = array; skinnedMeshRenderer.sharedMesh = mesh; mesh.bindposes = bindposes; skinnedMeshRenderer.bones = bones; skinnedMeshRenderer.rootBone = bones[0]; mesh.RecalculateBounds(); }