示例#1
0
 void SolverOnCollision(object sender, Obi.ObiSolver.ObiCollisionEventArgs e)
 {
     foreach (Oni.Contact contact in e.contacts)
     {
         // this one is an actual collision:
         if (contact.distance < 0.01)
         {
             ActiveCollider            ac = new ActiveCollider();
             ObiSolver.ParticleInActor pa = solver.particleToActor[contact.particle];
             ac.actor    = pa.actor;
             ac.idxInAct = pa.indexInActor;
             ac.idxInSol = contact.particle;
             Component collider;
             if (ObiCollider.idToCollider.TryGetValue(contact.other, out collider))
             {
                 Vector3 SolvColPos = new Vector3(contact.point[0], contact.point[1], contact.point[2]);
                 //print("Куб: Обнаружен контакт: " + contact.particle + " " + contact.point);
                 Vector3 WorldColPos = solver.gameObject.transform.TransformPoint(SolvColPos);
                 //marker.position = WorldColPos;
                 ac.pos = WorldColPos;
                 if (collider is Collider)
                 {
                     ac.col = collider as Collider;
                 }
             }
             _actCol.Add(ac);
         }
     }
 }
示例#2
0
 // проверить, что ac контактирует с внешним коллайдером
 private bool FindExternalCol(ActiveCollider ac)
 {
     for (int i = 0; i < yachtCols.Length; i++)
     {
         if (ac.col == yachtCols[i])
         {
             return(false);
         }
     }
     return(true);
 }
示例#3
0
    public void SolveAllRopes()
    {
        summF = Vector3.zero;

        //print("Утка " + name);

        // по всем канатам этой утки:
        for (int i = 0; i < Ropes.Count; i++)
        {
            if (!Ropes[i].obiRope.isActiveAndEnabled)
            {
                continue;
            }

            Vector3 direct  = Vector3.zero;         // направление силы на одном канате
            float   valueF  = 0;                    // величина силы на одном канате
            float   curDist = 0;                    // от утки до точки закрепления с учетом изгибов

            // сортируем точки коллайдинга
            var sortedCol = from c in Ropes[i].actCol orderby c.idxInAct select c;
            List <ActiveCollider> sortCol = new List <ActiveCollider>(sortedCol);

            // вычислим текущую длинну каната - она состоит из длинн отрезков
            if (sortCol.Count == 0)
            {
                curDist = Vector3.Distance(transform.position, Ropes[i].Pos);
            }
            else
            {
                curDist = Vector3.Distance(transform.position, sortCol[0].pos);
                for (int j = 0; j < sortCol.Count - 1; j++)
                {
                    curDist += Vector3.Distance(sortCol[j].pos, sortCol[j + 1].pos);
                }
                curDist += Vector3.Distance(sortCol[sortCol.Count - 1].pos, Ropes[i].Pos);
            }

            foreach (ActiveCollider ac in sortCol)
            {
                print(ac.actor.name + "  " + ac.idxInAct + "  " + ac.pos + "  " + ac.col.name + "  curDist = " + curDist);
            }

            direct = Vector3.zero;
            // проверка, не лопнул ли канат
            if (curDist / Ropes[i].Len > Ropes[i].Stretch)
            {
                print("Канат лопнул! Утка " + gameObject.name + "   канат " + i);
                Ropes[i].obiRope.gameObject.SetActive(false);
            }
            else
            {
                // если не лопнул, считаем силу на этом канате
                valueF = 0;
                if (curDist > Ropes[i].Len) // имеется натяжение?
                {
                    valueF = (curDist / Ropes[i].Len - 1) / (Ropes[i].Stretch - 1) * Ropes[i].MaxForce;


                    // определяем направление силы
                    if (sortCol.Count == 0)
                    {
                        // если нет коллайдеров на канате, направление - от утки к точке закрепления
                        direct = (Ropes[i].Pos - transform.position).normalized;
                    }
                    else
                    {
                        // если еть коллайдеры на канате, надо найти первый коллайдер не принадлежащий яхте (временно!)
                        ActiveCollider ac = null;
                        for (int j = 0; j < sortCol.Count; j++)
                        {
                            if (FindExternalCol(sortCol[j]))
                            {
                                ac = sortCol[j];
                                break;
                            }
                        }
                        if (ac == null)
                        {
                            // если коллайдеры только с корпусом яхты, направление - от утки к точке закрепления (временно!)
                            direct = (Ropes[i].Pos - transform.position).normalized;
                        }
                        else
                        {
                            direct = (ac.pos - transform.position).normalized;
                        }
                    }
                }
            }
            Ropes[i].curForce = direct * valueF;
            summF            += Ropes[i].curForce;
        }
    }