как рисовать фрейм вокруг выбранного объекта

Общие вопросы о Unity3D

как рисовать фрейм вокруг выбранного объекта

Сообщение Zavhoz 04 сен 2009, 07:50

никак не могу разобраться с данным вопросом. поискал тут, поискал на англоязычном форуме, везде ссылаются на WorldToScreenPoint через bounds

в итоге, bounds.size привожу к экранным координатам через WorldToScreenPoint
Код: Выделить всё
size = Camera.main.WorldToScreenPoint(myObject.renderer.bounds.size);

что выдаёт невнятные цифры. мало того при вращении камеры вокруг объекта, цифры меняются от положительных (гораздо больше текущего размера экрана), до отрицательных.

понимаю что чтото делаю не так... уже посматриваю на бубен, и пляски с ним вокруг этих фреймов ~x(
может у кого есть пример. хотелось бы посмотреть :-B
FUNNY BLOX
Аватара пользователя
Zavhoz
UNITрон
 
Сообщения: 197
Зарегистрирован: 10 фев 2009, 07:23
Откуда: Караганда KZ
  • ICQ

Re: как рисовать фрейм вокруг выбранного объекта

Сообщение Neodrop 04 сен 2009, 09:32

Хм... Очень странное решение, конвертить размер в координаты. bounds.size это размер. Получить из размера координаты невозможно никаким бубном. Получайте экранную позицию через тот же bound.center к примеру, а уже из комбинации bounds.center и bounds.size и найдёте свой фрейм.
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: как рисовать фрейм вокруг выбранного объекта

Сообщение Neodrop 04 сен 2009, 11:23

Вот, набросал на скорую руку.

В этом примере, при вращении объекта, рамка выделения несколько расширяется иногда. Это от того, что Bounds объектов считаются в мировых координатах и игнорируют вращение.

(c#)
Синтаксис:
Используется csharp
///
//Created by Neodrop
///
using UnityEngine;
using System.Collections;

public class Bounds : MonoBehaviour {

    public GameObject target;
    public Camera cam;
       
        void OnGUI ()
    {
        if(Event.current.type != EventType.Repaint)
           return;
        Vector3 center, size;
        center = target.renderer.bounds.center;
        size = target.renderer.bounds.size;

        Vector3[] vec = new Vector3[8];
       
        vec[0] = cam.WorldToScreenPoint(new Vector3(center.x - size.x / 2, center.y + size.y / 2, center.z + size.z / 2));
        vec[1] = cam.WorldToScreenPoint(new Vector3(center.x + size.x / 2, center.y + size.y / 2, center.z + size.z / 2));
        vec[2] = cam.WorldToScreenPoint(new Vector3(center.x - size.x / 2, center.y - size.y / 2, center.z + size.z / 2));
        vec[3] = cam.WorldToScreenPoint(new Vector3(center.x + size.x / 2, center.y - size.y / 2, center.z + size.z / 2));

        vec[4] = cam.WorldToScreenPoint(new Vector3(center.x - size.x / 2, center.y + size.y / 2, center.z - size.z / 2));
        vec[5] = cam.WorldToScreenPoint(new Vector3(center.x + size.x / 2, center.y + size.y / 2, center.z - size.z / 2));
        vec[6] = cam.WorldToScreenPoint(new Vector3(center.x - size.x / 2, center.y - size.y / 2, center.z - size.z / 2));
        vec[7] = cam.WorldToScreenPoint(new Vector3(center.x + size.x / 2, center.y - size.y / 2, center.z - size.z / 2));

        float xMinf, xMaxf, yMinf, yMaxf; xMaxf = yMaxf = 0; xMinf = yMinf = 10000;

        for (int i = 0; i < 8; i++)
        {
            if (vec[i].x < xMinf) xMinf = vec[i].x;
            if (vec[i].y < yMinf) yMinf = vec[i].y;
            if (vec[i].x > xMaxf) xMaxf = vec[i].x;
            if (vec[i].y > yMaxf) yMaxf = vec[i].y;
        }

        GUI.Box(new Rect(xMinf, Screen.height - yMinf - (yMaxf - yMinf), xMaxf - xMinf, yMaxf - yMinf), "");
        }
}
 
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: как рисовать фрейм вокруг выбранного объекта

Сообщение Zavhoz 04 сен 2009, 19:08

Neodrop, спасибо за отзывчивость и оперативность. :-bd

уж не знаю, к счастью или к сожалению но результат у меня получался такой же... и всё бы хорошо, но есть одно но: при приближении камеры к объекту "в плотную", и уж тем более с измененнием проекции (при этом ни один вертекс объекта не выпадает за вьюпорт), такой метод просчёта фрейма совсем не подходит. рамка рисуется не пропорционально объекту, а как хочет. :-?

пойду поковыряюсь ещё, погляжу англоязычный форум...

вопрос остаётся открытым: возможно ли "корректно" рисовать фрейм вокруг объекта?
FUNNY BLOX
Аватара пользователя
Zavhoz
UNITрон
 
Сообщения: 197
Зарегистрирован: 10 фев 2009, 07:23
Откуда: Караганда KZ
  • ICQ

Re: как рисовать фрейм вокруг выбранного объекта

Сообщение Neodrop 04 сен 2009, 19:26

Я же написал, что размер фрейма зависит от выбранного метода. Используйте локальные координаты трансформа, инвертированные в глобальные. Ну чего тут сложного? Или опять писать не нужный мне код? Всё тоже самое, только вместо bounds - координаты трансформа. 0.5 по X это правая грань, -0.5 это левая и так далее. Чего тут сложного то ? :-?
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: как рисовать фрейм вокруг выбранного объекта

Сообщение Zavhoz 07 сен 2009, 08:36

2Neodrop: рисовать сам фрейм у меня получается на ура :D , а вот посчитать его "правильные" координаты...

для ГО, содержащего всего один объект, получаем bounds.size = transform.localScale, за тем исключение что при приведении к экранным координатам bounds.size = transform.localScale/2.
брать bounds с меша тоже нет смысла, получаем всё тот же куб...

на данный момент в голове осталась только одна "очень бредовая" идея:
1) разворачиваем систему (объект+камера) таким образом, чтобы луч, от камеры к объекту, принял направление (0,0,1)
2) получаем боундбокс
3) переводим в экранные кординаты
4) возвращаем камеру и объект в свои "исходные" позиции

