Este blog esta em reforma no momento.

Mais veículos

Bom, peguei um freela, e pra não perder a concentração nele, fiz poucas coisas, e variadas.
Enquanto não descubri porque os meus programas CG não compilão (suspeito que seja um problema na versão do OGRE), vamos às modelagens

Como o acervo de veículos estava pequeno resolvi ampliar, agora um patinete.
Lembro dos problemas do Mauricio Cunha, com o oclusion map, aqui tive uns parecidos. O oclusion nos objetos quadrados ficou horrendo e fora de contexto.
A solução foi separar os pedaços do modelo, e criar objetos de alta resolução para servir de referência para o oclusion. O resultado ficou satisfatório ^_^
De posse do material, resolvi fazer uma textura em "radical". Lembrei-me de uns desenhos de skate que vi uma vez, infelizmente não achei até hoje o autor, por issu não vo poder usar os desenhos nas texturas.
Mas, consegui fazer umas coisinhas parecidas, santo Speedy Paint, to melhorando nessa técnica. O SAI é muito eficiente, da p rotacionar o desenho, mover de um lado p outro, sem mecher na matriz original.
A única coisa que esta me deixando irritado aki é o fato dele não receber a pressão da caneta, mesmo o driver do Wine estar indentificando ela a coisa não rola. Estou fazendo testes com a nova versão da Virtual Box, e me recomendarão um tal de Xen (que eu ví é beeeeem complicado).
Estou com um problema de organização, não sei se compensa dividir mais texturas em materiais diferentes, pois não planegei se os objetos estarão disponíveis apenas em uma fase especifica ou no game inteiro. Lógico, vou tentar fazer com que eles possam ser "comprados" a qualquer momento.
Bom, ficou simpático ^_~
A bruxinha na placa é provisória.

Agora parei em uma mobilete, leve-se em conta a simplicidade do motor achei estranhamente dificíl achar uma referência em close do motor!!! Claro, são só 3 peças aparentes, mas as miudezas não achei, vo procurar fotografar uma mobilete. Se alguem puder me dar uma mão agradeço.

Aqui em baixo esta a imagem do artista que estou tentando copiar o "clima", se alguem souber quem é me dá um toque.

Mais um fruto, ferramenta de simetria

Motivado pela preguiça e pelo fato de mais tarde ter que fazer o mesmo esforço em outros elementos do jogo, eu sentei o dedo no Python nessa ultima sexta.
Basicamente este script pega o objeto selecionado e verifica se ele se encontra transpondo as bordas da imagem que irá ser rendida. Como a camera é isométrica e em escala 2x esses limites são de -1 até 1, ou seja, o sistema de cordenadas padrão em uma tela de jogo 3D. Quando o objeto sangra o limite o script o duplica e o coloca na aresta oposta do quadrado. Pode-se pensar que é facil fazer a mão, mas esperimente fazer issu sem ter que fazer conta na calculadora. Assim, surge o terceiro filho do projeto, uma pequena ferramenta para ajudar nas texturas de tile em normalmap.
Observe que o funcionamento deu certinho no resultado final não se percebe emenda.
Não achei nada parecido nas ferramentas ja inclusas, tão pouco tive passiênia para procurar, ha coisas tão específicas que é melhor agente por a mão na massa mesmo.

O código funciona apenas com a biblioteca nativa do Blender, sem necessidade de instalar o Python em si. E não sofreu otimização, ainda apresenta falhas quando se seleciona multiplos objetos, mas já reduz em muito qualquer trabalho.
import Blender
from Blender import *

def simetrize( ob ):
print ob.name
loc = ob.getLocation()
box = ob.getBoundBox()
for b in box: print b

#checa bounds independente da rotacao
minX = 10000
maxX = -10000
minY = 10000
maxY = -10000
print "#" * 8
for v in box:
if (v[0]<minX): minX = v[0]
if (v[0]>maxX): maxX = v[0]
if (v[1]<minY): minY = v[1]
if (v[1]>maxY): maxY = v[1]
print " %s %s %s %s " % (minX, maxX, minY, maxY )

#fora do box 2x2 ?
if (minX<-1 or maxX>1 or minY<-1 or maxY>1):
if (minX<-1 or maxX>1) and (minY<-1 or maxY>1):
#solucao p 2 eixos
if (loc[0]<0):
mvX = -(-2 - loc[0])
else:
mvX = -1+(-1 + loc[0])
if (loc[1]<0):
mvY = -(-2 - loc[1])
else:
mvY = -1+(-1 + loc[1])
#duplica
Object.Duplicate()
sel = Object.GetSelected()[0]
atualLoc = sel.getLocation()
sel.setLocation(mvX, atualLoc[1], atualLoc[2])
#duplica
Object.Duplicate()
sel = Object.GetSelected()[0]
sel.setLocation(atualLoc[0], mvY, atualLoc[2])
#duplica
Object.Duplicate()
sel = Object.GetSelected()[0]
sel.setLocation(mvX, mvY, atualLoc[2])
ob.select(1)
else:
#solucao para 1 unico eixo
#analiza eixo x
if (minX<-1 or maxX>1):
if (loc[0]<0):
mv = -(-2 - loc[0])
else:
mv = -1+(-1 + loc[0])
#duplica para eixo X
Object.Duplicate()
sel = Object.GetSelected()[0]
atualLoc = sel.getLocation()
sel.setLocation(mv, atualLoc[1], atualLoc[2])
ob.select(1)
#analiza euxo y
if (minY<-1 or maxY>1):
if (loc[1]<0):
mv = -(-2 - loc[1])
else:
mv = -1+(-1 + loc[1])
Object.Duplicate()
sel = Object.GetSelected()[0]
atualLoc = sel.getLocation()
sel.setLocation(atualLoc[0], mv, atualLoc[2])
ob.select(1)
Blender.Redraw()

