static void DrawGizmoForMyScript(ObiActor actor, GizmoType gizmoType) { if (!ObiParticleActorEditor.editMode) { return; } // Get the particle actor editor to retrieve selected particles: ObiParticleActorEditor[] editors = (ObiParticleActorEditor[])Resources.FindObjectsOfTypeAll(typeof(ObiParticleActorEditor)); // If there's any particle actor editor active, we can show pin constraints: if (editors.Length > 0) { Gizmos.color = new Color(1, 1, 1, 0.75f); for (int i = 0; i < actor.positions.Length; i++) { // skip particles not facing the camera, or inactive ones: if (!actor.active[i] || (!ObiParticleActorEditor.backfaces && !ObiParticleActorEditor.facingCamera[i])) { continue; } // draw particle radiuses if needed if (ObiParticleActorEditor.selectionStatus[i] && currentProperty == ParticleProperty.RADIUS) { Gizmos.DrawSphere(wsPositions[i], actor.solidRadii[i]); } } } }
public override void Merge(ObiActor actor, IObiConstraintsBatch other) { var batch = other as ObiTetherConstraintsBatch; var user = actor as ITetherConstraintsUser; if (batch != null && user != null) { if (!user.tetherConstraintsEnabled) { return; } particleIndices.ResizeUninitialized((m_ActiveConstraintCount + batch.activeConstraintCount) * 2); maxLengthsScales.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount); stiffnesses.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount); lambdas.ResizeInitialized(m_ActiveConstraintCount + batch.activeConstraintCount); stiffnesses.CopyReplicate(user.tetherCompliance, m_ActiveConstraintCount, batch.activeConstraintCount); for (int i = 0; i < batch.activeConstraintCount * 2; ++i) { particleIndices[m_ActiveConstraintCount * 2 + i] = actor.solverIndices[batch.particleIndices[i]]; } for (int i = 0; i < batch.activeConstraintCount; ++i) { maxLengthsScales[m_ActiveConstraintCount + i] = new Vector2(batch.maxLengthsScales[i].x, user.tetherScale); } base.Merge(actor, other); } }
private void OnValidate() { m_Actor = GetComponent <ObiActor>(); Disable(AttachmentType.Static); Disable(AttachmentType.Dynamic); UpdateEnabledState(); UpdateAttachment(); }
// Merges a batch from a given actor with this one. public virtual void Merge(ObiActor actor, IObiConstraintsBatch other) { ObiConstraintsBatch batch = other as ObiConstraintsBatch; m_ConstraintCount += other.constraintCount; m_ActiveConstraintCount += other.activeConstraintCount; m_InitialActiveConstraintCount += other.initialActiveConstraintCount; }
protected override void OnBlueprintUnloaded(ObiActor actor, ObiActorBlueprint blueprint) { if (!Application.isPlaying) { clothMesh = null; filter.sharedMesh = null; } }
protected override void OnBlueprintLoaded(ObiActor actor, ObiActorBlueprint blueprint) { if (cloth.clothBlueprintBase != null && cloth.clothBlueprintBase.inputMesh != null) { cloth.clothBlueprintBase.inputMesh.GetNormals(restNormals); cloth.clothBlueprintBase.inputMesh.GetTangents(restTangents); } }
void Start() { actor = GetComponent <ObiActor>(); for (int i = 0; i < actor.solverIndices.Length; ++i) { actor.solver.colors[actor.solverIndices[i]] = gradient.Evaluate(UnityEngine.Random.value); } }
private void OnValidate() { m_Actor = GetComponent <ObiActor>(); // do not re-bind: simply disable and re-enable the attachment. DisableAttachment(AttachmentType.Static); DisableAttachment(AttachmentType.Dynamic); EnableAttachment(m_AttachmentType); }
void Actor_OnInterpolate(ObiActor actor) { GenerateSmoothChunks(((ObiRopeBase)actor), smoothing); if (OnCurveGenerated != null) { OnCurveGenerated(actor); } }
public override void Merge(ObiActor actor, IObiConstraintsBatch other) { var batch = other as ObiShapeMatchingConstraintsBatch; var user = actor as IShapeMatchingConstraintsUser; if (batch != null && user != null) { if (!user.shapeMatchingConstraintsEnabled) { return; } int initialIndexCount = particleIndices.count; // shape matching constraint particle indices are not reordered when deactivating constraints, // so instead of using batch.activeConstraintCount, batch.constraintCount. We need all of them. int numActiveIndices = 0; for (int i = 0; i < batch.constraintCount; ++i) { numActiveIndices += batch.numIndices[i]; } particleIndices.ResizeUninitialized(initialIndexCount + numActiveIndices); firstIndex.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount); numIndices.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount); explicitGroup.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount); materialParameters.ResizeUninitialized((m_ActiveConstraintCount + batch.activeConstraintCount) * 5); restComs.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount); coms.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount); orientations.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount); lambdas.ResizeInitialized(m_ActiveConstraintCount + batch.activeConstraintCount); numIndices.CopyFrom(batch.numIndices, 0, m_ActiveConstraintCount, batch.activeConstraintCount); explicitGroup.CopyFrom(batch.explicitGroup, 0, m_ActiveConstraintCount, batch.activeConstraintCount); orientations.CopyReplicate(actor.actorLocalToSolverMatrix.rotation, m_ActiveConstraintCount, batch.activeConstraintCount); for (int i = 0; i < numActiveIndices; ++i) { particleIndices[initialIndexCount + i] = actor.solverIndices[batch.particleIndices[i]]; } for (int i = 0; i < batch.activeConstraintCount; ++i) { firstIndex[m_ActiveConstraintCount + i] = batch.firstIndex[i] + initialIndexCount; materialParameters[(m_ActiveConstraintCount + i) * 5] = user.deformationResistance; materialParameters[(m_ActiveConstraintCount + i) * 5 + 1] = user.plasticYield; materialParameters[(m_ActiveConstraintCount + i) * 5 + 2] = user.plasticCreep; materialParameters[(m_ActiveConstraintCount + i) * 5 + 3] = user.plasticRecovery; materialParameters[(m_ActiveConstraintCount + i) * 5 + 4] = user.maxDeformation; } base.Merge(actor, other); } }
void Start() { actor = GetComponent <ObiActor>(); if (actor.colors != null) { for (int i = 0; i < actor.colors.Length; ++i) { actor.colors[i] = gradient.Evaluate(UnityEngine.Random.value); } } }
private void Awake() { m_Actor = GetComponent <ObiActor>(); m_Actor.OnBlueprintLoaded += Actor_OnBlueprintLoaded; m_Actor.OnSubstep += Actor_OnSolverStep; if (m_Actor.solver != null) { Actor_OnBlueprintLoaded(m_Actor, m_Actor.blueprint); } }
public void Awake() { actor = GetComponent <ObiActor>(); // figure out the size of our drawcall arrays: particlesPerDrawcall = Constants.maxVertsPerMesh / 4; drawcallCount = actor.positions.Length / particlesPerDrawcall + 1; particlesPerDrawcall = Mathf.Min(particlesPerDrawcall, actor.positions.Length); actor.OnAddedToSolver += delegate { Subscribe(); }; actor.OnRemovedFromSolver += delegate { Unsubscribe(); }; }
private void Awake() { m_Actor = GetComponent <ObiActor>(); m_Actor.OnBlueprintLoaded += Actor_OnBlueprintLoaded; m_Actor.OnPrepareStep += Actor_OnPrepareStep; m_Actor.OnEndStep += Actor_OnEndStep; if (m_Actor.solver != null) { Actor_OnBlueprintLoaded(m_Actor, m_Actor.sourceBlueprint); } }
private void UnregisterActor(ObiActor actor) { if (actor != null) { actor.OnBlueprintLoaded -= Actor_OnBlueprintLoaded; actor.OnBlueprintUnloaded -= Actor_OnBlueprintUnloaded; if (actor.solver != null) { Actor_OnBlueprintUnloaded(actor, actor.sourceBlueprint); } } }
public ObiConstraints(ObiActor actor = null, ObiConstraints <T> source = null) { this.actor = actor; this.source = source; if (source != null) { foreach (T batch in source.batches) { AddBatch(batch.Clone(this) as T); } } }
void Actor_OnBlueprintLoaded(ObiActor actor, ObiActorBlueprint blueprint) { // when both actors are in the same solver, add stitches. if (actor1 != null && actor2 != null && actor1.isLoaded && actor2.isLoaded) { if (actor1.solver != actor2.solver) { Debug.LogError("ObiStitcher cannot handle actors in different solvers."); return; } AddToSolver(actor1.solver); } }
void DrawParticles(ObiActor actor) { using (m_DrawParticlesPerfMarker.Auto()) { if (mesh == null || material == null || !render || !isActiveAndEnabled || !actor.isActiveAndEnabled || actor.solver == null) { return; } ObiSolver solver = actor.solver; // figure out the size of our instance batches: meshesPerBatch = Constants.maxInstancesPerBatch; batchCount = actor.particleCount / meshesPerBatch + 1; meshesPerBatch = Mathf.Min(meshesPerBatch, actor.particleCount); Vector4 basis1 = new Vector4(1, 0, 0, 0); Vector4 basis2 = new Vector4(0, 1, 0, 0); Vector4 basis3 = new Vector4(0, 0, 1, 0); //Convert particle data to mesh instances: for (int i = 0; i < batchCount; i++) { matrices.Clear(); colors.Clear(); mpb = new MaterialPropertyBlock(); int limit = Mathf.Min((i + 1) * meshesPerBatch, actor.activeParticleCount); for (int j = i * meshesPerBatch; j < limit; ++j) { int solverIndex = actor.solverIndices[j]; actor.GetParticleAnisotropy(solverIndex, ref basis1, ref basis2, ref basis3); matrices.Add(Matrix4x4.TRS(actor.GetParticlePosition(solverIndex), actor.GetParticleOrientation(solverIndex), Vector3.Scale(new Vector3(basis1[3], basis2[3], basis3[3]), instanceScale))); colors.Add(actor.GetParticleColor(solverIndex)); } if (colors.Count > 0) mpb.SetVectorArray("_Color", colors); // Send the meshes to be drawn: Graphics.DrawMeshInstanced(mesh, 0, material, matrices, mpb); } } }
public override void ApplyForcesToActor(ObiActor actor) { Matrix4x4 l2sTransform; if (actor.Solver.simulateInLocalSpace) { l2sTransform = actor.Solver.transform.worldToLocalMatrix * transform.localToWorldMatrix; } else { l2sTransform = transform.localToWorldMatrix; } Vector4 directionalForce = l2sTransform.MultiplyVector(Vector3.forward * (intensity + GetTurbulence(turbulence))); float sqrRadius = radius * radius; // Allocate forces array: Vector4[] forces = new Vector4[actor.particleIndices.Length]; Vector4 center = new Vector4(transform.position.x, transform.position.y, transform.position.z); // Calculate force intensity for each actor particle: for (int i = 0; i < forces.Length; ++i) { Vector4 distanceVector = actor.Solver.renderablePositions[actor.particleIndices[i]] - center; float sqrMag = distanceVector.sqrMagnitude; float falloff = Mathf.Clamp01((sqrRadius - sqrMag) / sqrRadius); if (radial) { forces[i] = distanceVector / (Mathf.Sqrt(sqrMag) + float.Epsilon) * falloff * intensity; } else { forces[i] = directionalForce * falloff; } } if (actor.UsesCustomExternalForces) { Oni.AddParticleWinds(actor.Solver.OniSolver, forces, actor.particleIndices, actor.particleIndices.Length); } else { Oni.AddParticleExternalForces(actor.Solver.OniSolver, forces, actor.particleIndices, actor.particleIndices.Length); } }
public override void UpdateRenderer(ObiActor actor) { base.UpdateRenderer(actor); if (Application.isPlaying && clothMesh != null && cloth.isLoaded) { // since the skinned mesh renderer won't accept a mesh with no bone weights, we need to render the mesh ourselves: skin.sharedMesh = null; skin.GetSharedMaterials(rendererMaterials); foreach (Material m in rendererMaterials) { Graphics.DrawMesh(clothMesh, skin.rootBone.transform.localToWorldMatrix, m, gameObject.layer); } } }
public int[] GetIndicesForActor(ObiActor actor) { int[] ignored = new int[ignoredParticleIndices.Length]; for (int j = 0; j < ignoredParticleIndices.Length; ++j) { if (ignoredParticleIndices[j] >= 0 && ignoredParticleIndices[j] < actor.particleIndices.Count) { ignored[j] = actor.particleIndices[ignoredParticleIndices[j]]; } else { ignored[j] = ignoredParticleIndices[j]; } } return(ignored); }
public virtual void UpdateRenderer(ObiActor actor) { using (m_UpdateClothRendererPerfMarker.Auto()) { SetupUpdate(); // Only update the mesh if the blueprint is loaded if (Application.isPlaying && cloth.isLoaded && clothMesh != null) { var solver = cloth.solver; space = renderMatrix * solver.transform.localToWorldMatrix; //Update mesh data: for (int i = 0; i < clothVertices.Count; ++i) { int actorIndex = topology.rawToWelded[i]; if (cloth.IsParticleActive(actorIndex)) { UpdateActiveVertex(solver, actorIndex, i); } else { UpdateInactiveVertex(solver, actorIndex, i); } } SetClothMeshData(); clothMesh.RecalculateBounds(); if (tangentSpaceUpdate == TangentSpaceUpdateMode.RecalculateNormalsFromMesh || tangentSpaceUpdate == TangentSpaceUpdateMode.RecalculateNormalsAndTangentsFromMesh) { clothMesh.RecalculateNormals(); } if (tangentSpaceUpdate == TangentSpaceUpdateMode.RecalculateNormalsAndTangentsFromMesh) { clothMesh.RecalculateTangents(); } if (OnRendererUpdated != null) { OnRendererUpdated(actor); } } } }
public override void ApplyForcesToActor(ObiActor actor) { float sqrRadius = radius * radius; float finalIntensity = intensity + GetTurbulence(turbulence); Matrix4x4 l2sTransform; if (actor.Solver.simulateInLocalSpace) { l2sTransform = actor.Solver.transform.worldToLocalMatrix * transform.localToWorldMatrix; } else { l2sTransform = transform.localToWorldMatrix; } Vector4 center = l2sTransform.MultiplyPoint3x4(Vector4.zero); Vector4 forward = l2sTransform.MultiplyVector(Vector3.forward); // Calculate force intensity for each actor particle: for (int i = 0; i < actor.particleIndices.Length; ++i) { Vector4 distanceVector = actor.Solver.positions[actor.particleIndices[i]] - center; float sqrMag = distanceVector.sqrMagnitude; float falloff = Mathf.Clamp01((sqrRadius - sqrMag) / sqrRadius); Vector4 force; if (radial) { force = distanceVector / (Mathf.Sqrt(sqrMag) + float.Epsilon) * falloff * finalIntensity; } else { force = forward * falloff * finalIntensity; } if (actor.UsesCustomExternalForces) { actor.Solver.wind[actor.particleIndices[i]] += force; } else { actor.Solver.externalForces[actor.particleIndices[i]] += force; } } }
void DrawParticles(ObiActor actor) { using (m_DrawParticlesPerfMarker.Auto()) { if (!isActiveAndEnabled || !actor.isActiveAndEnabled || actor.solver == null) { impostors.ClearMeshes(); return; } CreateMaterialIfNeeded(); impostors.UpdateMeshes(actor); DrawParticles(); } }
// Update is called once per frame void UpdatePlugs(ObiActor actor) { var rope = actor as ObiRopeBase; // cache the rope's transform matrix/quaternion: Matrix4x4 l2w = rope.transform.localToWorldMatrix; Quaternion l2wRot = l2w.rotation; int instanceIndex = 0; // place prefabs at the start/end of each curve: for (int c = 0; c < smoother.smoothChunks.Count; ++c) { ObiList <ObiPathFrame> curve = smoother.smoothChunks[c]; if ((plugTears && c > 0) || (plugStart && c == 0)) { var instance = GetOrCreatePrefabInstance(instanceIndex++); instance.SetActive(true); ObiPathFrame frame = curve[0]; instance.transform.position = l2w.MultiplyPoint3x4(frame.position); instance.transform.rotation = l2wRot * (Quaternion.LookRotation(-frame.tangent, frame.binormal)); instance.transform.localScale = instanceScale; } if ((plugTears && c < smoother.smoothChunks.Count - 1) || (plugEnd && c == smoother.smoothChunks.Count - 1)) { var instance = GetOrCreatePrefabInstance(instanceIndex++); instance.SetActive(true); ObiPathFrame frame = curve[curve.Count - 1]; instance.transform.position = l2w.MultiplyPoint3x4(frame.position); instance.transform.rotation = l2wRot * (Quaternion.LookRotation(frame.tangent, frame.binormal)); instance.transform.localScale = instanceScale; } } // deactivate remaining instances: for (int i = instanceIndex; i < instances.Count; ++i) { instances[i].SetActive(false); } }
/** * Adds the actor to this solver. Will return whether the allocation was sucessful or not. */ public bool AddActor(ObiActor actor, int numParticles) { if (particleToActor == null || actor == null) { return(false); } int[] allocated = new int[numParticles]; int allocatedCount = 0; for (int i = 0; i < maxParticles && allocatedCount < numParticles; i++) { if (particleToActor[i] == null) { allocated[allocatedCount] = i; allocatedCount++; } } // could not allocate enough particles. if (allocatedCount < numParticles) { return(false); } allocatedParticleCount += numParticles; // store per-particle actor reference: for (int i = 0; i < numParticles; ++i) { particleToActor[allocated[i]] = new ParticleInActor(actor, i); } // set the actor particle indices. actor.particleIndices = allocated; // Add the actor to the actor list: actors.Add(actor); // Update active particles. Update materials, in case the actor has a new one. UpdateActiveParticles(); UpdateEmitterMaterials(); return(true); }
private void UpdateBones(ObiActor actor) { if (m_Bones.Count > 0 && m_Source.solver != null) { int boneIndex = 0; var constraints = m_Source.softbodyBlueprint.GetConstraintsByType(Oni.ConstraintType.ShapeMatching) as ObiConstraints <ObiShapeMatchingConstraintsBatch>; foreach (ObiShapeMatchingConstraintsBatch batch in constraints.GetBatchInterfaces()) { for (int i = 0; i < batch.activeConstraintCount; ++i, ++boneIndex) { // the first particle index in each shape is the "center" particle. int shapeIndex = batch.particleIndices[batch.firstIndex[i]]; m_Bones[boneIndex].position = m_Source.GetParticlePosition(m_Source.solverIndices[shapeIndex]); m_Bones[boneIndex].rotation = m_Source.GetParticleOrientation(m_Source.solverIndices[shapeIndex]); } } } }
public virtual void OnEnable() { actor = (ObiActor)target; particlesMesh = new Mesh(); particlesMesh.hideFlags = HideFlags.HideAndDontSave; SetupValuesGradient(); separatorLine = new GUIStyle(EditorGUIUtility.GetBuiltinSkin(EditorSkin.Scene).box); separatorLine.normal.background = EditorGUIUtility.Load("SeparatorLine.psd") as Texture2D; separatorLine.border = new RectOffset(3, 3, 0, 0); separatorLine.fixedHeight = 3; separatorLine.stretchWidth = true; EditorApplication.update += Update; EditorApplication.playmodeStateChanged += OnPlayModeStateChanged; }
public override void Merge(ObiActor actor, IObiConstraintsBatch other) { var batch = other as ObiVolumeConstraintsBatch; var user = actor as IVolumeConstraintsUser; if (batch != null && user != null) { if (!user.volumeConstraintsEnabled) { return; } int initialIndexCount = particleIndices.count; int numActiveTriangles = 0; for (int i = 0; i < batch.constraintCount; ++i) { numActiveTriangles += batch.numTriangles[i]; } particleIndices.ResizeUninitialized(initialIndexCount + numActiveTriangles * 3); firstTriangle.ResizeUninitialized(firstTriangle.count + batch.activeConstraintCount); numTriangles.ResizeUninitialized(numTriangles.count + batch.activeConstraintCount); restVolumes.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount); pressureStiffness.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount); lambdas.ResizeInitialized(m_ActiveConstraintCount + batch.activeConstraintCount); numTriangles.CopyFrom(batch.numTriangles, 0, m_ActiveConstraintCount, batch.activeConstraintCount); restVolumes.CopyFrom(batch.restVolumes, 0, m_ActiveConstraintCount, batch.activeConstraintCount); pressureStiffness.CopyReplicate(new Vector2(user.pressure, user.compressionCompliance), m_ActiveConstraintCount, batch.activeConstraintCount); for (int i = 0; i < numActiveTriangles * 3; ++i) { particleIndices[initialIndexCount + i] = actor.solverIndices[batch.particleIndices[i]]; } for (int i = 0; i < batch.activeConstraintCount + 1; ++i) { firstTriangle[m_ActiveConstraintCount + i] = initialIndexCount / 3 + batch.firstTriangle[i]; } base.Merge(actor, other); } }
public override void Merge(ObiActor actor, IObiConstraintsBatch other) { var batch = other as ObiChainConstraintsBatch; var user = actor as IChainConstraintsUser; if (batch != null && user != null) { if (!user.chainConstraintsEnabled) { return; } int initialIndexCount = particleIndices.count; int numActiveIndices = 0; for (int i = 0; i < batch.activeConstraintCount; ++i) { numActiveIndices += batch.numParticles[i]; } particleIndices.ResizeUninitialized(initialIndexCount + numActiveIndices); firstParticle.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount); numParticles.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount); lengths.ResizeUninitialized(m_ActiveConstraintCount + batch.activeConstraintCount); lambdas.ResizeInitialized(m_ActiveConstraintCount + batch.activeConstraintCount); numParticles.CopyFrom(batch.numParticles, 0, m_ActiveConstraintCount, batch.activeConstraintCount); for (int i = 0; i < numActiveIndices; ++i) { particleIndices[initialIndexCount + i] = actor.solverIndices[batch.particleIndices[i]]; } for (int i = 0; i < batch.activeConstraintCount; ++i) { firstParticle[m_ActiveConstraintCount + i] = batch.firstParticle[i] + initialIndexCount; lengths[m_ActiveConstraintCount + i] = new Vector2(batch.lengths[i].y * user.tightness, batch.lengths[i].y); } base.Merge(actor, other); } }
static void DrawGizmoForMyScript(ObiActor actor, GizmoType gizmoType) { if (!ObiParticleActorEditor.editMode) return; // Get the particle actor editor to retrieve selected particles: ObiParticleActorEditor[] editors = (ObiParticleActorEditor[])Resources.FindObjectsOfTypeAll(typeof(ObiParticleActorEditor)); // If there's any particle actor editor active, we can show pin constraints: if (editors.Length >0) { Gizmos.color = new Color(1,1,1,0.75f); for(int i = 0; i < actor.positions.Length; i++) { // skip particles not facing the camera, or inactive ones: if (!actor.active[i] || (!ObiParticleActorEditor.backfaces && !ObiParticleActorEditor.facingCamera[i])) continue; // draw particle radiuses if needed if (ObiParticleActorEditor.selectionStatus[i] && currentProperty == ParticleProperty.RADIUS){ Gizmos.DrawSphere(wsPositions[i],actor.solidRadii[i]); } } } }
public virtual void OnEnable() { actor = (ObiActor)target; particlesMesh = new Mesh(); particlesMesh.hideFlags = HideFlags.HideAndDontSave; SetupValuesGradient(); separatorLine = new GUIStyle(EditorGUIUtility.GetBuiltinSkin(EditorSkin.Scene).box); separatorLine.normal.background = EditorGUIUtility.Load("SeparatorLine.psd") as Texture2D; separatorLine.border = new RectOffset(3,3,0,0); separatorLine.fixedHeight = 3; separatorLine.stretchWidth = true; EditorApplication.update += Update; EditorApplication.playmodeStateChanged += OnPlayModeStateChanged; }
/** * Inserts a new GameObject into the DBVH. The node bounds are supposed to be up to date. */ public bool Insert(ObiActor actor) { // If no gameobject at all, we can't insert it. if (actor == null) return false; // Create a new node. DBVHNode node = new DBVHNode(actor); node.UpdateBounds(nodes); // If there are no nodes in the tree, this is the root. if (nodes.Count == 0){ node.Index = 0; nodes.Add(node); }else{ InsertNode(node,nodes[0]); } return true; }
public DBVHNode(ObiActor actor) { this.content = actor; }
/** * Removes a GameObject from the tree. */ public void Remove(ObiActor actor) { if (actor == null) return; DBVHNode node = nodes[actor.nodeIndex]; //If this is the root node, destroy the whole thing. if (node.Parent < 0){ nodes.Clear(); }else{ //This is a regular node. DBVHNode sibling; DBVHNode parent = nodes[node.Parent]; // Get our sibling node: if (parent.Left == node.Index) sibling = nodes[parent.Right]; else sibling = nodes[parent.Left]; // transplant whole subtree: nodes[node.Index] = null; TransplantTree(sibling, parent.Index); // make sure bounds up the transplanted branch stay compact: int pIndex = sibling.Parent; while (pIndex >= 0){ nodes[pIndex].UpdateBounds(nodes); pIndex = nodes[pIndex].Parent; } } }