если я не вижу очевидных вещей, то стерплю любой подзатыльник, который повернёт меня в нужное направление.
FUNNY BLOX
Аватара пользователя
Zavhoz
UNITрон
 
Сообщения: 197
Зарегистрирован: 10 фев 2009, 07:23
Откуда: Караганда KZ
  • ICQ

Re: как рисовать фрейм вокруг выбранного объекта

Сообщение Neodrop 07 сен 2009, 11:29

Забыл спросить - объекты то, надеюсь, имеют scale 1x1x1 ?
Многие функции возвращают совсем не то, что ожидается при скеллированной модели.
P.S. относительно алгоритмов : я уже отчаялся донести до вас свои идеи. Не буду более тратить ваше время. :-?
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: как рисовать фрейм вокруг выбранного объекта

Сообщение Neodrop 07 сен 2009, 14:22

Вот это, по-вашему, некорректное отображение фрейма?
Это мой код, написанный выше.
:-w

HTML код для вашего блога :
Код: Выделить всё
<script language='javascript' type="text/javascript"> document.write("<iframe marginheight='0' src='http://unity3d.ru/distribution/player.php?url=ftp://ftp.unity3d.ru/Upload/compositions/bounds.unity3d&w=400&h=300&t=false&preview=1' height='"+(300+30)+"' width='400' frameborder='0' scrolling='no'></iframe>"); </script>
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: как рисовать фрейм вокруг выбранного объекта

Сообщение Zavhoz 07 сен 2009, 17:36

вот я балбес!!!
приношу свои глубочайшие извенения. скрипт работает просто отлично. проблема в модели к которой я прицепился... скале 1х1х1, коллайдера нет, чилдренов тоже нет, а боундинг бокс у неё считается всё равно некорректно. и недосуг же было на других примитивах поразбираться ~x( , пару дней убил на то, чтобы увидеть свою оплошность.

ещё раз спасибо за терпение и понимание ^:)^
FUNNY BLOX
Аватара пользователя
Zavhoz
UNITрон
 
