Страница 1 из 1

Помогите оптимизировать скрипт (создать циклы)

СообщениеДобавлено: 29 ноя 2010, 23:56
antonio
Не могу разобраться как оптимизировать скрипт. Создать циклы.
Задача такая отсылаю по osc координаты позиции X,Y,Z и вращения X,Y,Z - в Unity эти трансформации надо назначить костям.
Костей 20 поэтому скрипт сильно вырастает если описывать как сейчас. Позиция конечно не для всех костей нужна. Хотя бы для вращения разобраться.
Кто скажет что я лентяй - не могу посидеть подумать - тот будет прав, но если у кого есть время и может помочь - огромное спасибо.
Таким загадочным образом `1...20` и `1...120` я обозначил массивы элементов )
Сами кости будут добавляться уже в интерфейсе public var Bone1 : Transform;
Синтаксис:
Используется javascript
public var RemoteIP : String = "localhost";
public var SendToPort : int = 9000;
public var ListenerPort : int = 8000;
private var handler : Osc;

//Объекты которые будем трансформировать
public var Bone`1...20` : Transform;
//Сюда будем записывать принятые значения для трансформаций position X, Y, Z: rotation X, Y, Z.
private var sig`1...120` : float = 0;

public function Start ()
{      
        var udp : UDPPacketIO = GetComponent("UDPPacketIO");
        udp.init(RemoteIP, SendToPort, ListenerPort);
        handler = GetComponent("Osc");
        handler.init(udp);     
       
        //Выбераем адрес позиции для текущей кости
        handler.SetAddressHandler("/`1...20`/posX", Ex`1...20`posX);
        handler.SetAddressHandler("/`1...20`/posY", Ex`1...20`posY);
        handler.SetAddressHandler("/`1...20`/posZ", Ex`1...20`posZ);
       
        //Выбераем адрес вращения для текущей кости
        handler.SetAddressHandler("/`1...20`/rotX", Ex`1...20`rotX);
        handler.SetAddressHandler("/`1...20`/rotY", Ex`1...20`rotY);
        handler.SetAddressHandler("/`1...20`/rotZ", Ex`1...20`rotZ);
}

function Update () {
        //Записываем вектор позиции
        var ex`1...20`pos = Vector3(sig`1...120`,sig`2...120`,sig`3...120`);
        //Записываем ектор вращения
        var ex`1...20`rot = Vector3(sig`4...120`,sig`5...120`,sig`6...120`);
       
        //Трансформируем данную кость по полученным значениям
        Bone`1...20`.transform.position = Vector3.Lerp(Bone`1...20`.transform.position, ex`1...20`pos, Time.deltaTime);
        Bone`1...20`.transform.eulerAngles = ex`1...20`rot;
}

//Записываем в sig трансформацию для данной кости
public function Ex`1...20`posX(oscMessage : OscMessage) : void
{      
        sig`1...120` = oscMessage.Values[0];
}

public function Ex`1...20`posY(oscMessage : OscMessage) : void
{
        sig`2...120` = oscMessage.Values[0];   
}

public function Ex`1...20`posZ(oscMessage : OscMessage) : void
{      
        sig`3...120` = oscMessage.Values[0];
}

public function Ex`1...20`rotX(oscMessage : OscMessage) : void
{      
        sig`4...120` = oscMessage.Values[0];
}

public function Ex`1...20`rotY(oscMessage : OscMessage) : void
{      
        sig`5...120` = oscMessage.Values[0];   
}

public function Ex`1...20`rotZ(oscMessage : OscMessage) : void
{      
        sig`6...120` = oscMessage.Values[0];
}
 

А это пример для одной кости
Синтаксис:
Используется javascript
public var RemoteIP : String = "localhost";
public var SendToPort : int = 9000;
public var ListenerPort : int = 8000;
private var handler : Osc;

//Объекты которые будем трансформировать
public var Bone1 : Transform;
//Сюда будем записывать принятые значения для трансформаций position X, Y, Z: rotation X, Y, Z.
private var sig1 : float = 0;
private var sig2 : float = 0;
private var sig3 : float = 0;
private var sig4 : float = 0;
private var sig5 : float = 0;
private var sig6 : float = 0;

public function Start ()
{      
        var udp : UDPPacketIO = GetComponent("UDPPacketIO");
        udp.init(RemoteIP, SendToPort, ListenerPort);
        handler = GetComponent("Osc");
        handler.init(udp);     
       
        //Выбераем адрес позиции для текущей кости
        handler.SetAddressHandler("/1/posX", Ex1posX);
        handler.SetAddressHandler("/1/posY", Ex1posY);
        handler.SetAddressHandler("/1/posZ", Ex1posZ);
       
        //Выбераем адрес вращения для текущей кости
        handler.SetAddressHandler("/1/rotX", Ex1rotX);
        handler.SetAddressHandler("/1/rotY", Ex1rotY);
        handler.SetAddressHandler("/1/rotZ", Ex1rotZ);
}

function Update () {
        //Записываем вектор позиции
        var ex1pos = Vector3(sig1,sig2,sig3);
        //Записываем ектор вращения
        var ex1rot = Vector3(sig4,sig5,sig6);
       
        //Трансформируем данную кость по полученным значениям
        Bone1.transform.position = Vector3.Lerp(Bone1.transform.position, ex1pos, Time.deltaTime);
        Bone1.transform.eulerAngles = ex1rot;
}

//Записываем в sig трансформацию для данной кости
public function Ex1posX(oscMessage : OscMessage) : void
{      
        sig1 = oscMessage.Values[0];
}

public function Ex1posY(oscMessage : OscMessage) : void
{
        sig2 = oscMessage.Values[0];   
}