list = Object.GetSelected()
for ob in list:
simetrize( ob )

Coisa Ruim da Silva

Foi numa chuvosa manhã de domingo, com o estomago queimando de tanto café e ouvindo Epica que escrevi esta historia.
Coisa Ruim da Silva, era o primogênito do Grande Senhor Supremo das Trevas. Apesar da origem de “sangue nobre”, Coisa Ruim foi um adolescente revoltado como qualquer um.

Quando seu pai chegou e lhe disse: -Filho, essa terra você há de reinar, sob seus pés os mortais deverão se ajoelhar, que seu nome seja sinônimo de dor e agonia. Que por onde pise, as pastagens morram, e os campos sejam irrigados com sangue. Que seu horizonte seja de terror absoluto com suas legião de “caídos”. Domine a terra, o mar, chegue aos céus diante do trono.... entre outras coisas num belo e magnifico discurso magnifico irrigado pela mais pura maldade.

Mas revoltado, no clímax de sua revolta de um adolescente de 14 anos, Coisa Ruim olhou nos olhos negros do Senhor das Trevas, e com sua revolta encarou aquele olhar de onde emanavam ondas de dor e agonia do mais puro ódio e disse:

-Seguinte “velho”, to de saco cheio com essa historia, nuca foi minha praia. FODA-SE você e esse lance de maldade!

Coisa Ruim saiu pelo mundo, logicamente com seus poderes supremos não tinha de temer nem escuro, nem luz, nem ladrão, nem policia, nem bicho, nem fome, nem sede, nem bala de revolver banhada em vela de sete missas do Galo, nem decapitação, nem NADA!

Entrou em um templo budista, raspou a cabeça e passava seus dias em rezas, praticando boas ações e aprendendo com os monges.

Até que um belo dia foi picado por um pernilongo enquanto meditava, e Coisa Ruim se surpreendeu com sua reação, automáticamente levantou a mão e deu um tapa e matou o bicho. Coisa Ruim, se revoltou de novo, pois há quase 2 anos estava estudando naquele templo, rigado a paz, harmonia e beleza das altas montanhas - Porra! como se distraiu assim!? - se indagou. Naquele instante arruinara sua promessa de nunca mais fazer mau a nenhum ser!?

Ao concluir que finalmente achou que a raiz de sua revolta estava dentro de si mesmo, Coisa Ruim se dirígio ao grã-monge, pediu perdão por não ter aprendido seus ensinamentos e concluiu que não podia ficar mais naquele lugar sagrado pois ainda tinha “sangue nos zóios” e “pavio curto”. Decidiu, por sua própria lei, sair de novo pelo mundo até achar seu destino.O monge pediu desculpas por seus ensinamentos não serem o bastante para ajudar o pobre rapaz, e para não deixar que tudo tivesse sido em vão, deu-lhe uma tábua com um mantra gravado. Um poderoso mantra que tanto servia para proteger Coisa Ruim das maldades, como para lembrar-lhe que um dia esteve perto da iluminação. Claro mau sabia Coisa Ruim, que na origem mistica dos sons das palavras há também vários segredos, e um desses estava ali escondido, mesmo aos olhos dos iniciados!

Com o tempo Coisa Ruim foi se esquecendo dos ensinamentos, deixou o cabelo crescer, passou a se envolver em brigas, a corromper-se com mulher e cerveja. Derrepente se cansou e largou das brigas (afinal ele SEMPRE ganhava, são poucos que conseguem pulverizar os outros com golpes de colunas de fogo). Logicamente ele não largou das mulheres e cerveja.

Arrumou uma Harley tunada, e saiu pelo deserto, a procura de seu caminho.

Esta nele até hoje, virou uma figura lendária e folclórica, como o motoqueiro negro, hora contado como demônio justiceiro hora descrito como espirito traiçoeiro sempre disputando racha com quem acha-se pelo caminho, e punindo os perdedores....

Quem quiser e tiver coragem de procurar esta figura, basta ir rumo a rota 666


^_^

Eu realmente gostei desta história, o personagem pensei ha mutio tempo enquanto preparava os modelos, e evoluí ele de um ser estranho que andava pelas ruas com um sobretudo para um corredor selvagem. A idéia dele ser um demônio tão revoltado que deidiu ser bonzinho tive nessa manha. E apesar do toque comico, acabou que eu achei que surgirão umas coisas bonitas no meio dela.
Coisa Ruim é um personagem que pode ser bem explorado.

Um possivel dialogo:
(na casa do Coisa Ruim)
Cibele: - Ow! Seu Coisa Ruim, tem uma pilha de um metro de lata de cervaja no meio da sala!
Coisa Ruim: -Não liga, a empregada vem toda terça a tarde e limpa.
Cibele: -Más hoje é quarta!!!
Coisa Ruim: -Uhm. É que amanheci com sede hoje.