Сообщения: 197
Зарегистрирован: 10 фев 2009, 07:23
Откуда: Караганда KZ
  • ICQ

Re: как рисовать фрейм вокруг выбранного объекта

Сообщение TimmyMulla 09 июл 2010, 16:43

Хороший скрипт. Железная логика :)
Выражаю свое спасибо Neo.

Однако небольшая деталь: вместо bounds.size можно использовать bounds.extents. Тогда не придется делить на 2 везде. Ибо extents = size/2. (нарыл в справке).

Еще раз мерси :)
Аватара пользователя
TimmyMulla
UNец
 
Сообщения: 47
Зарегистрирован: 13 фев 2010, 10:07
Откуда: Екатеринбург

Re: как рисовать фрейм вокруг выбранного объекта

Сообщение Neodrop 09 июл 2010, 18:01

Если подправите скрипт, милости прошу, запостить его здесь.
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: как рисовать фрейм вокруг выбранного объекта

Сообщение bakca 31 мар 2012, 06:56

Исправил на extends. Добавил пару проверок, и отображение текстуры рамки (возможно корявенько) вместо бокса, если назначена.
Спасибо за скрипт.
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;

/// <summary>
/// by Neodrop
/// </summary>
public class GOBounds : MonoBehaviour
{

        public GameObject target;
        public Camera cam;
        public Texture tex;
        public float defaultBoundsHalfSize = 15.0f;

        void OnGUI()
        {
                if (target == null || Event.current.type != EventType.Repaint) return;

                Vector3 center, extends;
                if (target.renderer != null)
                {
                        center = target.renderer.bounds.center;
                        extends = target.renderer.bounds.extents;
                }
                else
                {
                        center = target.transform.position;
                        extends = new Vector3(defaultBoundsHalfSize, defaultBoundsHalfSize, 0);
                }

                if (cam == null) cam = Camera.main;

                Vector3[] vec = new Vector3[8];

                vec[0] = cam.WorldToScreenPoint(new Vector3(center.x - extends.x, center.y + extends.y, center.z + extends.z));
                vec[1] = cam.WorldToScreenPoint(new Vector3(center.x + extends.x, center.y + extends.y, center.z + extends.z));
                vec[2] = cam.WorldToScreenPoint(new Vector3(center.x - extends.x, center.y - extends.y, center.z + extends.z));
                vec[3] = cam.WorldToScreenPoint(new Vector3(center.x + extends.x, center.y - extends.y, center.z + extends.z));

                vec[4] = cam.WorldToScreenPoint(new Vector3(center.x - extends.x, center.y + extends.y, center.z - extends.z));
                vec[5] = cam.WorldToScreenPoint(new Vector3(center.x + extends.x, center.y + extends.y, center.z - extends.z));
                vec[6] = cam.WorldToScreenPoint(new Vector3(center.x - extends.x, center.y - extends.y, center.z - extends.z));
                vec[7] = cam.WorldToScreenPoint(new Vector3(center.x + extends.x, center.y - extends.y, center.z - extends.z));

                float xMinf, xMaxf, yMinf, yMaxf;
                xMaxf = yMaxf = 0;
                xMinf = yMinf = 10000;

                for (int i = 0; i < 8; i++)
                {
                        if (vec[i].x < xMinf) xMinf = vec[i].x;
                        if (vec[i].y < yMinf) yMinf = vec[i].y;
                        if (vec[i].x > xMaxf) xMaxf = vec[i].x;
                        if (vec[i].y > yMaxf) yMaxf = vec[i].y;
                }

                Rect boxRect = new Rect(xMinf, Screen.height - yMinf - (yMaxf - yMinf), xMaxf - xMinf, yMaxf - yMinf);
                if (tex != null)
                {
                        GUI.DrawTexture(boxRect, tex, ScaleMode.StretchToFill);
                }
                else
                {
                        GUI.Box(boxRect, "");
                }
        }
}
 


Текстура например такая как во вложении.
У вас нет доступа для просмотра вложений в этом сообщении.
Аватара пользователя
bakca
UNец
 
Сообщения: 19
Зарегистрирован: 03 авг 2009, 11:10


Вернуться в Общие вопросы

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

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