public function Ex1posZ(oscMessage : OscMessage) : void
{      
        sig3 = oscMessage.Values[0];
}

public function Ex1rotX(oscMessage : OscMessage) : void
{      
        sig4 = oscMessage.Values[0];
}

public function Ex1rotY(oscMessage : OscMessage) : void
{      
        sig5 = oscMessage.Values[0];   
}

public function Ex1rotZ(oscMessage : OscMessage) : void
{      
        sig6 = oscMessage.Values[0];
}
 

Re: Помогите оптимизировать скрипт (создать циклы)

СообщениеДобавлено: 30 ноя 2010, 01:51
Paul Siberdt
Неее... вы, батенька, не лентяй... леньтяи пользуют онемацыи. :-B

Первым делом не листинг выводите, а опишите задачу. Наверняка получите несколько альтернативных и более простых решений.

Re: Помогите оптимизировать скрипт (создать циклы)

СообщениеДобавлено: 30 ноя 2010, 13:18
antonio
Хорошо сейчас попробую сформулировать. Есть две программы одна вспомогательная в которой процедурно анимирован скелет и вторая Unity в которой находиться скелет на который надо назначить анимацию с анимированного скелета в вспомогательной программе. Основная задача заключается в том чтобы передать анимацию с одного скелета на другой через osc для этого и создавались макеты )
Приведенный скрипт работает и для одной кости и для двух и будет работать и для всех 20 но размер строк в нем очень сильно возрастает и его можно более грамотно записать - я так думаю, но пока не получилось )

Re: Помогите оптимизировать скрипт (создать циклы)

СообщениеДобавлено: 30 ноя 2010, 13:37
Paul Siberdt
Эээ.. MIDI-интерфейс для передачи данных между машинами? Хе...

Катати, если кости находятся в иерархии (скелет) у них, как правило, не изменяется position, сохраняя нулевое значение.

Создайте массив, равный числу костей, создайте цикл запроса параметров трансформа, пробегите по всем костям, заполните массив и потом разбросайте значения трансформов по косточкам... или напрямую, пробекая по юнискелету запрашивайте трансформы из таинственной программы... Тут скелет любой сложности обернется строчек в 10.

Re: Помогите оптимизировать скрипт (создать циклы)

СообщениеДобавлено: 30 ноя 2010, 14:11
antonio
Да примерно так и пытаюсь разобраться. Не очень уверенно чувствую себя в программировании, но думаю не буду глумить голову форумчанам посижу подумаю поэксперементирую.
Ну это не совсем MIDI. OSC более новый протокол более быстрый и разработан как замена MIDI со временем.
Через OSC могут соединяться не только программы, устройства работы со звуком.
Данные можно упаковать любые float int bool string. Во вспомогательной программе я записываю например для первой кости данные (float) для позиции и вращения по адресам /1/posX... и /1/rotX...
Для последующих соответственно /2.../
Да позиция мне нужна только для одной кости Hips, для остальных вращение.
Программа не таинственная vvvv называется )

Re: Помогите оптимизировать скрипт (создать циклы)

СообщениеДобавлено: 30 ноя 2010, 17:26
antonio
Вот что пока набыдлокодил циклы конечно не работают и голова тоже.
Следующий момент ExrotX и т.д. должны обновлять значеня (из OscMessage) для текущего пути по идее тоже массив %)
Синтаксис:
Используется javascript
%
public var RemoteIP : String = "localhost";
public var SendToPort : int = 9000;
public var ListenerPort : int = 8000;
private var handler : Osc;

private var sigX : float = 0;
private var sigY : float = 0;
private var sigZ : float = 0;

public var Bones : Transform[];

public function Start ()
{      
        var udp : UDPPacketIO = GetComponent("UDPPacketIO");
        udp.init(RemoteIP, SendToPort, ListenerPort);
        handler = GetComponent("Osc");
        handler.init(udp);     
       
        for (var i=0; i<20; i++) {
        //Здесь определяется конкретный адрес
        //в котором потом будут отслеживаться значения в ExrotX, Y, Z.
        //По идее в ExrotX, Y, Z должно извлекаться текущее значение для текущего пути
        //и потом применяться для текущей кости sigX, Y, Z.
                handler.SetAddressHandler(("/"+i.ToString("")+"/rotX"), ExrotX);
                handler.SetAddressHandler(("/"+i.ToString("")+"/rotY"), ExrotY);
                handler.SetAddressHandler(("/"+i.ToString("")+"/rotZ"), ExrotZ);
        }
}

function Update ()
{
        for(var t : Transform in Bones)
        {
                var exrot = Vector3(sigX,sigY,sigZ);
                t.transform.eulerAngles = exrot;
        }
}

public function ExrotX(oscMessage : OscMessage) : void
{      
        sigX = oscMessage.Values[0];
}

public function ExrotY(oscMessage : OscMessage) : void
{
        sigY = oscMessage.Values[0];   
}

public function ExrotZ(oscMessage : OscMessage) : void
{      
        sigZ = oscMessage.Values[0];
}
 

Re: Помогите оптимизировать скрипт (создать циклы)

СообщениеДобавлено: 04 дек 2010, 20:04
hitalik3
Люди такой вопрос может не по теме но всё же.. что лучше использовать анимацию или менять положения костей кодом, например положения человека в машине?

Re: Помогите оптимизировать скрипт (создать циклы)

СообщениеДобавлено: 04 дек 2010, 21:15
antonio
Процедурная анимация пока достаточно ресурсоемкая чем подготовленная по ключам. Ну а если необходимо просто позиционировать персонажа в пространстве то кодом.