domingo, 28 de outubro de 2018

Coroutinas em Unity 3D Parte II

As coroutines são funções úteis para implementar tarefas que devem ocorrer ao longo de várias frames.

Neste posto vamos ver como animar a camera de um ponto inicial para outro ponto final com uma determinada duração em segundos. A duração da animação é armazenada numa variável para que possa ser facilmente ajustada.

A função é executada quando o utilizador premir a barrar de espaços.

void Update () {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            if(func!=null)
                StopCoroutine(func);
            func = StartCoroutine(smoothMoveCamera());
        }
}

Precisamos de algumas variáveis:
    public float duration = 2.0f;
    public float xStart = -5.0f;
    public float xFinish = 5.0f;
    Coroutine func;

A primeira define a duração em segundas da animação. A segunda o ponto inicial e a terceira o ponto final, ao longo do eixo dos x.
Por temos uma referência para a coroutina para que seja possível parar a sua execução, se necessário.

O código da coroutina:
    IEnumerator smoothMoveCamera()
    {
        float speed = 1 / duration;
        float percent = 0;
        while (true)
        {
            percent += speed*Time.deltaTime;
            transform.position = new Vector3(Mathf.Lerp(xStart, xFinish, percent),1,-10);
            yield return null;
            if (percent >= 1) break;
        }
    }

Começamos por calcular a velocidade da animação, por segundo, dividindo 1 pela duração da animação. Esta velocidade é, dentro do ciclo, multiplicada pelo deltaTime para ajustar em função do tempo que demorou a desenhar a última frame.
Depois calculamos a nova posição usando a função Lerp com base na percentagem do tempo da animação que já está concluída e interpolando entre o ponto inicial e final.
Depois da nova posição ser definida devolvemos a execução ao Unity, com o método yield, para que possa fazer o render da frame. Depois testamos se a animação já terminou e nesse caso saímos do ciclo.

quarta-feira, 12 de setembro de 2018

Coroutines em Unity3d

Coroutines são funções que mantém o estado enquanto devolvem a execução do código ao método que as chamou.

São úteis para o desenvolvimento de jogos para permitir a execução de determinado código ao longo de várias frames.

Por exemplo para animar a câmara do jogo podíamos executar o seguinte código:

for(int i=0;i<100;i++){
    transform.position += new Vector3(1, 0,0);
}

Se este código estiver dentro de uma função que é executada normalmente não é possível ver a câmara a mover-se ao longo do eixo dos X uma vez que a atualização do cenário do jogo só ocorre no final do ciclo e não ao longo da execução deste.

Para que seja possível ver o movimento da câmara é necessário executar um iteração do ciclo e depois atualizar a cena (fazer o render) e depois continuar a execução do ciclo com mais uma iteração e volta a atualizar a cena, neste caso o que se pretende é interromper a execução e retomar sem que se perca o estado, para isso pode-se implementar uma coroutine.

Uma coroutine não é mais do que um IEnumerator em C#, a seguinte função executa um ciclo com 100 iterações e em cada iteração a câmara move-se um valor ao longo do eixo dos X e depois interrompe a execução por 0,1 segundos. A execução continua com a atualização da variável do ciclo e mais uma iteração.

IEnumerator animaCameraPrincipal()
    {
        for(int i = 0; i < 100; i++) {
            transform.position += new Vector3(1, 0,0);
            yield return new WaitForSecondsRealtime(0.1f);
        }
    }

Esta função é executada assim:

       StartCoroutine(animaCameraPrincipal());

É muito importante não esquecer que como esta função é executada ao longo do tempo não deve ser chamada antes da sua execução estar concluída. Neste caso a execução total do código da função dura 10 segundos (0,1 x 100 = 10).

A coroutine pode ser parada de duas formas:
      - parando todas as coroutines: StopAllCoroutines();
      - parando só esta e para isso tempos de guardar uma referência para a coroutine, assim, Coroutine              funcao=StartCoroutine(animaCameraPrincipal()); e depois parando assim, StopCoroutine(funcao);



terça-feira, 20 de fevereiro de 2018

ASP.NET MVC com Entity, Identity e Migrações Parte 3 - Upload de ficheiros

Na terceira parte deste tutorial vamos adicionar dois controllers e dois models com a possibilidade de fazer o upload de ficheiros para o nosso site.