Curiosidades:
  • Coisa Ruim não abastece no posto, quando a gasolina acaba corta o pulso e enche o tanque (alcool e fator de cura são realmente bençãos)
  • Mágias e simbolos divinos não afetam Coisa Ruim, afinal esses ítens só servem contra o mal
  • Mágia negra e ítens sombrios são piores pois deixam ele mais forte
Bom, acho que posso aproveitar a
Estou com poucas referências de imagens, por incrivel que pareca não acho aquelas Harley com aspecto exagerado. Mas acho que a tunada deve ser o suficiente
Referencias

Correções e mais objetos


Bom, esta lista de ítens é a parte fundamental do jogo. Cibele tem que juntar todos eles para salvar o planeta da mortifera Bunda-Assassina-do-Espaço-Cideral.
Notem que existe um certo gráu cadavério de dificuldade para se conseguir cada um. Calma ela ira contar com a ajuda de um poderoso arque-mago, que eu apresentarei nos próximos posts.
Cada ítem gera uma aventura de caracteristicas únicas, e se possivel um nó mental em quem estiver jogando.
Coloquei um ícone de joypad do lado, para demostrar como seria a interação do usuário. Pretendo fazer o jogo jogável pelo joypad.

http://docs.google.com/Doc?id=dddvrrg4_7cd9w8f2v
Estou comecando a usar o Google Docs para toda a documentação do projeto, além de me dar liberdade de escrever em qualquer lugar aproveitando tempos livres e inspirações momentâneas, posso publicar os documentos como páginas. Permitindo o acompanhamento do projeto.
Logo porei do lado do blog uma lista com os links dos documentos.

Corrigindo de novo e de novo.
Bom, por indicação da Carla (trabalha comigo e foi organizadora do Animeguara), troquei a cor do urso de rosa por amarelo. Logo depois o Mauricio Cunha do Forum da PDJ me sugeriu bege, mas como eu ja tinha alterado por amarelo e uma opinião feminina nessas horas é rara, deixei amarelo.
Por falar nissu, interessantes minhas estatistias no youtube, a mulherada é cerca de 7% do pulico, cinal que elas ainda não tem um grande interesse por games e 3D, que pena.
Seguindo ainda as dicas do Mauricio (mcunha98), eu tentei pintar mais marcas de dobra no tecido. No entanto fiquei com preguiça de pintar e usei o sculpt do Blender pra gerar o oclusiomap e sobrepuz na textura. Oque acham?

Esse fim de sabado criei mais alguns objetos, quero montar uma vendinha, clássica em jogos de RPG, onde a personagem pode comprar alguns itens. Se não der, também posso utiliza-los no jogo como opcionais no cenário.
O cavalinho-de-páu, um "crássico", eu sériamente pensei em fazer simplezinho com 1 textura de 256x256 apenas. No entanto lembrei que deveria ser usado pela personagem principal e resolvi melhorar os detalhes. São duas texturas de 512x512, no entanto elas podem ser redimencionas pra 256x256 que provavelmente não vai perder qualidade. Fiz uma coisa diferente, para não ter que usar uma textura de alpha, dupliquei as faces da correia e inverti suas normais.
A idéia é que ele conceda um bônu de movimento de 15%. Não teria lógica em se gastar dinheiro apenas por ver ela trotando num cavalinho-de-pau, né.
Agora a péroloa, um PogoBall!!! Uhulll, infância 80 extreme retro-core ^_~
Bom, eu acho q um aumento de 7% no movimento seria coerente. Além de poder ver o vestidinho pulando nos saltinhos ^_^
Uma coisa legal, eu parti de uma UVSphere normal, e depois apliquei o decimate. Acabou que o decimate não proporcionou uma deformação muito drastica num valor de 0.75, depois foi só acertar os triângulos.

Fim de semana rendeu

Bom, ao menos a fada esta menos pior de mapeamento. Deu bug no meio do processo do normalmap. Tive que refazer o sculpt 5 vezes. Segui uns conselhos do Mauricio Cunha e do Rodrigo e acertei bastante a mão.
Eu também fiz o rig, depois vou por ela no youtube.

Comecei também com alguns objetos de cena. alguns foram bem simples. A cadeira é que deu mais trabalho. Pena q no Blender não há como cortar faces por faces (não q eu tenha tido despreguiça de procurar um script p issu).
Fis também a caminha, achei mais lógico um simples colchão surrado, afinal Cibele é praticamente uma eremita vivendo da venda ocasional de hervas, sem muita grana pra móveis.
Eu fico muito duvidoso sobre a real quantidade de poligonos que podemos usar. Fala-se em economizar, mas mais e mais veem saindo consoles potentes e o hardware grafico também não fica atráz, mesmo em maquinas mais modestas. Eu jogava Fable na minha GeForce 5200, sofria mas jogava.
Resolvi dar uma arredondada mais decente na orelha, e não me preocupei muito com a perna.
Este urso deve ter ficado em uns 200 tri, eu n ontei.


