/// <summary> /// 设置anim_ins鱼类的效果 /// </summary> /// <param name="go"></param> /// <param name="val"></param> public void SetInnerEffectState(GameObject go, int val) { AnimationInstancing.LodInfo[] lodinfo = go.GetComponentInChildren <AnimationInstancing>().lodInfo; for (int i = 0; i < lodinfo.Length; i++) { AnimationInstancing.LodInfo lod = lodinfo[i]; for (int h = 0; h < lod.vertexCacheList.Length; h++) { VertexCache cache = lod.vertexCacheList[h]; foreach (var block in cache.instanceBlockList) { block.Value.instanceData.isshowInner = val; } } } }
// alias is to use for attachment, it should be a bone name public void AddMeshVertex(string prefabName, AnimationInstancing.LodInfo[] lodInfo, Transform[] bones, List <Matrix4x4> bindPose, int bonePerVertex, string alias = null) { UnityEngine.Profiling.Profiler.BeginSample("AddMeshVertex()"); for (int x = 0; x != lodInfo.Length; ++x) { AnimationInstancing.LodInfo lod = lodInfo[x]; for (int i = 0; i != lod.skinnedMeshRenderer.Length; ++i) { Mesh m = lod.skinnedMeshRenderer[i].sharedMesh; if (m == null) { continue; } int nameCode = lod.skinnedMeshRenderer[i].name.GetHashCode(); int identify = GetIdentify(lod.skinnedMeshRenderer[i].sharedMaterials); VertexCache cache = null; if (vertexCachePool.TryGetValue(nameCode, out cache)) { MaterialBlock block = null; if (!cache.instanceBlockList.TryGetValue(identify, out block)) { block = CreateBlock(cache, lod.skinnedMeshRenderer[i].sharedMaterials); cache.instanceBlockList.Add(identify, block); } lod.vertexCacheList[i] = cache; lod.materialBlockList[i] = block; continue; } VertexCache vertexCache = CreateVertexCache(prefabName, nameCode, 0, m); vertexCache.bindPose = bindPose.ToArray(); MaterialBlock matBlock = CreateBlock(vertexCache, lod.skinnedMeshRenderer[i].sharedMaterials); vertexCache.instanceBlockList.Add(identify, matBlock); SetupVertexCache(vertexCache, matBlock, lod.skinnedMeshRenderer[i], bones, bonePerVertex); lod.vertexCacheList[i] = vertexCache; lod.materialBlockList[i] = matBlock; } for (int i = 0, j = lod.skinnedMeshRenderer.Length; i != lod.meshRenderer.Length; ++i, ++j) { Mesh m = lod.meshFilter[i].sharedMesh; if (m == null) { continue; } int renderName = lod.meshRenderer[i].name.GetHashCode(); int aliasName = (alias != null ? alias.GetHashCode() : 0); int identify = GetIdentify(lod.meshRenderer[i].sharedMaterials); VertexCache cache = null; if (vertexCachePool.TryGetValue(renderName + aliasName, out cache)) { MaterialBlock block = null; if (!cache.instanceBlockList.TryGetValue(identify, out block)) { block = CreateBlock(cache, lod.meshRenderer[i].sharedMaterials); cache.instanceBlockList.Add(identify, block); } lod.vertexCacheList[j] = cache; lod.materialBlockList[j] = block; continue; } VertexCache vertexCache = CreateVertexCache(prefabName, renderName, aliasName, m); if (bindPose != null) { vertexCache.bindPose = bindPose.ToArray(); } MaterialBlock matBlock = CreateBlock(vertexCache, lod.meshRenderer[i].sharedMaterials); vertexCache.instanceBlockList.Add(identify, matBlock); SetupVertexCache(vertexCache, matBlock, lod.meshRenderer[i], m, bones, bonePerVertex); lod.vertexCacheList[lod.skinnedMeshRenderer.Length + i] = vertexCache; lod.materialBlockList[lod.skinnedMeshRenderer.Length + i] = matBlock; } } UnityEngine.Profiling.Profiler.EndSample(); }
void ApplyBoneMatrix() { Vector3 cameraPosition = cameraTransform.position; for (int i = 0; i != aniInstancingList.Count; ++i) { AnimationInstancing instance = aniInstancingList[i]; if (!instance.IsPlaying()) { continue; } if (instance.aniIndex < 0 && instance.parentInstance == null) { continue; } if (instance.applyRootMotion) { ApplyRootMotion(instance); } instance.UpdateAnimation(); instance.boundingSpere.position = instance.transform.position; boundingSphere[i] = instance.boundingSpere; if (!instance.visible) { continue; } instance.UpdateLod(cameraPosition); AnimationInstancing.LodInfo lod = instance.lodInfo[instance.lodLevel]; int aniTextureIndex = -1; if (instance.parentInstance != null) { aniTextureIndex = instance.parentInstance.aniTextureIndex; } else { aniTextureIndex = instance.aniTextureIndex; } for (int j = 0; j != lod.vertexCacheList.Length; ++j) { VertexCache cache = lod.vertexCacheList[j]; MaterialBlock block = lod.materialBlockList[j]; Debug.Assert(block != null); int packageIndex = block.runtimePackageIndex[aniTextureIndex]; Debug.Assert(packageIndex < block.packageList[aniTextureIndex].Count); InstancingPackage package = block.packageList[aniTextureIndex][packageIndex]; if (package.instancingCount + 1 > instancingPackageSize) { ++block.runtimePackageIndex[aniTextureIndex]; packageIndex = block.runtimePackageIndex[aniTextureIndex]; if (packageIndex >= block.packageList[aniTextureIndex].Count) { InstancingPackage newPackage = CreatePackage(block.instanceData, cache.mesh, cache.materials, aniTextureIndex); block.packageList[aniTextureIndex].Add(newPackage); PreparePackageMaterial(newPackage, cache, aniTextureIndex); newPackage.instancingCount = 1; } block.packageList[aniTextureIndex][packageIndex].instancingCount = 1; } else { ++package.instancingCount; } { VertexCache vertexCache = cache; InstanceData data = block.instanceData; int index = block.runtimePackageIndex[aniTextureIndex]; InstancingPackage pkg = block.packageList[aniTextureIndex][index]; int count = pkg.instancingCount - 1; if (count >= 0) { Matrix4x4 worldMat = instance.worldTransform.localToWorldMatrix; Matrix4x4[] arrayMat = data.worldMatrix[aniTextureIndex][index]; arrayMat[count].m00 = worldMat.m00; arrayMat[count].m01 = worldMat.m01; arrayMat[count].m02 = worldMat.m02; arrayMat[count].m03 = worldMat.m03; arrayMat[count].m10 = worldMat.m10; arrayMat[count].m11 = worldMat.m11; arrayMat[count].m12 = worldMat.m12; arrayMat[count].m13 = worldMat.m13; arrayMat[count].m20 = worldMat.m20; arrayMat[count].m21 = worldMat.m21; arrayMat[count].m22 = worldMat.m22; arrayMat[count].m23 = worldMat.m23; arrayMat[count].m30 = worldMat.m30; arrayMat[count].m31 = worldMat.m31; arrayMat[count].m32 = worldMat.m32; arrayMat[count].m33 = worldMat.m33; float frameIndex = 0, preFrameIndex = -1, transition = 0f; if (instance.parentInstance != null) { frameIndex = instance.parentInstance.aniInfo[instance.parentInstance.aniIndex].animationIndex + instance.parentInstance.curFrame; if (instance.parentInstance.preAniIndex >= 0) { preFrameIndex = instance.parentInstance.aniInfo[instance.parentInstance.preAniIndex].animationIndex + instance.parentInstance.preAniFrame; } transition = instance.parentInstance.transitionProgress; } else { frameIndex = instance.aniInfo[instance.aniIndex].animationIndex + instance.curFrame; if (instance.preAniIndex >= 0) { preFrameIndex = instance.aniInfo[instance.preAniIndex].animationIndex + instance.preAniFrame; } transition = instance.transitionProgress; } data.frameIndex[aniTextureIndex][index][count] = frameIndex; data.preFrameIndex[aniTextureIndex][index][count] = preFrameIndex; data.transitionProgress[aniTextureIndex][index][count] = transition; } } } } }
// alias is to use for attachment, it's usually a bone name public void AddMeshVertex(string prefabName, AnimationInstancing.LodInfo[] lodInfo, Transform[] bones, List <Matrix4x4> bindPose, int bonePerVertex, string alias = null) { UnityEngine.Profiling.Profiler.BeginSample("AddMeshVertex()"); for (int x = 0; x != lodInfo.Length; ++x) { AnimationInstancing.LodInfo lod = lodInfo[x]; for (int i = 0; i != lod.skinnedMeshRenderer.Length; ++i) { Mesh m = lod.skinnedMeshRenderer[i].sharedMesh; if (m == null) { continue; } int nameCode = lod.skinnedMeshRenderer[i].name.GetHashCode(); VertexCache cache = null; if (vertexCachePool.TryGetValue(nameCode, out cache)) { lod.vertexCacheList[i] = cache; #if !USE_CONSTANT_BUFFER ++cache.instancingCount; #endif continue; } VertexCache vertexCache = CreateVertexCache(prefabName, nameCode, 0, m); vertexCache.bindPose = bindPose.ToArray(); lod.vertexCacheList[i] = vertexCache; SetupVertexCache(vertexCache, lod.skinnedMeshRenderer[i], bones, bonePerVertex); } for (int i = 0, j = lod.skinnedMeshRenderer.Length; i != lod.meshRenderer.Length; ++i, ++j) { Mesh m = lod.meshFilter[i].sharedMesh; if (m == null) { continue; } int renderName = lod.meshRenderer[i].name.GetHashCode(); int aliasName = (alias != null ? alias.GetHashCode() : 0); VertexCache cache = null; if (vertexCachePool.TryGetValue(renderName + aliasName, out cache)) { lod.vertexCacheList[j] = cache; #if !USE_CONSTANT_BUFFER ++cache.instancingCount; #endif continue; } VertexCache vertexCache = CreateVertexCache(prefabName, renderName, aliasName, m); if (bindPose != null) { vertexCache.bindPose = bindPose.ToArray(); } lod.vertexCacheList[lod.skinnedMeshRenderer.Length + i] = vertexCache; SetupVertexCache(vertexCache, lod.meshRenderer[i], m, bones, bonePerVertex); } #if !USE_CONSTANT_BUFFER foreach (var obj in vertexCachePool) { VertexCache vertexCache = obj.Value; for (int j = 0; j != vertexCache.subMeshCount; ++j) { Material material = vertexCache.instanceMaterial[j]; material.SetBuffer("buf_Vertex", vertexCache.bufVertex); } } #endif } UnityEngine.Profiling.Profiler.EndSample(); }
void ApplyBoneMatrix() { Vector3 cameraPosition = cameraTransform.position; for (int i = 0; i != aniInstancingList.Count; ++i) { AnimationInstancing instance = aniInstancingList[i]; if (!instance.IsPlaying()) { continue; } if (instance.aniIndex < 0 && instance.parentInstance == null) { continue; } instance.UpdateAnimation(); if (!instance.visible) { continue; } if (instance.applyRootMotion) { ApplyRootMotion(instance); } instance.UpdateLod(cameraPosition); AnimationInstancing.LodInfo lod = instance.lodInfo[instance.lodLevel]; #if USE_CONSTANT_BUFFER VertexCache vertexCache = lod.vertexCacheList[0]; InstanceData data = vertexCache.instanceData; int aniTextureIndex = -1; if (instance.parentInstance != null) { aniTextureIndex = instance.parentInstance.aniTextureIndex; } else { aniTextureIndex = instance.aniTextureIndex; } int index = vertexCache.runtimePackageIndex[aniTextureIndex]; VertexCache.InstancingPackage pkg = vertexCache.packageList[aniTextureIndex][index]; int count = pkg.instancingCount - 1; if (count >= 0) { Matrix4x4 worldMat = instance.worldTransform.localToWorldMatrix; Matrix4x4[] arrayMat = data.worldMatrix[aniTextureIndex][index]; arrayMat[count].m00 = worldMat.m00; arrayMat[count].m01 = worldMat.m01; arrayMat[count].m02 = worldMat.m02; arrayMat[count].m03 = worldMat.m03; arrayMat[count].m10 = worldMat.m10; arrayMat[count].m11 = worldMat.m11; arrayMat[count].m12 = worldMat.m12; arrayMat[count].m13 = worldMat.m13; arrayMat[count].m20 = worldMat.m20; arrayMat[count].m21 = worldMat.m21; arrayMat[count].m22 = worldMat.m22; arrayMat[count].m23 = worldMat.m23; arrayMat[count].m30 = worldMat.m30; arrayMat[count].m31 = worldMat.m31; arrayMat[count].m32 = worldMat.m32; arrayMat[count].m33 = worldMat.m33; float frameIndex = 0; if (instance.parentInstance != null) { frameIndex = instance.parentInstance.aniInfo[instance.parentInstance.aniIndex].animationIndex + instance.parentInstance.curFrame; } else { frameIndex = instance.aniInfo[instance.aniIndex].animationIndex + instance.curFrame; } data.frameIndex[aniTextureIndex][index][count] = frameIndex; instance.boundingSpere.position.x = worldMat.m03; instance.boundingSpere.position.y = worldMat.m13; instance.boundingSpere.position.z = worldMat.m23; boundingSphere[i] = instance.boundingSpere; } for (int j = 0; j != lod.vertexCacheList.Length; ++j) { VertexCache cache = lod.vertexCacheList[j] as VertexCache; int packageIndex = cache.runtimePackageIndex[aniTextureIndex]; Debug.Assert(packageIndex < cache.packageList[aniTextureIndex].Count); VertexCache.InstancingPackage package = cache.packageList[aniTextureIndex][packageIndex]; if (package.instancingCount + 1 > instancingPackageSize) { ++cache.runtimePackageIndex[aniTextureIndex]; packageIndex = cache.runtimePackageIndex[aniTextureIndex]; if (packageIndex >= cache.packageList[aniTextureIndex].Count) { VertexCache.InstancingPackage newPackage = CreatePackage(cache.instanceData, cache.mesh, vertexCache.materials, aniTextureIndex); cache.packageList[aniTextureIndex].Add(newPackage); PreparePackageMaterial(newPackage, cache, aniTextureIndex); newPackage.instancingCount = 1; } } else { ++package.instancingCount; } } #else for (int j = 0; j != lod.vertexCacheList.Length; ++j) { VertexCache cache = lod.vertexCacheList[j] as VertexCache; if (cache.instancingData == null) { cache.instancingData = new InstancingData[cache.instancingCount]; cache.bufInstance = new ComputeBuffer((int)cache.instancingCount, 64 + 4 + 4 + 8); } Matrix4x4 worldMat = instance.worldTransform.localToWorldMatrix; cache.instancingData[cache.currentInstancingIndex].worldMatrix.m00 = worldMat.m00; cache.instancingData[cache.currentInstancingIndex].worldMatrix.m01 = worldMat.m01; cache.instancingData[cache.currentInstancingIndex].worldMatrix.m02 = worldMat.m02; cache.instancingData[cache.currentInstancingIndex].worldMatrix.m03 = worldMat.m03; cache.instancingData[cache.currentInstancingIndex].worldMatrix.m10 = worldMat.m10; cache.instancingData[cache.currentInstancingIndex].worldMatrix.m11 = worldMat.m11; cache.instancingData[cache.currentInstancingIndex].worldMatrix.m12 = worldMat.m12; cache.instancingData[cache.currentInstancingIndex].worldMatrix.m13 = worldMat.m13; cache.instancingData[cache.currentInstancingIndex].worldMatrix.m20 = worldMat.m20; cache.instancingData[cache.currentInstancingIndex].worldMatrix.m21 = worldMat.m21; cache.instancingData[cache.currentInstancingIndex].worldMatrix.m22 = worldMat.m22; cache.instancingData[cache.currentInstancingIndex].worldMatrix.m23 = worldMat.m23; cache.instancingData[cache.currentInstancingIndex].worldMatrix.m30 = worldMat.m30; cache.instancingData[cache.currentInstancingIndex].worldMatrix.m31 = worldMat.m31; cache.instancingData[cache.currentInstancingIndex].worldMatrix.m32 = worldMat.m32; cache.instancingData[cache.currentInstancingIndex].worldMatrix.m33 = worldMat.m33; cache.instancingData[cache.currentInstancingIndex].frameIndex = instance.aniInfo[animationIndex].animationIndex + instance.curFrame; cache.instancingData[cache.currentInstancingIndex].animationIndex = 0; ++cache.currentInstancingIndex; } #endif } }