O model Room é muito simples:

 public class Room {
        [Key]
        public int nr { get; set; }

        [Required(ErrorMessage = "Deve indicar o piso do quarto")]
        public int piso { get; set; }

        [Required(ErrorMessage = "Deve indicar a lotação")]
        public int lotacao { get; set; }

        [Required(ErrorMessage = "Deve indicar o estado do quarto")]
        public bool estado { get; set; }

        [DataType(DataType.Currency)]
        [Required(ErrorMessage = "Deve indicar o preço por dia do quarto")]
        public decimal custo_dia { get; set; }
    }

Agora basta adicionar o controller com a Entity framework.

O Client model:

    public class Client {
        [Key]
        public int ClientId { get; set; }

        [Required(ErrorMessage = "Tem de indicar o nome do cliente")]
        [StringLength(50)]
        [MinLength(5, ErrorMessage = "O nome é muito pequeno")]
        public string nome { get; set; }

        [Required(ErrorMessage = "Tem de indicar a morada do cliente")]
        [StringLength(50)]
        [MinLength(5, ErrorMessage = "Morada muito pequena")]
        public string morada { get; set; }

        [Required(ErrorMessage = "Tem de indicar o código postal do cliente")]
        [StringLength(8)]
        [MinLength(7, ErrorMessage = "O código postal é muito pequeno")]
        [Display(Name = "Código Postal")]
        public string cp { get; set; }

        [DataType(DataType.EmailAddress)]
        public string email { get; set; }

        public string telefone { get; set; }

        [DataType(DataType.Date)]
        [Display(Name = "Data de Nascimento")]
        [Required(ErrorMessage = "Tem de indicar a data de nascimento do cliente")]
        public DateTime data_nascimento { get; set; }
    }

Mais uma vez utilizamos a Entity framework para adicionar o controller:

Para fazer o upload dos ficheiros precisamos de alterar a view create dos clientes assim:

        <div class="form-group">
            <input type="file" name="fotografia" id="fotografia" class="form-control" /><br />
        </div>

O web form também tem de ser alterado:

@using (Html.BeginForm("Create", "Clients", FormMethod.Post, new { enctype = "multipart/form-data" }))

Precisamos do multipart encoding para fazer o upload do ficheiro.

Para terminar temos de alterar a função que recebe o formulário quando é submetido:

 public ActionResult Create([Bind(Include = "ClientId,nome,morada,cp,email,telefone,data_nascimento")] Client client)
        {
            if (ModelState.IsValid)
            {
                db.Clients.Add(client);
                db.SaveChanges();
                //save the file
                HttpPostedFileBase fotografia = Request.Files["fotografia"];
                if (fotografia != null) {
                    string imagem = Server.MapPath("~/Images/") + client.ClientId.ToString() + ".jpg";
                    fotografia.SaveAs(imagem);
                }
                return RedirectToAction("Index");
            }

            return View(client);
        }

Não podemos nos esquecer de criar a pasta Images.

Para podermos ver as imagens enviadas temos de alterar a view index, adicionando uma coluna assim:

        <td>
            <img src="@Url.Content(String.Format("~/Images/{0}.jpg",item.ClientId))" width="100" />
        </td>

Isto tudo está disponível no Youtube


GitHub

domingo, 18 de fevereiro de 2018

TensorFlow Variáveis e placeholders

Neste tutorial vamos introduzir dois novos tipos de nós: variáveis e placeholders.

Depois de importarmos o tensorflow:

import tensorflow as tf

Iniciamos a sessão, mas antes fazemos o reset ao estado interno:

tf.reset_default_graph()
sess=tf.Session()

Agora podemos criar duas variáveis:

x = tf.Variable(2.0,tf.float32)
y = tf.Variable(3.0,tf.float32)

Sempre que se utilizam variáveis numa sessão tensorflow é necessário inicializa-las:

init = tf.global_variables_initializer()
sess.run(init)

Agora podemos definir a expressão matemática a utilizar:

sumnodes = x + y

Agora podemos calcular o resultado da expressão:

print(sess.run(sumnodes))

Para alterarmos os valores das variáveis devemos utilizar a função assign:

sess.run(x.assign(5.0))

