Weld вершин

Программирование на Юнити.

Weld вершин

Сообщение gnoblin 09 апр 2010, 17:07

Хочу склеить шов между двумя отдельными кусками меша (пример: два треугольника которые надо сшить по одному ребру).
В максе эта операция называется weld.

Не учитываю вариант, когда количество треугольников изменяется.

Никак не получается ~x(. Вместо склееного меша получается какая-то каша.
По-ходу это как-то связано с тем как юнити добавляет в меш дополнительные вершины (+ я накосячил, очевидно).

Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class CharPartsContourWelder : MonoBehaviour
{
    public GameObject[] parts;
   
    MeshFilter mesh_filter;
    public float delta = 0.5f;
   
    void Start()
    {
       
        List<CombineInstance> combineInstances = new List<CombineInstance>();
        for (int sub = 0; sub < parts.Length; sub++)
        {
            CombineInstance ci = new CombineInstance();
            ci.mesh = parts[sub].GetComponent<MeshFilter>().mesh;
            ci.transform = parts[sub].transform.localToWorldMatrix;
            parts[sub].renderer.enabled = false;
            combineInstances.Add(ci);
        }
        mesh_filter = gameObject.GetComponent<MeshFilter>();
        mesh_filter.mesh = new Mesh();
        mesh_filter.mesh.CombineMeshes(combineInstances.ToArray(), true, true);

        int length = mesh_filter.mesh.vertexCount;
        int tri_length = mesh_filter.mesh.triangles.Length;
        Vector3[] vec = new Vector3[length];
        int[] tris = new int[tri_length];

        mesh_filter.mesh.vertices.CopyTo(vec, 0);
        mesh_filter.mesh.triangles.CopyTo(tris, 0);

        int c = 0;

        List<int> vert_id_list = new List<int>();

        List<Vector3> vec_list = new List<Vector3>(vec);

        List<int> tri_list = new List<int>(tris);

        int i = 0;
        int j = 0;
       
        int cc = 0;
        while (i < length - 1)
        {
            j = i + 1;
            while (j < length)
            {
                if (Vector3.Distance(vec_list[i], vec_list[j]) < delta)
                {
                    Vector3 tmp = vec_list[i];
                    vec_list[i] = vec_list[j] = tmp;

                    vec_list.Remove(vec_list[j]);
                    length--;

                    for (int yy = 0; yy < tri_length; yy++)
                    {
                        if (tris[yy] == j)
                            tris[yy] = i;
                        if (tris[yy] > j)
                        {
                            tris[yy]--;
                        }
                    }
                }
                else
                {
                    j++;
                }
            }

            i++;
        };
       
        vec = new Vector3[vec_list.Count];
        vec_list.CopyTo(vec);
       
        mesh_filter.mesh.triangles = tris;
        mesh_filter.mesh.vertices = vec;
    }
   
}
 
У вас нет доступа для просмотра вложений в этом сообщении.
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Weld вершин

Сообщение gnoblin 14 апр 2010, 21:04

Нашел работающее решение, которое даже учитывает уменьшение количества полигонов.
На джаббаскрипте, правда :) .


Join 4Shared Now!
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Weld вершин

Сообщение gnoblin 03 май 2010, 19:16

Спасибо ffinder'у за идею:

для того чтобы на модельке не было видно шва - нужно всего-лишь выставить одинаковые нормали с одной и второй стороны шва. Тогда даже уменьшать количество поликов не нужно :ymhug: .
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Weld вершин

Сообщение Altodor 14 ноя 2010, 13:14

У меня тоже возникла эта проблема. Я её решил, сделав Weld вручную таким вот кодом:

Код: Выделить всё
void Start () {
      int i,k;
      Mesh mesh = GetComponent<MeshFilter>().mesh;
      Vector3[] vertices = mesh.vertices;
      int[] triangles = mesh.triangles;
      for( i=0; i<triangles.Length;i++)
      {
         Vector3 vertice = vertices[triangles[i]];
         for( k=i; k<triangles.Length; k++ )
         {
            if( vertice == vertices[triangles[k]] )
            {
               triangles[k] = triangles[i];
            }
         }
      }
      mesh.triangles = triangles;
   }


Этот код не изменяет нормалей. Он просто объединяет несколько точек, находящихся в одном месте в одну. Работает быстро, на меше из 10000 поликов тормозов не замечал.
Altodor
UNIт
 
Сообщения: 82
Зарегистрирован: 19 сен 2010, 07:58

Re: Weld вершин

Сообщение gnoblin 14 ноя 2010, 19:08

интересно :-bd .

Я пробовал удалять лишние вершины - похоже что зря).
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Weld вершин

Сообщение Paul Siberdt 14 ноя 2010, 21:09

Дык, недостаточно будет просто удалять лишние вертексы, надо пересчитать новые масивы вертексов, трисов, ювишек и перестроить меш.
Аватара пользователя
Paul Siberdt
Адепт
 
Сообщения: 5317
Зарегистрирован: 20 июн 2009, 21:24
Откуда: Moscow, Russia
Skype: siberdt
  • Сайт

Re: Weld вершин

Сообщение gnoblin 15 ноя 2010, 00:10

ага, в этом и запутался
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Weld вершин

Сообщение gnoblin 09 мар 2011, 02:40

Я недавно видел несложный скрипт, в котором вершины при велде все-таки удаляются.
К сожалению забыл где именно видел :).
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Weld вершин

Сообщение Syberex 09 мар 2011, 09:05

Блин, почему забыл? Это же важно! А так - Спасибо за наработки по теме!
Аватара пользователя
Syberex
Адепт
 
Сообщения: 2292
Зарегистрирован: 14 янв 2011, 20:35
Откуда: Кострома
  • Сайт

Re: Weld вершин

Сообщение Syberex 09 мар 2011, 11:39

А если это будет модель с анимацией и костями, в ней можно будет удалить кусок меша, вставить другой, "свелдить" ... после этого он еще будет ходить? :-?
Аватара пользователя
Syberex
Адепт
 
Сообщения: 2292
Зарегистрирован: 14 янв 2011, 20:35
Откуда: Кострома
  • Сайт

Re: Weld вершин

Сообщение gnoblin 09 мар 2011, 17:25

будет,
в случае с персом по-моему проще выравнивать нормали
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Weld вершин

Сообщение Syberex 09 мар 2011, 19:24

А выравнивать нормали с помощью Юнити или 3д программ?
Аватара пользователя
Syberex
Адепт
 
Сообщения: 2292
Зарегистрирован: 14 янв 2011, 20:35
Откуда: Кострома
  • Сайт

Re: Weld вершин

Сообщение gnoblin 09 мар 2011, 19:57

с помощью скрипта в юнити
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт


Вернуться в Скрипты

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2