Eu ja devo ter postado isso, não lembro, sobre a dificuldade de acertar a cor. Hj consegui uma foto mais realista do problema. No entanto não sei ainda. Vou essa semana mandar revelar a foto, impressa a percepção das corer é muito maior (infelismente também depende de onde vc revela).
Deu trampo issu, tive que montar a camera num tripé, e ficar testando várias configurações. Essa foto ai foi batida em quase 1 segundo (1/2 na verdade) de exposição, por issu não aparece aquela mancha do monitor de tubo, a imagem dele foi se acumulando na foto.
Bom, ainda tive q Gimpear a imagem p regular a itensidade da cor, ainda ta uns 90~95% doque realmente vejo, supondo-se que não sou dautonico.
Informações da propria camêra:
Tipo de imagem: jpeg (Formato de imagem JPEG)
Largura: 1680 pixels
Altura: 1260 pixels
Marca da câmera: FUJIFILM
Modelo da câmera: FinePix S9100
Data da foto: 2009:03:28 16:07:45
Tempo de exposição: 1/2 seg.
Valor da abertura: 6,60 EV (f/9,8)
Taxa de velocidade ISO: 200
Flash disparado: Flash did not fire, compulsory flash mode.
Modo de medição: Padrão
Programa de exposição: Manual
Distância focal: 7,6 mm
Aplicação: GIMP 2.6.1
Copyright: Marcos Augusto Bitetti


Agora oque rendeu mesmo é o material para o próximo post, na noite de sabado fiz um sketch, e na manhã de domingo escrevi a história. Eu ainda preciso estudar bem mais sobre a arte de escrever, pois a ideia era cada personagem ser apresentado de um geito. Mas o concept ficou legal ^_^
Aguardem....

Lime

Bom, mais uma semana e mais um personagem.
Houve um atraso, mais foi por um bom motivo. No entanto, ja fiz muita coisa nesta! Estou realmente pegando o jeito. Ja não olho mais para o "unwrap" do Blender com os mesmos olhos, agora olho com olhar de fascinação por essa santa ferramenta!

Após o sculpt passei a demarcar o grosso da pintura no Gimp, e posteriormente passei ao Blender onde dei os ultimos retoques nos detalhes da textura. Resolvi fazer as extremidades e pintas rosas, como se fosse um pequeno animal (Ramister me inspirando).
De fato ela é muito pequena, por issu dei uma economizada nos poligonos. E por sorte o exporter da OGRE tem uma regulagem de LOD conforme a distância, que irei reduzir em 10 vezes para esta personagem. (LOD - Level Of Detail - Diminui a quantidade de poligonos conforme a distância).
Aqui também não aparece a textura da asa, eu estou dividindo os personagens em materiais solidos e transparentes. Isso porque o transparente necessita de uma textura para alpha, e alguns parâmetros diferentes de configuração.
Bom, com certeza eu exagerei nos detalhes, mas eu me empolguei... acontece muito.
Infelizmente o normalmap ficou, digamos,... um lixo. Vou ter q refazer. Quem sabe até aumente os olhos.
Ela acabou ficando bem acima de onde eu queria chegar, tem 1218 triangulos de malha. Para um ser que inicialmente seria nada mais doque uma lamparina é muito. Mas pretendo justificar esse excesso, com as funcionalidades da fada.

Ela sera uma ajudante, seus poderes incluem iluminar o ambiente e partilhar a visão (espionagem).

Descrição da raça
Essa é uma fada hematofaga (sim por tráz da carinha de santa há uma vampirinha), de constituição frágil e pequena estatura, entre 5 à 10cm no máximo.
Possui habilidades bioluminescentes(gera luz e alguns exemplares podem produzir um laser), habilidade empatica (precebe emoções), e é capaz de desenvolver uma forma limitada, mas extremamente eficiente, de telepatia com seu possuidor (partilhar a visão e audição).
Sua natureza hematofaga gera uma relação de dependência e lealdade muito grande com o dono.
Manter uma dessas não é muito fácil, consome 1HP a cada dia, e mais 1 ou 2 HP para se regenerar em caso de batalha. (NOTA: Dados não oficiais até eu terminar o sistema do jogo)
Para obter uma exemplar, além de conseguir encontrar alguem que possua uma "rainha", esta mesma rainha deve aprovar a pessoa. A capacidade empatica da rainha e seus instintos são capazes de determinar se um individuo é virtuoso o suficiente para confiar um de seus filhotes.
Com excessão da rainha, todos os outros indivíduos são asexuados. Oque leva pesquizadores a crer que algum dia essas fadas viviam em colonias. Obviamente perderam isso ao serem domesticados pelos homens.

As origens
Faz anos e anos e anos (1999-2001), reparem que o scan ta um lixo, foi feito na primeira escola de informática que dei aula a Good Friends. (Escola legal, scanner fraco ehhehe)
Foi durante uma aula do curso Técnico em Segurança do Trabalho, eu copiando a matéria, pensando em matar o resto da aula pra conversar no corredor... surgiu o primeiro esboço e a idéia dela se alimentar com sangue pra gerar o vinculo. (de certo, foi bom não exercer a profissão. Ja pensou eu com o peão: -Olha, se você não usar um EPI pode ter um braço arrancado pela máquina, e do geito que estou estressado se não por essa coisa agora... eu mesmo arranco)
De inicio progetei-lhes como uma colmeia, uma enorme colônia, com poderes de projetar raios laser e com dois individuos especiais. Um soldado e um guardião.
O soldado é essa em baixo, com espinhos e pontas afiadas, mais resistencia, e uma cauda de escorpião, e carinha de mau para deixar claro a sua função.
O guardião é uma com aparência de anjo, com escudinhos. Só que não devo ter o scan desta, e nem imagino onde diabos meti a folha com os desenhos.
Uma fatidica constatação... esqueci de fazer as antenas! Mas tudo bem, sobrou algum espaço nas texturas de alpha. Vou corrigir esse engano, mesmo porque tenho q mecher nesse normalmap tosco.
Elas serião usadas em um fansine maior que eu planejava fazer. Onde serião guardiãns em uma sala do grande-ultra-mega-fodão-chefão do mau da saga.
Quem sabe eu consiga mais tarde em alguma expanção criar e usar os outros dois individos da familia da Lime.
Um pequeno Flas que fiz a muito tempo, credo, Flash 5 ainda!

