本文整理汇总了C#中UnityEngine.Plane.GetSide方法的典型用法代码示例。如果您正苦于以下问题:C# Plane.GetSide方法的具体用法?C# Plane.GetSide怎么用?C# Plane.GetSide使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类UnityEngine.Plane
的用法示例。
在下文中一共展示了Plane.GetSide方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: AdjustEdgeHandleColor
private void AdjustEdgeHandleColor(Vector3 handlePos, Vector3 slideDir1, Vector3 slideDir2, Matrix4x4 transform, float alphaFactor)
{
bool flag;
Vector3 inPoint = transform.MultiplyPoint(handlePos);
Vector3 normalized = transform.MultiplyVector(slideDir1).normalized;
Vector3 rhs = transform.MultiplyVector(slideDir2).normalized;
if (Camera.current.isOrthoGraphic)
{
flag = (Vector3.Dot(-Camera.current.transform.forward, normalized) < 0f) && (Vector3.Dot(-Camera.current.transform.forward, rhs) < 0f);
}
else
{
Plane plane = new Plane(normalized, inPoint);
Plane plane2 = new Plane(rhs, inPoint);
flag = !plane.GetSide(Camera.current.transform.position) && !plane2.GetSide(Camera.current.transform.position);
}
if (flag)
{
alphaFactor *= 0.2f;
}
if (alphaFactor < 1f)
{
Handles.color = new Color(Handles.color.r, Handles.color.g, Handles.color.b, Handles.color.a * alphaFactor);
}
}
示例2: ClipPolygon
public static CausticDecalPolygon ClipPolygon(CausticDecalPolygon polygon, Plane plane)
{
bool[] positive = new bool[9];
int positiveCount = 0;
for(int i = 0; i < polygon.vertices.Count; i++) {
positive[i] = !plane.GetSide( polygon.vertices[i] );
if(positive[i]) positiveCount++;
}
if(positiveCount == 0) return null; // полностью за плоскостью
if(positiveCount == polygon.vertices.Count) return polygon; // полностью перед плоскостью
CausticDecalPolygon tempPolygon = new CausticDecalPolygon();
for(int i = 0; i < polygon.vertices.Count; i++) {
int next = i + 1;
next %= polygon.vertices.Count;
if( positive[i] ) {
tempPolygon.vertices.Add( polygon.vertices[i] );
}
if( positive[i] != positive[next] ) {
Vector3 v1 = polygon.vertices[next];
Vector3 v2 = polygon.vertices[i];
Vector3 v = LineCast(plane, v1, v2);
tempPolygon.vertices.Add( v );
}
}
return tempPolygon;
}
示例3: OnGUI
void OnGUI()
{
Vector3 position = transform.position + Offset;
Plane plane = new Plane( Camera.main.transform.forward, Camera.main.transform.position );
//If the object is behind the camera, then don't draw it
if( plane.GetSide( position ) == false )
{
return;
}
//Calculate the 2D position of the position where the icon should be drawn
Vector3 viewportPoint = Camera.main.WorldToViewportPoint( position );
//The viewportPoint coordinates are between 0 and 1, so we have to convert them into screen space here
Vector2 drawPosition = new Vector2( viewportPoint.x * Screen.width, Screen.height * ( 1 - viewportPoint.y ) );
float clampBorder = 12;
//Clamp the position to the edge of the screen in case the icon would be drawn outside the screen
drawPosition.x = Mathf.Clamp( drawPosition.x, clampBorder, Screen.width - clampBorder );
drawPosition.y = Mathf.Clamp( drawPosition.y, clampBorder, Screen.height - clampBorder );
GUI.color = Color;
GUI.DrawTexture( new Rect( drawPosition.x - Icon.width * 0.5f, drawPosition.y - Icon.height * 0.5f, Icon.width, Icon.height ), Icon );
}
示例4: Internal_RaycastRef
internal bool Internal_RaycastRef(Ray ray, ref UIHotSpot.Hit hit)
{
float single;
Vector2 vector2 = new Vector2();
if (this.radius == 0f)
{
return false;
}
Plane plane = new Plane(UIHotSpot.forward, this.center);
if (!plane.Raycast(ray, out single))
{
hit = new UIHotSpot.Hit();
return false;
}
hit.point = ray.GetPoint(single);
hit.normal = (!plane.GetSide(ray.origin) ? UIHotSpot.backward : UIHotSpot.forward);
vector2.x = hit.point.x - this.center.x;
vector2.y = hit.point.y - this.center.y;
float single1 = vector2.x * vector2.x + vector2.y * vector2.y;
if (single1 >= this.radius * this.radius)
{
return false;
}
hit.distance = Mathf.Sqrt(single1);
return true;
}
示例5: IsHandInBag
public static bool IsHandInBag(Vector3 pos_)
{
// The player is supposed to stand up while playing.
Vector3 forward = Vector3.zero;
if (Mathf.Abs(Vector3.Dot(Vector3.up, _head.forward)) < _tolerance)
{
Debug.LogWarning("Chosen forward = cam.forward");
forward = _head.forward;
}
else if (Mathf.Abs(Vector3.Dot(Vector3.up, _head.up)) < _tolerance)
{
Debug.LogWarning("Chosen forward = cam.up");
forward = _head.up;
}
else
{
Debug.LogWarning("Chosen forward = mix");
// Is that ok... ?
forward = (_head.forward + _head.up).normalized;
}
Plane pl = new Plane(forward, _head.position - forward * 0.15f);
if (!pl.GetSide(pos_))
{
Debug.LogWarning("Point on negative side");
if (pos_.y < _head.position.y)
{
Debug.LogWarning("Point lower than head");
if (_head.position.y - pos_.y < Hub.playerHeight * 0.45f)
{
Debug.LogWarning("Point higher than waist");
Vector3 headPosFromTop = _head.position;
headPosFromTop.y = 0f;
Vector3 handPosFromTop = pos_;
handPosFromTop.y = 0f;
if ((headPosFromTop - handPosFromTop).magnitude < 0.55f)
{
Debug.LogWarning("Point within tube");
return true;
}
}
}
}
else
{
Debug.LogWarning("Point on positive side");
}
return false;
}
示例6: IsPointInside
public bool IsPointInside(Mesh aMesh, Vector3 aLocalPoint)
{
var verts = aMesh.vertices;
var tris = aMesh.triangles;
int triangleCount = tris.Length / 3;
for (int i = 0; i < triangleCount; i++)
{
var V1 = verts[tris[i * 3]];
var V2 = verts[tris[i * 3 + 1]];
var V3 = verts[tris[i * 3 + 2]];
var P = new Plane(V1, V2, V3);
if (P.GetSide(aLocalPoint))
return false;
}
return true;
}
示例7: HandleCam
private void HandleCam()
{
//Debug.Log(deltaAimAngle_X);
//Debug.Log(deltaAimAngle_Y);
//Debug.DrawRay(tf.position, deltaAimPos_X, Color.red);
//Debug.DrawRay(tf.position, deltaAimPos_Y, Color.green);
//Debug.DrawRay(tf.position, Vector3.back * 10.0f);
//HORIZONTAL
Quaternion newHorRot = GetNewHorCamRot(deltaAimAngle_X);
tf.rotation = Quaternion.Slerp(tf.rotation, newHorRot, Time.deltaTime * aimSensitivity);
//VERTICAL
//if (Mathf.Sign(deltaAimDirec.y) > 0.0f && Vector3.Angle(camTF.forward, Vector3.forward) < 90.0f)
Quaternion newVertRot = GetNewVertCamRot(deltaAimAngle_Y);
Quaternion finalVertRot = Quaternion.Slerp(camNeckTf.rotation, newVertRot, Time.deltaTime * aimSensitivity);
//Debug.DrawRay(camNeckTf.position, finalVertRot * Vector3.forward, Color.red);
//planes for limiting player's view rotation (currently generated every frame, this is only ideal if we change the player's orientation, like if gravity changed)
Plane forwardPlane = new Plane(tf.forward, camNeckTf.position);
Plane upPlane = new Plane(tf.up, camNeckTf.position);
if (!forwardPlane.GetSide((finalVertRot * Vector3.forward) + camNeckTf.position)) {
//LIMIT UP
if (upPlane.GetSide((finalVertRot * Vector3.forward) + camNeckTf.position)) {
//Debug.Log("up");
finalVertRot = tf.rotation;
finalVertRot *= Quaternion.LookRotation(tf.up, tf.up);
}
//LIMIT DOWN
else {
//Debug.Log("down");
finalVertRot = tf.rotation;
finalVertRot *= Quaternion.LookRotation(-tf.up, tf.up);
}
}
//Debug.DrawRay(camNeckTf.position, upPlane.normal * 2.0f, Color.blue);
camNeckTf.rotation = finalVertRot;
}
示例8: UpdateRectSelection
private bool UpdateRectSelection()
{
bool flag1 = false;
SkinnedMeshRenderer component = this.cloth.GetComponent<SkinnedMeshRenderer>();
Vector3[] normals = this.cloth.normals;
ClothSkinningCoefficient[] coefficients = this.cloth.coefficients;
float x1 = Mathf.Min(this.m_SelectStartPoint.x, this.m_SelectMousePoint.x);
float x2 = Mathf.Max(this.m_SelectStartPoint.x, this.m_SelectMousePoint.x);
float y1 = Mathf.Min(this.m_SelectStartPoint.y, this.m_SelectMousePoint.y);
float y2 = Mathf.Max(this.m_SelectStartPoint.y, this.m_SelectMousePoint.y);
Ray worldRay1 = HandleUtility.GUIPointToWorldRay(new Vector2(x1, y1));
Ray worldRay2 = HandleUtility.GUIPointToWorldRay(new Vector2(x2, y1));
Ray worldRay3 = HandleUtility.GUIPointToWorldRay(new Vector2(x1, y2));
Ray worldRay4 = HandleUtility.GUIPointToWorldRay(new Vector2(x2, y2));
Plane plane1 = new Plane(worldRay2.origin + worldRay2.direction, worldRay1.origin + worldRay1.direction, worldRay1.origin);
Plane plane2 = new Plane(worldRay3.origin + worldRay3.direction, worldRay4.origin + worldRay4.direction, worldRay4.origin);
Plane plane3 = new Plane(worldRay1.origin + worldRay1.direction, worldRay3.origin + worldRay3.direction, worldRay3.origin);
Plane plane4 = new Plane(worldRay4.origin + worldRay4.direction, worldRay2.origin + worldRay2.direction, worldRay2.origin);
Quaternion rotation = component.actualRootBone.rotation;
for (int index = 0; index < coefficients.Length; ++index)
{
Vector3 lastVertex = this.m_LastVertices[index];
bool flag2 = (double) Vector3.Dot(rotation * normals[index], Camera.current.transform.forward) <= 0.0;
bool flag3 = plane1.GetSide(lastVertex) && plane2.GetSide(lastVertex) && plane3.GetSide(lastVertex) && plane4.GetSide(lastVertex) && (this.state.ManipulateBackfaces || flag2);
if (this.m_RectSelection[index] != flag3)
{
this.m_RectSelection[index] = flag3;
flag1 = true;
}
}
return flag1;
}
示例9: PlaneAvoidance
public Vector3 PlaneAvoidance()
{
makeFeelers();
Plane worldPlane = new Plane(new Vector3(0, 1, 0), 0);
Vector3 force = Vector3.zero;
foreach (Vector3 feeler in PlaneAvoidanceFeelers)
{
if (!worldPlane.GetSide(feeler))
{
float distance = Math.Abs(worldPlane.GetDistanceToPoint(feeler));
force += worldPlane.normal * distance;
}
}
if (force.magnitude > 0.0)
{
DrawFeelers();
}
return force;
}
示例10: UpdateRectSelection
private bool UpdateRectSelection()
{
bool flag = false;
SkinnedMeshRenderer component = this.cloth.GetComponent<SkinnedMeshRenderer>();
Vector3[] normals = this.cloth.normals;
ClothSkinningCoefficient[] coefficients = this.cloth.coefficients;
float x = Mathf.Min(this.m_SelectStartPoint.x, this.m_SelectMousePoint.x);
float num2 = Mathf.Max(this.m_SelectStartPoint.x, this.m_SelectMousePoint.x);
float y = Mathf.Min(this.m_SelectStartPoint.y, this.m_SelectMousePoint.y);
float num4 = Mathf.Max(this.m_SelectStartPoint.y, this.m_SelectMousePoint.y);
Ray ray = HandleUtility.GUIPointToWorldRay(new Vector2(x, y));
Ray ray2 = HandleUtility.GUIPointToWorldRay(new Vector2(num2, y));
Ray ray3 = HandleUtility.GUIPointToWorldRay(new Vector2(x, num4));
Ray ray4 = HandleUtility.GUIPointToWorldRay(new Vector2(num2, num4));
Plane plane = new Plane(ray2.origin + ray2.direction, ray.origin + ray.direction, ray.origin);
Plane plane2 = new Plane(ray3.origin + ray3.direction, ray4.origin + ray4.direction, ray4.origin);
Plane plane3 = new Plane(ray.origin + ray.direction, ray3.origin + ray3.direction, ray3.origin);
Plane plane4 = new Plane(ray4.origin + ray4.direction, ray2.origin + ray2.direction, ray2.origin);
Quaternion rotation = component.actualRootBone.rotation;
for (int i = 0; i < coefficients.Length; i++)
{
Vector3 inPt = this.m_LastVertices[i];
bool flag2 = Vector3.Dot((Vector3) (rotation * normals[i]), Camera.current.transform.forward) <= 0f;
bool flag3 = (((plane.GetSide(inPt) && plane2.GetSide(inPt)) && plane3.GetSide(inPt)) && plane4.GetSide(inPt)) && (this.state.ManipulateBackfaces || flag2);
if (this.m_RectSelection[i] != flag3)
{
this.m_RectSelection[i] = flag3;
flag = true;
}
}
return flag;
}
示例11: DrawRotateGUI
static void DrawRotateGUI()
{
Handles.color = Color.white;
ShapeGUI.NameNextHandle("RotateHandle");
EditorGUI.BeginChangeCheck();
Vector3 topCenterWorld = transform.TransformPoint( topCenter );
Vector3 rotateHandle = topCenterWorld + transform.up * HandleUtility.GetHandleSize(topCenterWorld) *.5f;
rotateHandle = ShapeGUI.VectorHandle( rotateHandle );
Handles.DrawLine( rotateHandle, transform.TransformPoint( topCenter ) );
Plane plane = new Plane( transform.forward, transform.position );
Ray ray = new Ray( rotateHandle, plane.GetSide(rotateHandle) ? -transform.forward : transform.forward );
float d = 0;
plane.Raycast( ray, out d );
rotateHandle = ray.GetPoint(d);
Vector3 rotateVector = (rotateHandle - transform.position).normalized;
float angle = Vector3.Angle( rotateVector, Vector3.up );
float snappedAngle = Mathf.Round( angle / 15 ) * 15;
Vector3 snappedVector = Vector2.up.Rotate( snappedAngle );
if( Event.current.type == EventType.Used )
{
isRotating = EditorGUI.EndChangeCheck();
}
if( GUI.changed )
{
Quaternion newRotation = Quaternion.LookRotation( transform.forward, Event.current.shift ? snappedVector : rotateVector );
if( transform.rotation != newRotation )
{
Transform[] parents = new Transform[ shapes.Length ];
for( int i = 0; i < shapes.Length; i++)
{
Shape shape = shapes[i];
parents[i] = shape.transform.parent;
Undo.SetTransformParent( shape.transform, transform, "Rotate Shapes" );
}
Undo.RecordObject( transform, "Rotate Shapes" );
transform.rotation = newRotation;
for( int i = 0; i < shapes.Length; i++)
{
Shape shape = shapes[i];
Undo.SetTransformParent( shape.transform, parents[i], "Rotate Shapes" );
}
}
GUI.changed = false;
}
}
示例12: Fracture
void Fracture(Vector3 point, Vector3 force, float iterations){
MeshFilter thisMeshFilter = gameObject.GetComponent<MeshFilter>();
if(instantiateOnBreak && force.magnitude >= Mathf.Max(minBreakingForce, forcePerDivision)){
if(Network.isServer || Network.isClient) Network.Instantiate(instantiateOnBreak, transform.position, transform.rotation,0);
else Instantiate(instantiateOnBreak, transform.position, transform.rotation);
instantiateOnBreak=null;
}
while (iterations > 0){
if(totalMaxFractures == 0 || Vector3.Min(thisMeshFilter.mesh.bounds.size, minFractureSize) != minFractureSize){
if(destroySmallAfterTime >= 1.0f)
Destroy(gameObject, destroySmallAfterTime);
totalMaxFractures = 0;
return;
}
totalMaxFractures--;
iterations--;
if(fractureAtCenter) point = thisMeshFilter.mesh.bounds.center;
Vector3 vec = Vector3.Scale(grain,Random.insideUnitSphere).normalized;
Vector3 sub = transform.worldToLocalMatrix.MultiplyVector(force.normalized)*(useCollisionDirection ? 1 : 0)*Vector3.Dot(transform.worldToLocalMatrix.MultiplyVector(force.normalized),vec);
//Vector3 sub = transform.worldToLocalMatrix.MultiplyVector(force.normalized)*useCollisionDirection*Vector3.Dot(transform.worldToLocalMatrix.MultiplyVector(force.normalized),vec);
Plane plane = new Plane(vec-sub,Vector3.Scale(Random.insideUnitSphere, thisMeshFilter.mesh.bounds.size)*randomOffset+point);
GameObject newObject;
if(Network.isServer || Network.isClient){
newObject = _PublicData._PublicProperties.minePlayer.networkView.RPC("CreateCopyLocally",RPCMode.OthersBuffered,gameObject.transform);
//newObject = Network.Instantiate(gameObject.transform, transform.position, transform.rotation,0) as GameObject;
}
else newObject = Instantiate(gameObject.transform, transform.position, transform.rotation) as GameObject;
MeshFilter newObjectMeshFilter = newObject.GetComponent<MeshFilter>();
if(avoidSelfCollision) IgnoreCollision(newObject.collider,gameObject.collider);
if(rigidbody) newObject.rigidbody.velocity = rigidbody.velocity;
Vector3[] vertsA = thisMeshFilter.mesh.vertices;
Vector3[] vertsB = newObjectMeshFilter.mesh.vertices;
Vector3 average = Vector3.zero;
foreach(Vector3 i in vertsA) average+=i;
average /= thisMeshFilter.mesh.vertexCount;
average -= plane.GetDistanceToPoint(average)*plane.normal;
int broken = 0;
if(fractureToPoint){
for(int i=0;i<thisMeshFilter.mesh.vertexCount;i++){
if(plane.GetSide(vertsA[i])){
vertsA[i] = average;
broken++;
}
else vertsB[i] = average;
}
}
else{
for(int ii=0;ii<thisMeshFilter.mesh.vertexCount;ii++){
if(plane.GetSide(vertsA[ii])){
vertsA[ii] -= plane.GetDistanceToPoint(vertsA[ii])*plane.normal;
broken++;
}
else vertsB[ii] -= plane.GetDistanceToPoint(vertsB[ii])*plane.normal;
}
}
if(broken == 0 || broken == thisMeshFilter.mesh.vertexCount){
totalMaxFractures++;
iterations++;
Destroy(newObject);
//yield return null; //mmm
}
else{
thisMeshFilter.mesh.vertices = vertsA;
newObjectMeshFilter.mesh.vertices = vertsB;
thisMeshFilter.mesh.RecalculateNormals();
newObjectMeshFilter.mesh.RecalculateNormals();
thisMeshFilter.mesh.RecalculateBounds();
newObjectMeshFilter.mesh.RecalculateBounds();
MeshCollider thisMeshCol = gameObject.GetComponent<MeshCollider>();
if(thisMeshCol){
thisMeshCol.sharedMesh = thisMeshFilter.mesh;
newObject.GetComponent<MeshCollider>().sharedMesh = newObjectMeshFilter.mesh; //mmm
}
else{
Destroy(collider);
Destroy(gameObject, 1.0f);
}
}
if(smartJoints){
Joint[] jointsb = GetComponents<Joint>();
if(jointsb.Length>0){
for(int iii=0;iii<jointsb.Length;iii++){
if(jointsb[iii].connectedBody!=null && plane.GetSide(transform.worldToLocalMatrix.MultiplyPoint(jointsb[iii].connectedBody.transform.position))){
Joint[] tmpJoints = jointsb[iii].gameObject.GetComponent<ObjectDestruction>().joints;
if(tmpJoints.Length>0){
foreach(Joint j in tmpJoints){
//if(j == jointsb[iii]) j=newObject.GetComponents<Joint>()[iii]; //mmm
}
//.........这里部分代码省略.........
示例13: Save
void Save()
{
model = transform.root.GetComponentInChildren<SkinnedMeshRenderer>();
if (!Split)
return;
//foreach (var a in this.transform.root.GetComponentsInChildren<Rigidbody>())
// a.isKinematic = true;
var r = model;
var lcp = r.transform.localPosition;
var lcr = r.transform.localRotation;
var lcp2 = r.transform.root.position;
var lcr2 = r.transform.root.rotation;
r.transform.localPosition = Vector3.zero;
r.transform.localRotation = Quaternion.identity;
r.transform.root.position = Vector3.zero;
r.transform.root.rotation = Quaternion.identity;
plane = new Plane(transform.up, transform.position);
var sharedMesh = new Mesh();
r.BakeMesh(sharedMesh);
vertices = sharedMesh.vertices;
var Points = new Point[vertices.Length];
var triangles = sharedMesh.triangles;
boneWeights = r.sharedMesh.boneWeights;
var bones = new List<Transform>(r.bones);
foreach(var a in UpperBones)
{
var indexOf = bones.IndexOf(a);
if (indexOf != -1)
ubID.Add(indexOf);
}
if (ubID.Count == 0) throw new Exception("upper bone not found ");
foreach (var a in lowerBones)
{
var indexOf = bones.IndexOf(a);
if (indexOf != -1)
lbID.Add(indexOf);
}
if (lbID.Count == 0) throw new Exception("lower bone not found ");
Transform[] bt = UpperBones[0].GetComponentsInChildren<Transform>();
for (int i = 0; i < bt.Length; i++)
{
var indexOf = bones.IndexOf(bt[i]);
if (indexOf != -1)
temp.Add(new BoneSave() { boneid = indexOf, i = i });
}
Dictionary<KeyValuePair<int, int>, int> dict = new Dictionary<KeyValuePair<int, int>, int>();
for (int i = 0; i < vertices.Length; i++)
{
Points[i] = new Point(vertices[i]) { index = i };
var side = plane.GetSide(vertices[i]);
var v = vertices[i];
v += plane.normal * -plane.GetDistanceToPoint(v);
if (this.collider.bounds.Contains(v))
for (int j = 0; j < 4; j++)
{
var boneid = GetBone(boneWeights[i], j);
if (lbID.Contains(boneid) && side)
{
SetBone(ref boneWeights[i], j, ubID[0]);
dict[new KeyValuePair<int, int>(i, j)] = ubID[0];
}
if (ubID.Contains(boneid) && !side)
{
SetBone(ref boneWeights[i], j, lbID[0]);
dict[new KeyValuePair<int, int>(i, j)] = lbID[0];
}
}
}
boneSave.Clear();
foreach (var a in dict)
boneSave.Add(new BoneSave() { vertex = a.Key.Key, i = a.Key.Value, boneid = a.Value });
triangleSave.Clear();
for (int i = 0; i < triangles.Length / 3; i++)
{
var index0 = i * 3;
Point p0 = Points[triangles[index0]];
Point p1 = Points[triangles[index0 + 1]];
Point p2 = Points[triangles[index0 + 2]];
var sameSide = SameSide(p0, p1) && SameSide(p0, p2) && SameSide(p1, p2);
if (drawGizmo)
{
Debug.DrawLine(p0.pos, p1.pos, sameSide ? Color.blue : Color.red, 5);
Debug.DrawLine(p1.pos, p2.pos, sameSide ? Color.blue : Color.red, 5);
Debug.DrawLine(p2.pos, p0.pos, sameSide ? Color.blue : Color.red, 5);
}
if (!sameSide)
{
triangleSave.Add(index0);
triangles[index0] = 0;
triangles[index0 + 1] = 0;
triangles[index0 + 2] = 0;
//.........这里部分代码省略.........
示例14: FitsAligned
/// <summary>
/// Returns true if THIS metric fits inside the given CONTAINER mesh.
/// </summary>
/// <param name="this_T">Transform of this metric.</param>
/// <param name="other_T">Transform of the given mesh.</param>
/// <param name="container">Mesh acting as a container.</param>
/// Implemeted using algorithm described at
/// http://answers.unity3d.com/questions/611947/am-i-inside-a-volume-without-colliders.html
public bool FitsAligned(Transform this_T, Transform other_T, Mesh container)
{
//get edges in containers reference frame
var edges = hull != null? hull.Points.ToArray() : BoundsEdges(bounds);
//check each triangle of container
var c_edges = container.vertices;
var triangles = container.triangles;
if(triangles.Length/3 > edges.Length)
{
for(int i = 0; i < edges.Length; i++)
edges[i] = other_T.InverseTransformPoint(this_T.position+this_T.TransformDirection(edges[i]-center));
for(int i = 0; i < triangles.Length/3; i++)
{
var V1 = c_edges[triangles[i*3]];
var V2 = c_edges[triangles[i*3+1]];
var V3 = c_edges[triangles[i*3+2]];
var P = new Plane(V1, V2, V3);
foreach(Vector3 edge in edges)
{ if(!P.GetSide(edge)) return false; }
}
}
else
{
var planes = new Plane[triangles.Length/3];
for(int i = 0; i < triangles.Length/3; i++)
{
var V1 = c_edges[triangles[i*3]];
var V2 = c_edges[triangles[i*3+1]];
var V3 = c_edges[triangles[i*3+2]];
planes[i] = new Plane(V1, V2, V3);
}
for(int i = 0; i < edges.Length; i++)
{
var edge = other_T.InverseTransformPoint(this_T.position+this_T.TransformDirection(edges[i]-center));
foreach(Plane P in planes)
{ if(!P.GetSide(edge)) return false; }
}
}
return true;
}
示例15: SplitVertex
/**
* Splits a vertex in two along a plane. Returns true if the vertex can be split, false otherwise. Does not create new border
* edges inside the tear in order to prevent non-manifold vertices emerging, so it is only suitable for realtime cloth tearing.
* \param vertex the vertex to split.
* \param splitPlane plane to split the vertex at.
* \param newVertex the newly created vertex after the split operation has been performed.
* \param vertices new mesh vertices list after the split operation.
* \param removedEdges list of edge ids removed after splitting the vertex.
* \param addedEdges list of edge ids added after splitting the vertex.
* \param oldAndNewEdges a dictionary relating old and new edge ids.
*/
public bool SplitVertex(HEVertex vertex, Plane splitPlane, out HEVertex newVertex, out Vector3[] vertices, out HashSet<int> removedEdges, out HashSet<int> addedEdges, out Dictionary<int,int> oldAndNewEdges)
{
// initialize return values:
removedEdges = new HashSet<int>();
addedEdges = new HashSet<int>();
oldAndNewEdges = new Dictionary<int,int>();
newVertex = null;
// initialize face lists for each side of the split plane.
List<HEFace> side1Faces = new List<HEFace>();
List<HEFace> side2Faces = new List<HEFace>();
HashSet<int> side2Edges = new HashSet<int>();
// Get a copy of mesh vertices:
vertices = input.vertices;
// classify adjacent faces depending on which side of the cut plane they reside in:
foreach(HEFace face in GetNeighbourFacesEnumerator(vertex)){
int v1 = heEdges[face.edges[0]].startVertex;
int v2 = heEdges[face.edges[1]].startVertex;
int v3 = heEdges[face.edges[2]].startVertex;
//Skip this face if it doesnt contain the splitted vertex.
if (v1 != vertex.index && v2 != vertex.index && v3 != vertex.index) continue;
Vector3 faceCenter = (vertices[heVertices[v1].physicalIDs[0]] +
vertices[heVertices[v2].physicalIDs[0]] +
vertices[heVertices[v3].physicalIDs[0]]) / 3.0f;
if (splitPlane.GetSide(faceCenter)){
side1Faces.Add(face);
}else{
side2Faces.Add(face);
foreach(int e in face.edges)
side2Edges.Add(e);
}
}
// If the vertex cant be split, return false.
if (side1Faces.Count == 0 || side2Faces.Count == 0) return false;
// create new mesh vertex and triangle buffers:
vertices = new Vector3[input.vertexCount+1];
Array.Copy(input.vertices,vertices,input.vertexCount);
int[] triangles = input.triangles;
// create a new vertex:
newVertex = new HEVertex(input.vertexCount);
newVertex.index = heVertices.Count;
heVertices.Add(newVertex);
// add the new vertex to the mesh vertices buffer:
vertices[input.vertexCount] = vertices[vertex.physicalIDs[0]];
// Copy uvs, colors and other mesh info.
Vector2[] uv = null;
Vector2[] uv2 = null;
Vector2[] uv3 = null;
Vector2[] uv4 = null;
Color32[] colors = null;
if (input.uv.Length > 0){
uv = new Vector2[input.uv.Length+1];
Array.Copy(input.uv,uv,input.uv.Length);
uv[input.uv.Length] = uv[vertex.physicalIDs[0]]; //TODO: could cause copying uvs from the other side of the cut...
}
if (input.uv2.Length > 0){
uv2 = new Vector2[input.uv2.Length+1];
Array.Copy(input.uv2,uv2,input.uv2.Length);
uv2[input.uv2.Length] = uv2[vertex.physicalIDs[0]];
}
if (input.uv3.Length > 0){
uv3 = new Vector2[input.uv3.Length+1];
Array.Copy(input.uv3,uv3,input.uv3.Length);
uv3[input.uv3.Length] = uv3[vertex.physicalIDs[0]];
}
if (input.uv4.Length > 0){
uv4 = new Vector2[input.uv4.Length+1];
Array.Copy(input.uv4,uv4,input.uv4.Length);
uv4[input.uv4.Length] = uv4[vertex.physicalIDs[0]];
}
if (input.colors32.Length > 0){
colors = new Color32[input.colors32.Length+1];
Array.Copy(input.colors32,colors,input.colors32.Length);
colors[input.colors32.Length] = colors[vertex.physicalIDs[0]];
}
// rearrange edges at side 1:
//.........这里部分代码省略.........