Como sempre temos de executar dentro da sessão. Podemos associar esta operação a uma referência o que permite executar várias operações em simultâneo:

NewX = x.assign(5.0)
NewY = y.assign(10.0)

sess.run([NewX,NewY])

Agora, se avaliarmos a expressão o resultado é diferente:

print(sess.run(sumnodes))

Os placeholders têm um comportamento diferente, pois permite mudar o valor quando a expressão é avaliada, podendo ser definido um conjunto de valores (array) que fazem com que o TensorFlow avalie a expressão para cada um de eles.

Assim, criamos um placeholder:

a = tf.placeholder(tf.float32)

Como se pode ver não tem nenhum valor atribuído. De seguida alteramos a nossa expressão para:

sumnodes = x*a + y

Para avaliar a expressão fazemos:

print(sess.run(sumnodes,{a: 10}))

O parâmetro que é passado define o valor do placeholder. Também podemos fazer assim:

print(sess.run(sumnodes,{a: range(10)}))

ou assim:

print(sess.run(sumnodes,{a: [2,5,8,11]}))

Ao trabalharmos com variáveis e placeholders é muito importante não esquecer de fechar a sessão:

sess.close()

O vídeo no youtube


O codigo no Github

segunda-feira, 12 de fevereiro de 2018

Introdução ao TensorFlow - Parte 1

Segundo a Google o TensorFlow é uma framework the software aberto que permite para a computação numérica.

No TensorFlow cada nó pode ser uma constante, uma variável ou uma expressão matemática que utiliza variáveis e/ou constantes.

Estes nós pode ser executados no CPU ou no GPU tirando partido de dispositivos multicore.

Começamos por importar a framework:

import tensorflow as tf

Para criar uma constante fazemos:

node1 = tf.constant(3.0)

ou

node2 = tf.constant(4.0, dtype=tf.float32)

A primeira linha permite ao TensorFlow decidir qual o tipo de dados a aplicar à variável.

Depois temos de iniciar uma sessão TensorFlow assim:

sess = tf.Session()

Para ver o tipo de nó podemos utilizar:

print(node1,node2)

Para avaliar o nó, recebendo o valor que ele contém:

print(sess.run([node1,node2]))

Podemos criar uma função matemática que calcular a soma das duas constantes:

sumnodes = tf.add(node1,node2)

Para obter o resultado:

print(sess.run(sumnodes))

Vídeo no Youtube:


Código no GitHub

Como instalar o TensorFlow no Windows com Anaconda:

ASP.NET MVC com Entity, Identity e Migrações Parte 2 - Dropdown list

Na segunda parte do tutorial sobre MVC vamos adicionar uma dropdown list que permitirá escolher o perfil do utilizador.

No User model temos de adicionar um campo do tipo interface que servirá para passar à view a lista de opções:

public IEnumerable<System.Web.Mvc.SelectListItem> perfis { get; set; }

No controlador temos de editar as funções Create e Edit para preencher a interface com um vetor com as opções de perfis. O código é qualquer coisa assim:

        // GET: Users/Create
        public ActionResult Create()
        {
            //perfis options for the dropdownlist
            var user = new User();
            user.perfis = new[] {
                new SelectListItem{Value="0",Text="Admin"},
                new SelectListItem{Value="1",Text="User"},
            };
            return View(user);
        }

Agora as Views. Apagamos a linha que cria a text box e adicionamos uma linha para gerar a drop down list:

 @Html.DropDownListFor( model=>model.perfil,new SelectList(Model.perfis,"Value","Text"))

Vídeo no youtube



Código no GitHub

terça-feira, 6 de fevereiro de 2018

ASP.NET MVC com Entity, Identity e Migrations

Este tutorial explora o MVC da Microsoft com as frameworks Entity, Identity e migrações para a manipulação da base de dados.

A framework Entity é o que normalmente se apelida de um ORM (Object-Relational Mapping) basicamente é uma forma de armazenar dados de um objecto numa base de dados relacional sem utilizar SQL.

A framework Identity é responsável por gerir as credenciais do utilizador e as permissões de acesso, permitindo que cada utilizar tenha diferentes perfis.

A base de dados é criada com recurso às migrações (método code first), começando por criar uma classe que representa os dados em memória as migrações geram a correspondente tabela na base de dados.

O vídeo com o tutorial


O código no GitHub