Antes que me perguntem, porque o nome Lime se a bendita raça tem uma rosa na cabeça?
Bom, uma boa coisa é dar esse pequeno nó na cabeça de quem joga. Afinal se o jogador pensar, eu favoreço a interação ^_~
E o nome Lime vem de Lime mesmo, na época eu estava assistindo Saber Marionet J. Assistão, é um anime antiguinho mais muito bonito. link1 e link2

Programar programar programar

Novas "features" do exporter:
Metodo appendAnimation()
Agora todo objeto que estiver marcado com IPO sera exportado com um bloco de animação.
O objeto também podera conter propriedades especiais como:
nomevalor
autostarttrue/false
looptrue/false
firsframeint/string
lastframeint/string
frameliststring:endereco_de_arquivo.txt
callbackstring
A intenção é montar um sistema de animação independente, para atender os cinematics.
Uma coisa chata é a curva IPO, descobri que não tenho um pingo de paciência para fazer os malditos calcúlos das curvas.
Mas sei que da pra fazer a equação entre frames fácil (aquela que você calcula a diferênça entre um frame e outro por causa do framerate elevado).
Outra coisa perigosa é que não sei como vai ser a nova API do Blender, dizem que as curvas IPO vão ser descartadas.
Bom, outra vantagem é o framelist, que aponta para um arquivo com endereços de animação. Onde cada linha tem um numero inicial, um final e um label para a animação. Eu poderia usar o sistema de Actions do Blender para issu, no entanto acho que esse caminho é mais simples de início. Mesmo porque ainda não sei oque vira na API do 2.50.

Nas próximas implementações eu irei ver se consigo obter os dados do filtro Constraint. São muitos filtros, e alguns deles não interesão. Na verdade oque deve ser mais usado é o "Track to", que vai se traduzir em um simples "Look At" dentro da OGRE, assim poderei ter cameras estratégicamente posicionadas em cena seguindo o personagem.

Enquanto ia ao banheiro pensei em um pequeno acrescimo para futuras expansões, um campo para chamar uma função callback. Inicialmente achei que ia ser util para animação dinâmica. No entanto ja é previsto que isso seja feito via código naturalmente. Então ficaria redundande. No entanto achei uma finalidade: chamar uma callback informando o frame e o objeto que esta sendo animado. Assim posso disparar eventos em determinadas sircunstâncias.
A cada frame registrado, é enviado a função definida em callback, esta passa dois valores, o lua_userdata do objeto e o lua_number do frame corrente. Uma utilização seria:
function cameraActIntro( ob, frame )
if frame >= 90 then
displayControl.setVisible( true )
else
displayControl.setVisible( false )
end
end
Também implementei melhorias nos objetos, agora ele serializa os objetos em cena antes de mandar pro xml. Assim acaba-se o erro de um objeto pedir um pai sem que o pai seja instanciado.
Uma coisa curiosa sobre o Python, olhei no meu manual e nada, mas não achei um método para pegar o indice de um dado elemento dentro de listas. Acabou que fiquei com pressa de procurar solução no Google e meti uma função para fazer issu, já que a melhor que o método index(valor) precisava estar num TRY para funcionar.
Depois com calma vasculhei o Google e... não é que essa é uma solução que o pessoal realmente utiliza! Curioso a linguagem não ter um indexOf.
Ainda não olhei com calma, ou bons olhos, o Python 3.0 pra saber se issu foi alterado.
O proximo passo agora é dentro do C++, onde deverei inserir uma classe Frame para interpolar valores, e jogar direto na Camera.

Ufah! Esse hoje foi bem técnico, acho que ninguem leu até o fim. Para os que tiverem saco para ler olhem esse endereço (é de onde vem meu papel de parede): www.brianhamner.com

Mais um inimogo

Crendespaldo
Vamos introduzir o conceito, o Dr Raph And Zody (eu estava ouvindo Raphzody quando pensei no nome) era um funileiro que conseguiu chegar ao ultimo ano de faculdade.
No entanto seu T.C.C. não agradou muito a banca, pois se tratava de um projeto que visava trazer tecidos mortos de volta a vida por vias eletro-mecânicas.
Os seus companheiros de classe o chamaram de louco, no entanto apenas quando ele resolveu explicar os motivos de porque não era louco e porque seu projeto tinha tudo para dar certo para uma samambaia, o corpo doscente resolvel internalo num manicômio.Anos depois, muitos mesmo ao ponto dele ficar velinho, ele foi solto e descobriu sua fabriqueta aos pedaços.
No entanto seu laboratorio ainda estava intacto, e não foi dificil achar material para suas experiência pois havia uma pequena guerra civil na cidade próxima.
Surge assim o MC-100107 ou Crendespaldo, o Dr Raph And Zody deu lhe esse apelido porque todos que o olhavam diziam: - CRENDESPALDO!!!!!!!
Como pode-se imaginar Crendespaldo não é um modelo de fino acabamento, feito com materiais precários, um motor de um caminão velho, uma batedeira usada de 1930, umas valvulas de TV velha e umas sobras de pizza e um topete emo, juntando e controlando pedaços de corpos rescurrectos as preças antes que os urubus começem as sobras.
Raph And Zody usa Crendespaldo para pilhar as cidades visinhas, e criou um pequeno exercito de automatos para defender sua "fortaleza".
Ele agora pensa em vender os direitos para Hollywood e enriquecer com a historia do terrivel monstro assassino.

