public void UnregisterObject(UnityEngine.Object InObject) { ManagedObjectInfo objectInfo = RemoveAndReturnValue(InObject, managedObjects); if (objectInfo != null) { if (objectInfo.GetPostSignificanceType() == PostSignificanceType.Sequntial) { --managedObjectsWithSequentialPostWork; } if (managedObjectsByTag.ContainsKey(objectInfo.GetTag())) { List <ManagedObjectInfo> ObjectsWithTag = managedObjectsByTag[objectInfo.GetTag()]; if (ObjectsWithTag.Count == 1) { managedObjectsByTag.Remove(objectInfo.GetTag()); } else { ObjectsWithTag.Remove(objectInfo); } FManagedObjectPostSignificanceFunction ManagedObjectPostSignificanceFunction = objectInfo.GetPostSignificanceFunction(); if (ManagedObjectPostSignificanceFunction != null) { ManagedObjectPostSignificanceFunction(objectInfo, objectInfo.GetSignificance(), 1.0f, true); } } objectInfo = null; } }
public float SignificanceFunction(ManagedObjectInfo objectInfo, Transform transform) { Transform significanceActor = (Transform)objectInfo.GetObject(); float distance = Vector3.Distance(transform.position, significanceActor.position); //distance、visibility、screen size //TODO occlusionCulling if (distance < significanceDistance) { Collider collider = significanceActor.GetComponent <Collider>(); if (collider) { Plane[] planes = GeometryUtility.CalculateFrustumPlanes(mainCamera); if (GeometryUtility.TestPlanesAABB(planes, collider.bounds)) { float diameter = collider.bounds.extents.magnitude; float distanceToCamera = Vector3.Distance(mainCamera.transform.position, significanceActor.position); float angularSize = (diameter / distanceToCamera) * Mathf.Rad2Deg; float pixelSize = ((angularSize * Screen.height) / mainCamera.fieldOfView); float distanceSignificance = 1f - distance / significanceDistance; pixelSize = pixelSize > significancePixelSize ? significancePixelSize : pixelSize; float pixelSignificance = (1 - distanceSignificance) * pixelSize / significancePixelSize;//能量守恒 return(distanceSignificance + pixelSignificance); } } } return(0.0f); }
protected void RegisterManagedObject(ManagedObjectInfo objectInfo) { UnityEngine.Object Object = objectInfo.GetObject(); if (objectInfo.GetPostSignificanceType() == PostSignificanceType.Sequntial) { ++managedObjectsWithSequentialPostWork; } if (viewpoints.Count > 0) { objectInfo.UpdateSignificance(viewpoints, bSortSignificanceAscending); if (objectInfo.GetPostSignificanceType() == PostSignificanceType.Sequntial) { FManagedObjectPostSignificanceFunction PostSignificanceFunction = objectInfo.GetPostSignificanceFunction(); PostSignificanceFunction(objectInfo, 1.0f, objectInfo.GetSignificance(), false); } } managedObjects.Add(Object, objectInfo); List <ManagedObjectInfo> managedObjectInfos = FindOrAdd(objectInfo.GetTag(), managedObjectsByTag); if (managedObjectInfos.Count > 0) { int LowIndex = 0; int HighIndex = managedObjectInfos.Count - 1; while (true) { int MidIndex = LowIndex + (HighIndex - LowIndex) / 2; if (CompareBySignificanceAscending(objectInfo, managedObjectInfos[MidIndex])) { if (LowIndex == MidIndex) { managedObjectInfos.Insert(LowIndex, objectInfo); break; } else { HighIndex = MidIndex - 1; } } else if (LowIndex == HighIndex) { managedObjectInfos.Insert(LowIndex + 1, objectInfo); break; } else { LowIndex = MidIndex + 1; } } } else { managedObjectInfos.Add(objectInfo); } }
private ManagedObjectInfo RemoveAndReturnValue(UnityEngine.Object Object, Dictionary <UnityEngine.Object, ManagedObjectInfo> managedObjects) { ManagedObjectInfo managedObjectInfo = null; if (managedObjects.ContainsKey(Object)) { managedObjectInfo = managedObjects[Object]; managedObjects.Remove(Object); } return(managedObjectInfo); }
//Ascending private int CompareBySignificance(ManagedObjectInfo x, ManagedObjectInfo y) { if (x.GetSignificance() > y.GetSignificance()) { return(-1); } else if (x.GetSignificance() < y.GetSignificance()) { return(1); } return(0); }
public void RegisterObject(UnityEngine.Object inObject, string tag, FManagedObjectSignificanceFunction managedObjectSignificanceFunction, PostSignificanceType postSignificanceType = PostSignificanceType.None, FManagedObjectPostSignificanceFunction managedObjectPostSignificanceFunction = null) { ManagedObjectInfo managedObjectInfo = new ManagedObjectInfo( inObject, tag, 1.0f, postSignificanceType, managedObjectSignificanceFunction, managedObjectPostSignificanceFunction); RegisterManagedObject(managedObjectInfo); }
public void PostSignificanceFunction(ManagedObjectInfo objectInfo, float oldSignificance, float significance, bool bUnregistered) { if (significance > 0f) { //提高 AI tick 频率,设置粒子发射器等等 //设置 lod level } else { //关闭 AI tick,关闭粒子等 //关闭 lod } #if UNITY_EDITOR Transform significanceActor = (Transform)objectInfo.GetObject(); DebugHUD textMesh = significanceActor.GetComponentInChildren <DebugHUD>(); textMesh.ShowDebugView(significance, debugDisplayInfo.ShouldDisplayDebug); #endif }
public void UpdateSignificance(List <Transform> inViewpoints) { viewpoints.Clear(); viewpoints.AddRange(inViewpoints); objArray.Capacity = managedObjects.Count; objWithSequentialPostWork.Capacity = managedObjectsWithSequentialPostWork; foreach (ManagedObjectInfo ObjectInfo in managedObjects.Values) { objArray.Add(ObjectInfo); if (ObjectInfo.GetPostSignificanceType() == PostSignificanceType.Sequntial) { SequentialPostWorkPair sequentialPostWorkPair = new SequentialPostWorkPair(); sequentialPostWorkPair.objectInfo = ObjectInfo; sequentialPostWorkPair.oldSignificance = ObjectInfo.GetSignificance(); objWithSequentialPostWork.Add(sequentialPostWorkPair); } } for (int i = 0; i < objArray.Count; i++) { ManagedObjectInfo ObjectInfo = objArray[i]; ObjectInfo.UpdateSignificance(viewpoints, bSortSignificanceAscending); } foreach (SequentialPostWorkPair sequentialPostWorkPair in objWithSequentialPostWork) { ManagedObjectInfo objectInfo = sequentialPostWorkPair.objectInfo; objectInfo.GetPostSignificanceFunction()(objectInfo, sequentialPostWorkPair.oldSignificance, objectInfo.GetSignificance(), false); } objArray.Clear(); objWithSequentialPostWork.Clear(); foreach (List <ManagedObjectInfo> managedObjectInfos in managedObjectsByTag.Values) { managedObjectInfos.Sort(CompareBySignificance); } }
public float SignificanceFunction(ManagedObjectInfo objectInfo, Transform transform) { Transform significanceActor = (Transform)objectInfo.GetObject(); float distance = Vector3.Distance(transform.position, significanceActor.position); //distance、visibility //TODO screen size... //TODO occlusionCulling if (distance < significanceDistance) { Collider collider = significanceActor.GetComponent <Collider>(); if (collider) { Plane[] planes = GeometryUtility.CalculateFrustumPlanes(mainCamera); if (GeometryUtility.TestPlanesAABB(planes, collider.bounds)) { float significance = 1f - distance / significanceDistance; return(significance); } } } return(0f); }
public ManagedObjectMetric(CachedSnapshot snapshot, ManagedObjectInfo obj) { m_Snapshot = snapshot; m_Object = obj; }
private bool CompareBySignificanceAscending(ManagedObjectInfo A, ManagedObjectInfo B) { return(A.GetSignificance() < B.GetSignificance()); }
public ManagedObjectInfo ParseObjectHeader(ulong ptr, int index) { ManagedObjectInfo o; o = new ManagedObjectInfo(); o.ptrObject = ptr; o.managedObjectIndex = index; var boHeader = FindManageBytes(ptr); var ptrIdentity = boHeader.ReadPointer(); o.ptrTypeInfo = ptrIdentity; o.iTypeDescription = ManagedTypeInfoToTypeDescriptionIndex(o.ptrTypeInfo); bool error = false; if (o.iTypeDescription < 0) { o.usedHeaderIdentityPointer = true; var boIdentity = FindManageBytes(ptrIdentity); if (boIdentity.IsValid) { var ptrTypeInfo = boIdentity.ReadPointer(); o.ptrTypeInfo = ptrTypeInfo; o.iTypeDescription = ManagedTypeInfoToTypeDescriptionIndex(o.ptrTypeInfo); error = o.iTypeDescription < 0; } else { error = true; } } else { o.usedHeaderIdentityPointer = false; } if (!error) { o.data = boHeader; //If is a unity object, find its native object index if (DerivesFrom(o.iTypeDescription, m_UnityEngineObject_TypeIndex)) { int instanceID = 0; if (m_UnityEngineObject_instanceIDOffset >= 0) { instanceID = FindManageBytes(o.ptrObject + (UInt64)m_UnityEngineObject_instanceIDOffset).ReadInt32(); } else if (m_UnityEngineObject_cachedPtrOffset >= 0) { // If you get a compilation error on the following 2 lines, update to Unity 5.4b14. var cachedPtr = FindManageBytes(o.ptrObject + (UInt64)m_UnityEngineObject_cachedPtrOffset).ReadPointer(); var indexOfNativeObject = m_NativeObject_Address.FindIndex(no => no == cachedPtr); if (indexOfNativeObject >= 0) { instanceID = m_NativeObject_InstanceID[indexOfNativeObject]; } else { UnityEngine.Debug.LogWarning("Managed object (addr:" + o.ptrObject + ", index:" + o.managedObjectIndex + ") pointing to unknown native object. (cachedPtr:" + cachedPtr + ")"); } } if (!m_NativeObjectInstanceID_ToIndex.TryGetValue(instanceID, out o.nativeObjectIndex)) { o.nativeObjectIndex = -1; } } } else { var ptrIdentityTypeIndex = ManagedTypeInfoToTypeDescriptionIndex(ptrIdentity); var cursor = boHeader; string str = ""; for (int j = 0; j != 4; ++j) { for (int i = 0; i != 8; ++i) { var b = cursor.bytes[cursor.offset + i]; str += string.Format(" {0:X2}", b); } var d = cursor.ReadInt64(); str += string.Format(" : 0x{0:X}, {1}", d, d); str += "\n"; cursor = cursor.Add(8); } UnityEngine.Debug.LogWarning("Unknown object header or type. Index = " + index + " header: \n" + str + " First pointer as type index = " + ptrIdentityTypeIndex ); o.ptrTypeInfo = 0; o.iTypeDescription = -1; } return(o); }