Acrobat 3D i zmiana materiałów w modelach, część 1

No Comments

O produktach Adobe pisałem już swego czasu. Okazało się, że przy odrobinie dobrej woli animacje w modelach to absolutna łatwizna w porównaniu do prób zmiany koloru jakiegokolwiek elementu…
Oczywiście, można pokusić się o zmienianie poszczególnych właściwości obiektów klasy Material(), ale z reguły nie działa to tak, jak powinno…

To znaczy działa, owszem… ale na nerwy programisty. W związku z tym trzeba jakoś zautomatyzować cały proces.

Na początek stwórzmy kontener przechowujący właściwości materiału. Na podstawie dokumentacji można wywnioskować, że właściwości materiałów jest znacznie więcej, niestety testy wykazały, że dokumentacja się myli :)

Prosta klasa materiału wygląda następująco:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function ExtMaterial(meshname)
{
  myMesh = Context().scene.meshes.getByName(meshname);
 
  this.ambient  = new Array(myMesh.material.ambientColor.r,  myMesh.material.ambientColor.g,  myMesh.material.ambientColor.b);
  this.diffuse  = new Array(myMesh.material.diffuseColor.r,  myMesh.material.diffuseColor.g,  myMesh.material.diffuseColor.b);
  this.specular = new Array(myMesh.material.specularColor.r, myMesh.material.specularColor.g, myMesh.material.specularColor.b);
  this.emissive = new Array(myMesh.material.emissiveColor.r, myMesh.material.emissiveColor.g, myMesh.material.emissiveColor.b);
  this.specularStrength   = myMesh.material.specularStrength;
  this.reflectionStrength = myMesh.material.reflectionStrength;
 
  this.opacity = myMesh.material.opacity;
 
  try
  {
    this.texture = myMesh.material.reflectionTexture.getImage();
  }
  catch(e)
  {
    this.texture = '';
  }
}

Jak widać, pobiera ona ze wskazanego elementu (mesh) te właściwości, które będą później potrzebne. Warto zauważyć, że wszystkie właściwości oprócz tekstury mają jakąś wartość. W związku z tym, właściwość tekstury trzeba opakować w try-catch, żeby próba pobrania obrazu przy jego braku nie powodowała sypania błędami po konsoli.

Dlaczego pobieramy właściwości z mesha? Spieszę z wyjaśnieniem: przy obecnie oferowanych przez Adobe narzędziach do tworzenia i edycji modeli 3D (jeszcze mi się ręce trzęsą, jak o tym pomyślę), śmiało można powiedzieć, że nigdy nie wiadomo, co jak będzie wyglądać. Dlatego lepiej materiał stworzyć w tym samym programie (chociaż oczywiście można to spróbować zrobić programowo).
Wymaga to od twórcy modelu zamieszczenia w pliku U3D “próbek”, posiadających przypisany materiał, który nas interesuje, ale niewidocznych w samym modelu. Najlepiej oprócz .visible=false nadać im mikroskopijny rozmiar, bo każdy mesh można włączyć w widoku drzewa z poziomu Adobe Readera.

Załóżmy, że mamy nasz nieszczęsny model długopisu. Wstępnie jest paskudny zielony, ale chcemy dać użytkownikowi możliwość zobaczenia go w wersji chromowanej. Moglibyśmy to zrobić dwojako:

  • utworzyć dwie wersje korpusu długopisu z przypisanymi dwoma materiałami
  • utworzyć jeden korpus z przypisanym materiałem i próbkę drugiego materiału

Rozwiązanie drugie, logicznie rzecz ujmując, jest bardziej opłacalne. Żeby stworzyć próbkę, wystarczy jeden mesh. Żeby utworzyć kopię obiektu, czasem trzeba poświęcić dobrych kilka megabajtów.

Jak to będzie się odbywać? Tworzymy model i dokładamy do niego próbkę drugiego materiału. Na starcie pobieramy właściwości materiału tej próbki. W momencie, kiedy użytkownik wykonuje określoną akcję (np. kliknie przycisk), przepisujemy właściwości materiału na nasz element. Proste?

No dobrze, ale jak te właściwości przepisać? Bardziej dociekliwi po przeanalizowaniu kodu klasy ExtMaterial() poznają ogólne założenia. O tym w następnym odcinku :)

Categories: Acrobat, JavaScript, Software Tags: Tagi:

Leave a Reply

Your email address will not be published. Required fields are marked *