Scripting materials

Consegui resolver o problema da multitextura sem precisar programar em GLSL. No entanto ainda vou usar issu como alternativa, assim que eu descobrir como pegar as texturas dentro do shader.
A alternativa GLSL ainda pode ser bem util porque o framerate caio bastante, de 120 para 80 com todas as texturas e mapa de iluminação.
Uma grande vantagem no sistema de materiais do OGRE são as thecniques, o mesmo material pode ter varias. Cada thecnique apresenta um conjunto de efeitos, o OGRE em tempo de execução, escolhe qual a thecnique mais adequada para o hardware, então eu posso produzir várias para garantir que se a placa gráfica vai exibir com dada precisão oque eu quero.
Isso também é uma mão na roda para gerar desempenho. Por exemplo, posso aplicar uma thecnique com normalmaps mais perto da camera e uma sem ao longe.Esse normalmap ta dando um boooom trabalho. Pois cada elemento que coloco na borda tenho q fazer uma conta para colocalo na borda oposta.
Da trampo, mas fica bom. A melhor solução que encontrei é curiosa, pois é uma téquinica antiga desenvolvida antes do blender ter recurso de renderizar para textura. Onde a camera é posta em ortogonal com escala de 2 (um plano em OpenGL geralmente vai de -1 até 1) e o material usa 3 texturas de blend nos eixos x,y e z. Essa textura vai ser usada no terreno da terceira ou quarta fase.

Os parametros de textura são muito poderosos. Pode-se definir detalhes doque sera feito na pipeline como se estivesse usando os nodes do Blender.
Apartir de agora so uso o Blender para marcar o material no exporter. Todo o trabalho de definição é feito no Notepad++.
Esse fogo deu umas duas horas lendo e preparando até eu acertar. Mas ficou muito bom o resultado, 8 triangulos, bem menos que um cubo e sem nenhum sistema de particulas. E são só 4 texturas 64x64 em jpeg.
material fogo01
{
receive_shadows off
technique
{
pass
{
lighting off
cull_hardware none
cull_software none
scene_blend one one_minus_src_colour
depth_func less_equal
depth_write off
texture_unit
{
anim_texture fogo_frame_1.jpg fogo_frame_2.jpg fogo_frame_3.jpg fogo_frame_4.jpg .5
tex_address_mode clamp
filtering trilinear
colour_op modulate
}
}
}
}

Meu exporter do Blender também evoluio um pouco, resolvi muitos dos problemas de posicionamento. Mas ainda ficaram para traz algumas questões de rotação e escala.
Oque complica na verdade é a versatilidade, crieu o script de forma que tudo que tiver a propriedade "actor" ativa seja considerado objeto dinâmico. Ja os outros são transformados em "static geometry". O problema é que a geometria estatica não aceita as transformações hierarquicas por si só, então tenho q posicionar os objetos no braço dentro do C++.
O OGRE tem bastantes recursos para issu, classes Vector, Quaternion e Matrix. No entanto o Python do Blender parece ter bem mais funcionalidades.
Mas o desenvolvimento esta ficando bem agíl. ^_~

Primeiro walk-cicle, mais problemas e café

Bom, calor do verão gerando um stresse na hora de trabalhar, exportação sem recursos, problemas no rig, sistema dando pau ao usar recursos avançados (monitor em clone, wine com tablet, memoria indo pro saco...) em resumo "tudo normal para um ambiente de produção".
Até o presente momento, comparado a minha experiência em agências, não estou sentindo nenhuma diferênça em relação ao "ruwindows". A não ser é claro os softwares mais bombados, como o After Effects para mecher com video eo Flash para animação.

Comecei a animação de Aracne, gente, como esse bichu dá trabalho! Fiz por enquanto um walk-cicle simples, o proxímo passo é ela correr.
Considerei um frame-rate de 30fps para a animação. Alguns bugs no wheight-paint ainda ocorrem e umas deformações estrenas nas pontas dos dedos ocorrem no Blender. Vamos ver o resultado quando exportar para o OGRE.
Os braços acho que ainda estão meio durões, não sei se deixo ela mais solta, Aracne deve aparecer um pouco mais durona, ja que é meio amaldiçoada.

Como dito no post anterior, o exporter n salvou a multi-textura, eis aqui o resultado dentro do engine
Comecei a caçar (finalmemte) tutos de GLSL, e consegui meu primeiro Hellow World GLSL!
void main ()
{
vec4 modelVM0 = gl_ModelViewMatrix[0];
gl_FragColor = vec4( modelVM0[0], modelVM0[1], modelVM0[2], 1.0);
}
esse script faz a cor de desenho corrente mudar em relação ao ângulo da camera.
Bom, uma outra alternativa, vou baixar o código fonte do Blender, lá deve ter os arquivos glsl responsáveis pela multi-textura, vai ser uma boa base.
Esse blog também parece ser interesante http://blenderecia.orgfree.com/index.php/blender/2d-filters-glsl-e-custom-textures/

Bom, infelismente para os amantes de Windows, eu me concentrarei no GLSL, o OGRE tem suporte à HLSL para o DirectX, mas por motivos de tempo vou fazer tudo primeiro para a OpenGL, depois esturadei a transição de código.

PS.: http://linux.softpedia.com/get/Multimedia/Audio/Ogv-to-Flv-Converter-41863.shtml
Este script é uma mão na roda, pra quem não tem a menor paciência de ficar digitando e lembrando comando de console. Tem umas falhas, quanto as resoluções serem pra monitor quadradão, mas nada que uma mechida no código não resolva.

Os problemas hardcore começaram

Pois é minha gente, domingo de carnaval, minhas buscas pelo Orkut, bate-papo UOL e afins, n renderam nenhuma menina com parafilia por lobsomens cabeludos, meus amigos ou estão espalhados pelo mundo, ou se preocupando com suas respectivas "donas maria", então aqui estou eu frente ao possante onde as mulheres tem orelhas grandes e em alguns casos presas.
Bom, enquanto recuperava minhas forças no sabado, antes de começar a animar Aracne, comecei o cenário da primeira cena.
Fiquei realmente impressionado com o novo sistema de texturas e materiais da GE do Blender, usando massivamente GLSL as coisas ficaram realmente brutas! A ferramenta "Texture Paint" consegue pintar mesmo com normalmaps ativos e o suporte a multi-textura esta realmente ótimo.A multi-textura esta me rendendo uma aparênia mais real do ambiente. Essa textura de pedra realmente ficou um lixo, mas a grama esta boa, como podem ver abaixo.Só preciso tirar uma ou duas dessas florzinhas vermelhas, elas denunciaram o "padrão" da textura.
Outros elementos como arvores, pedras e arbustos, darão o acabamento final. Talvez eu subdivida essa malha para mais algus detalhes e separar outros materiais.

A desgraça começa!
Infelizmente para minha desagradavel surpresa, o filtro do OGRE ainda n se adaptou as novas features do Blender ~_~
material terreno
{
receive_shadows on
technique
{
pass
{
ambient 0.500000 0.500000 0.500000 1.000000
diffuse 0.640000 0.640000 0.640000 1.000000
specular 0.068839 0.068839 0.068839 1.000000 12.500000
emissive 0.000000 0.000000 0.000000 1.000000
texture_unit
{
texture grama_mesclagem.png
tex_address_mode wrap
filtering trilinear
colour_op alpha_blend
}
}
}
}
material agua
{
receive_shadows off
technique
{
pass
{
ambient 0.500000 0.500000 0.500000 1.000000
diffuse 0.640000 0.640000 0.640000 1.000000
specular 0.500000 0.500000 0.500000 1.000000 12.500000
emissive 0.000000 0.000000 0.000000 1.000000
}
}
}
Nesse arquivo de parâmetos pode-se ver que é passado apenas a textura usada no mapeamento UV. Oque me deixou cabreiro pois lembro que nos testes anteriores obtive uma exportação melhor. No entanto ainda não estava usando a multi-textura tão massivamente.
Foram 3 texturas de 512x512 e mais duas de 1024x1024 para o mapeamento stencil.
Em ultimo caso, terei que mecher no sistema interno da OGRE, posso talvez dispensar o sistema de rendering de geometria dele para implementar o meu propŕio, afinal ja tenho alguma coisa pronta.
This is Sparta!!!

Novo header

Bom, como essa ultima semana fiquei dodoi, peguei um freela e tinha uma montagem de foto p fazer, n produzi nada pro game diretamente.
Mas ai no tempo vago, resolvi instalar de vez o suporte a Flash no Linux. Infelizmente a melhor IDE depois do FlashDevelop é o Eclipse com ASDT que infelizmente é pra ActionScript 2.
Me recomendaram o VIM, mas não estou "pegando bem" com ele não. Ainda não achei onde tem a complementação de código e outras coisas importantes. Mas usei ele para gerar um html colorindo o código descentemente (claro, tirei muitos
e do resultado).

O novo header é feito 100% em Flash OpenSource, a única coisa que ele acrescenta é um efeito especial bobo mas muito simpático que desenvolvi nas horas vagas enquanto estudava o código do efeito "lake".
Ele se aplica melhor escondendo o fundo, como podem ver aqui com a menina de Final Fantasy, mas dá um bom acabamento do geito que esta no blog.
Para os céticos que não acreditam na existência de Flash fora do Windows, aqui vai um mini-tutorial:
1) Baixe o Flex SDK 3 ou superios (no link acima tem o endereço);
2) Use um editor descente, se for usar AS2 o do tutorial do link acima é perfeito. Usei o VIM aqui;
3) Aqui esta o código usado no filme principal e no botão com a logo da Creative Commons:

package
{
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.events.Event;
import flash.display.BlendMode;
import flash.filters.DropShadowFilter;
import Effect02;

/**
* class Main
* @author Marcos A. Bitetti ( marcosbitetti@gmail.com )
*/

[SWF(width='700', height='378', backgroundColor='#aaaaff', frameRate='16')]

public class Main extends Sprite
{

// Insere imagem da capa
[Embed(source="../../capa_01.jpg")]
private var Capa:Class;

public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}

private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point

addChild( new Capa() );

// Insere link do Creative Commons
addChild( new CC() );

//título do blog com sombra
var txt:TextField = new TextField();
txt.selectable = false;
txt.autoSize = TextFieldAutoSize.LEFT;
txt.htmlText = '<font size="78" color="#f2984c">Wild Witch Project</font>';
txt.filters = [ new DropShadowFilter(4,45, 0x000000, .8, 4,4, 1, 2, false, false ) ];
addChild( txt );

//aplica efeito especial
var efeito:Effect02;
addChild( efeito = new Effect02(.4) );
efeito.blendMode = BlendMode.SCREEN;

}

}

}

Umas diferenças importantes, aqui nós configuramos diretrizes de compilação usando [ ] no código:
[SWF(width='700', height='378', backgroundColor='#aaaaff', frameRate='16')]
(sim, uso 16 frames por segundo, poderia usar 20 mas achei mais garantido 16 para rodar em qualquer maquina. Nunca uso framerate acima dos 30, é pura idiotice pois ao contrário doque um monte de desavisado por ai pensa você não ganha qualidade na animação, apenas perde processamento inutilmente - seu monitor so exibe 30~34 fps e NADA mais)

[Embed(source="../../capa_01.jpg"), mimeType="image/jpeg"]
aqui é a biblioteca, posso apontar qualquer tipo de arquivo, basta informar o tipo mime dele: application/octet-stream, image/gif, image/jpeg, image/png, text/plain, text/xml, etc

package
{

import flash.display.Sprite;
import flash.display.DisplayObject;
import flash.text.TextField;
import flash.display.Graphics;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.URLRequest;
import flash.net.navigateToURL;

/**
* class CC (Creative Commons)
* @author Marcos A. Bitetti ( marcosbitetti@gmai.com )
*/
public class CC extends Sprite
{

// Insere imagem da CC
[Embed(source="../../88x31.png")]
private var _CC:Class;

public function CC():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}

private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
var cc:DisplayObject;
addChild( cc = new _CC() );
cc.x = 200;
cc.y = 2;

//desenha retângulo de fundo
var g:Graphics = this.graphics;
g.clear();
g.beginFill( 0x000000, .5 );
g.lineStyle( 1,0xffffff,.4);
g.drawRect( 0,0, cc.x+cc.width+2, cc.height+4);
g.endFill();

//Texto Informativo
var tx:TextField = new TextField();
tx.selectable = false;
tx.multiline = tx.wordWrap = true;
tx.htmlText = '<font size="14" color="#ffffff"><b>Projeto de game estilo mangá</b></font>';//tosco usar font, + é mais repido dq criar um object Steele Sheet
tx.width = 198;
tx.height = cc.height+2;
addChild( tx );

//Põe em cache como imagem para n ser renderizada de novo
cacheAsBitmap = true;

//monitora redimensionamento
stage.addEventListener( Event.RESIZE, resize );
resize( null );

//deixa como botão
useHandCursor = true;
buttonMode = true;
addEventListener( MouseEvent.CLICK, licenca );
}

private function resize( e:Event ):void {
x = stage.stageWidth - width - 4;
y = stage.stageHeight - height - 4;
}

//abre link da CC
private function licenca( e:MouseEvent ):void {
navigateToURL( new URLRequest( "http://creativecommons.org/licenses/by-nc-sa/2.5/br/" ), "_blank" );
}

}

}

4) Por fim, dentro do Flex temos o arquivo mxmlc que seria um compilador para os arquivos mxml do Flex, no entanto ele pode ser apontado para um arquivo AS bruto! Resultando em um swf sem o framework do Flex!
Assim criei o arquivo make.sh com o conteudo:
/usr/share/flex/bin/mxmlc -compiler.optimize -compiler.source-path=/home/bitetti/programacao/flash/efeitos/effect02/src/ -target-player=10 -output=./bin/header.swf ./src/Main.as
Detalhes importantes:
-compiler.source-path -> aponta para uma pasta de biblioteca de código qualquer
e...
-target-player -> seta a versão de player para qual o swf se destina. O default é 9, no entanto forcei para a versão 10, pois esta versão tem maior integração ao hardware grafico, alem do 3D, suporte a texto em colunas e pode-se escrever coisas como: var inimigos:Vector.<Inimigo> = new Vector.<Inimigo>(40); //crio um vetor de 40 inimigos! Muito mais elegante que um mero Array.

Enjoy! ^_^

O ultimo passo foi inserir no blogspot, comentei o trecho insano q insere o header do default e inseri meu código logo abaixo. Uma coisa que tive que fazer foi setar o parametro wmode para transparent para poder usar com o pequeno soft que exibe os personagens. Pensei que issu iria custar muito na performance, + testei no pc do trabalho, que é um humilde P4 e o desempenho saio-se dentro dos limites toleráveis.

P.S.: Quem quizer usar o mesmo sistema de exibição de código deste blog: (sem framework de novo, sou mesmo revoltado)

<style type="text/css">.code_hide_style { width: 100%; height: 150px; overflow: scroll; background: #ffffff; border: 1px solid #000000; } .code_show_style { width: 100%; overflow: visible; background: #ffffff; border: 1px solid #000000; } .code_control_header { width: 100%; background: #5050ff; color: #ffffff; }</style>
<div class="code_control_header"><a href="javascript:var ____j=document.getElementById('NOME_DA_DIV_A_SER_CONTROLADA');____j.className = (____j.className.indexOf('hide')==-1) ? 'code_hide_style':'code_show_style'; void(0);" class="code_control_header">Expandir código [on/off]</a></div>
<div id="NOME_DA_DIV_A_SER_CONTROLADA" class="code_hide_style"><pre>
conteudo aqui
</pre></div>