Initial commit

master
Thomas Forgione 3 years ago
commit 40db946939
  1. 1
      .gitignore
  2. 79
      README.md
  3. BIN
      assets/eye.png
  4. 66
      assets/scheme.svg
  5. 354
      assets/windfall/Windfall.mtl
  6. 84882
      assets/windfall/Windfall.obj
  7. BIN
      assets/windfall/a_iwa.png
  8. BIN
      assets/windfall/a_kusa.png
  9. BIN
      assets/windfall/a_kusa_yane.png
  10. BIN
      assets/windfall/a_kysakiwa.png
  11. BIN
      assets/windfall/a_tuta.png
  12. BIN
      assets/windfall/gakkou03.png
  13. BIN
      assets/windfall/k_taru04.png
  14. BIN
      assets/windfall/k_taru05.png
  15. BIN
      assets/windfall/m_kabe33.png
  16. BIN
      assets/windfall/m_kabe38.png
  17. BIN
      assets/windfall/m_ki12.png
  18. BIN
      assets/windfall/m_ki13.png
  19. BIN
      assets/windfall/m_komono11.png
  20. BIN
      assets/windfall/m_leaf01.png
  21. BIN
      assets/windfall/m_leaf05.png
  22. BIN
      assets/windfall/m_leaf09.png
  23. BIN
      assets/windfall/m_mado02.png
  24. BIN
      assets/windfall/m_mado08.png
  25. BIN
      assets/windfall/m_miti05.png
  26. BIN
      assets/windfall/m_ren15.png
  27. BIN
      assets/windfall/m_ren16.png
  28. BIN
      assets/windfall/m_siba04.png
  29. BIN
      assets/windfall/m_yane08.png
  30. BIN
      assets/windfall/m_yuka10.png
  31. BIN
      assets/windfall/rotennuno4.png
  32. BIN
      assets/windfall/rotennuno70.png
  33. BIN
      assets/windfall/rotennuno85.png
  34. BIN
      assets/windfall/water.png
  35. BIN
      assets/windfall/wood01.png
  36. BIN
      assets/windfall/wood04.png
  37. BIN
      assets/windfall/wood06.png
  38. 20
      index.html
  39. 83
      js/Bookmark.js
  40. 532
      js/MTLLoader.js
  41. 797
      js/OBJLoader.js
  42. 283
      js/main.js
  43. 1034
      js/three.min.js

1
.gitignore vendored

@ -0,0 +1 @@
assets

@ -0,0 +1,79 @@
# TP Interaction
Ce TP a pour but de vous faire coder des interactions avec un modèle 3D. Pour
cela, vous implémenterez en Javascript des interactions avec la souris et avec
les touches du clavier qui permettent de changer de point de vue, c'est à dire,
de mettre à jour la position et l'orientation de la caméra (Partie 1), et
ensuite d'enregistrer de tels points de vues pour permettre une navigation plus
haut niveau (Partie 2).
Ce TP sera fait pendant les séances consacrées (un TP jeudi 9, un TP jeudi 16).
### Cloner le repository
```
git clone https://gitea.tforgione.fr/tforgione/tp-interaction
```
### Lancer le server
```
python -m SimpleHTTPServer
```
Vous pouvez ensuite aller sur la page [localhost:8000](http://localhost:8000)
pour lancer l'interface. Pour voir la console vous pouvez cliquer sur `F12`,
ce qui vous permettra de debugger plus facilement.
### Sujet
#### Partie 1 : interaction clavier / souris
L'objectif de cette premiere partie est d'implémenter les interactions type
*free fly camera*. Nous vous proposons de mettre à jour les interactions avec
la souris pour tourner la caméra et avec le clavier pour la deplacer.
L'utilisateur peut appuyer sur les flèches du clavier pour déplacer la caméra :
- flèche en haut (ou touche z) pour avancer
- flèche du bas (ou touche s) pour reculer
- flèche de gauche (ou touche q) pour se translater vers la gauche
- flèche de droite (ou touche d) pour se translater vers la droite
Ces directions seront définies à partir de l'orientation de la caméra, donnée
par 2 angles `theta` et `delta`.
![](https://gitea.tforgione.fr/tforgione/tp-interaction/src/branch/master/assets/scheme.svg)
Vous pouvez trouver des exemples de coordonnées sphériques sur
[wikipedia](https://fr.wikipedia.org/wiki/Coordonn%C3%A9es_sph%C3%A9riques).
**Attention** : dans THREE.js, l'axe des y est celui qui va vers le haut.
Pour cette partie, vous aurez besoin de compléter les *TODO Part 1* du fichier
`js/main.js`.
#### Partie 2 : interaction via point de vue
L'objectif de cette deuxième partie est d'utiliser les points de vue
enregistrés pour faciliter l'interaction. Pour commencer, vous pouvez
décommenter les lignes 236 à 239 du fichier `js/main.js` pour faire apparaitre
un point de vue. Vous devez ensuite compléter les *TODO Part 2* pour permettre
à un utilisateur de cliquer sur un point de vue pour s'y déplacer.
### Les vecteurs dans THREE.js
Ce TP utilise le moteur de rendu THREE.js. Puisque javascript ne permet pas la
surcharge d'opérateurs, il est impossible d'écrire `x + y` quand `x` et `y`
sont des vecteurs de THREE.js. Ansi, THREE.js définit des méthodes pour
effectuer ces opérations :
| Avec opérateurs | En THREE.js |
|:----:|:---:|
| `a += b` | `a.add(b)` |
| `a -= b` | `a.sub(b)` |
| `a *= l` | `a.multiplyScalar(l)` |
| `a = b` | `a.copy(b)` |
| `a + b` | `a.clone().add(b)` |
| `a = b + c` | `a.copy(b.clone().add(c))` |
| ... | ... |

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="360" height="360" version="1.1">
<g id="Coord_LatLong" transform="translate(159.5, 195.5) scale(1,-1)">
<path d="M -143,0 A 143,62 0 1 0 143,0" style="stroke:#808080;stroke-width:1;stroke-dasharray:6,6;fill:none;"/>
<path d="M 0,143 A 143,60 -90 1 1 0,-143" transform="rotate(13)" style="stroke:#808080;stroke-dasharray:6,6;stroke-width:1;fill:none;"/>
<path d="M -125,0 H 186" transform="rotate(-135)" style="stroke:#000000;stroke-width:1;fill:none;"/>
<path d="M 0,-2.5 L 4,-3 L 2,4 L 0,12 L -2,4 L -4,-3 L 0,-2.5 Z" transform="rotate(-225) translate(0,186)" style="stroke:none;fill:#000000;"/>
<path d="M -155,0 H 188" transform="rotate(-10.6)" style="stroke:#000000;stroke-width:1;fill:none;"/>
<path d="M 0,-2.5 L 4,-3 L 2,4 L 0,12 L -2,4 L -4,-3 L 0,-2.5 Z" transform="rotate(-10.6) translate(188,0) rotate(270)" style="stroke:none;fill:#000000;"/>
<path d="M 0,-163 V 177" style="stroke:#000000;stroke-width:1;fill:none;"/>
<path d="M 0,-2.5 L 4,-3 L 2,4 L 0,12 L -2,4 L -4,-3 L 0,-2.5 Z" transform="translate(0,177)" style="stroke:none;fill:#000000;"/>
<circle cx="0" cy="0" r="143" style="stroke:#000000;stroke-width:2;fill:none;"/>
<path d="M 0,-143 A 143,60 -90 1 1 0,143" transform="rotate(13)" style="stroke:#000000;stroke-width:1;fill:none;"/>
<path d="M -143,0 A 143,62 0 1 1 143,0" style="stroke:#000000;stroke-width:1;fill:none;"/>
<path d="M 0,0 L -56.88,-56.88 A 143,62 0 0 1 66.73,-54.84 L 0,0 Z" style="stroke:none;fill:#204a87;opacity:0.2;"/>
<path d="M 0,0 L 52.68,-68.44 A 143,60 -90 0 1 53.71,63.72 L 0,0 Z" transform="rotate(13)" style="stroke:none;fill:#f57900;opacity:0.3;"/>
<path d="M 0,0 L 38,74.17" style="stroke:#4e9a06;stroke-width:2;fill:none;"/>
<path d="M 0,0 L -10,3 L -10,-3 L 0,0 Z" transform="translate(38, 74.17) rotate(63)" style="stroke:#4e9a06;stroke-width:2;fill:#4e9a06;"/>
<path d="M 52.68,-68.44 A 143,60 -90 0 1 53.71,63.72" transform="rotate(13)" style="stroke:#f57900;stroke-width:2;fill:none;"/>
<path d="M 0,0 L -10,3 L -10,-3 L 0,0 Z" transform="translate(38, 74.17) rotate(112)" style="stroke:#f57900;stroke-width:2;fill:#f57900;"/>
<path d="M -56.88,-56.88 A 143,62 0 0 1 62,-55.87" style="stroke:#204a87;stroke-width:2;fill:none;"/>
<path d="M 0,0 L -10,3 L -10,-3 L 0,0 Z" transform="translate(66.73,-54.84) rotate(11)" style="stroke:#204a87;stroke-width:2;fill:#204a87;"/>
<circle cx="38" cy="74.17" r="4" style="stroke:none;fill:#5c3566;"/>
<circle cx="0" cy="0" r="2" style="stroke:none;fill:#000000;"/>
<text transform="scale(1,-1)" x="6" y="-44" xml:space="preserve" style="font-size:28px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;stroke:none;font-family:DejaVu Serif;-inkscape-font-specification:DejaVu Serif Italic"><tspan x="6" y="-44">ρ</tspan>
</text>
<text transform="scale(1,-1)" x="64" y="-10" xml:space="preserve" style="font-size:28px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;stroke:none;font-family:DejaVu Serif;-inkscape-font-specification:DejaVu Serif Italic"><tspan x="64" y="-10">δ</tspan>
</text>
<text transform="scale(1,-1)" x="-22" y="90" xml:space="preserve" style="font-size:28px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;stroke:none;font-family:DejaVu Serif;-inkscape-font-specification:DejaVu Serif Italic"><tspan x="-22" y="90">θ</tspan>
</text>
<text transform="scale(1,-1)" x="45" y="-78" xml:space="preserve" style="font-size:28px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;stroke:none;font-family:DejaVu Serif;-inkscape-font-specification:DejaVu Serif Italic"><tspan x="45" y="-78">P</tspan>
</text>
<g transform="translate(-127,-154) scale(1,-1)">
<text x="0" y="0" xml:space="preserve" style="font-size:32px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#000000;stroke:none;font-family:DejaVu Serif;-inkscape-font-specification:DejaVu Serif Italic"><tspan x="0" y="0">z</tspan>
</text>
</g>
<g transform="translate(167,-65) scale(1,-1)">
<text x="0" y="0" xml:space="preserve" style="font-size:32px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#000000;stroke:none;font-family:DejaVu Serif;-inkscape-font-specification:DejaVu Serif Italic"><tspan x="0" y="0">x</tspan>
</text>
</g>
<g transform="translate(10,170) scale(1,-1)">
<text x="0" y="0" xml:space="preserve" style="font-size:32px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#000000;stroke:none;font-family:DejaVu Serif;-inkscape-font-specification:DejaVu Serif Italic"><tspan x="0" y="0">y</tspan>
</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.4 KiB

@ -0,0 +1,354 @@
# Blender MTL File: 'None'
# Material Count: 32
newmtl m0lambea_v_x_v_x
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd a_tuta.png
newmtl m10lambert12_v_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd m_siba04.png
newmtl m11lambert14_v_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd rotennuno85.png
newmtl m12lambert15_v_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd wood04.png
newmtl m13lambert2_v_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd a_kusa.png
newmtl m14lambert6_v_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd m_yuka10.png
newmtl m15lambert74_v_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd a_iwa.png
newmtl m16lambert75_v_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd rotennuno4.png
newmtl m17lambert84_v_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd m_kabe33.png
newmtl m18lambert85_v_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd m_ren15.png
newmtl m19lambert8_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd m_miti05.png
newmtl m1lambert100_v_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd m_ki12.png
newmtl m20lambert92_v_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd m_yane08.png
newmtl m21lambert94_v_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd m_ki13.png
newmtl m22lambert95_v_x_v_x
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd a_kusa_yane.png
newmtl m23lambert98_v_x_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd gakkou03.png
newmtl m24lambert98_v_x_v_x
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd gakkou03.png
newmtl m25lambert99_v_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd m_mado08.png
newmtl m26lambertaa_v_v_x
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd a_kysakiwa.png
newmtl m27lambv_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd m_mado02.png
newmtl m28test_lambert105_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd m_leaf01.png
newmtl m29test_lambert48_v_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd k_taru04.png
newmtl m2lambert101_v_v_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd m_komono11.png
newmtl m30test_lambert49_v_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd k_taru05.png
newmtl m31lambert12_v_v_2_
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd m_siba04.png
newmtl m3lambert102_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd m_ren16.png
newmtl m4lambert103_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd m_kabe38.png
newmtl m5lambert104_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd m_leaf05.png
newmtl m6lambert107_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd m_leaf09.png
newmtl m7lambert10_v_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd wood01.png
newmtl m8lambert115_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd rotennuno70.png
newmtl m9lambert11_v_v
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd wood06.png

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

@ -0,0 +1,20 @@
<!doctype html>
<html>
<head>
<title>TP</title>
<meta charset="utf-8">
<style>
body {
overflow: hidden;
margin: 0px;
}
</style>
</head>
<body>
<script src="js/three.min.js"></script>
<script src="js/OBJLoader.js"></script>
<script src="js/MTLLoader.js"></script>
<script src="js/Bookmark.js"></script>
<script src="js/main.js"></script>
</body>
</html>

@ -0,0 +1,83 @@
class Bookmark extends THREE.Object3D {
constructor(position, target, scale = 500.0) {
super();
position = new THREE.Vector3().copy(position);
target = new THREE.Vector3().copy(target);
this.position.copy(position);
this.target = new THREE.Vector3().copy(target);
this.t = 0;
let material = new THREE.LineBasicMaterial({
color: 0xffffff,
linewidth: 3,
});
let geometry = new THREE.Geometry();
let direction = this.target.clone().sub(position).normalize().multiplyScalar(this.length());
geometry.vertices.push(new THREE.Vector3(0.0, -1000000.0, 0.0));
geometry.vertices.push(new THREE.Vector3(0.0, 0.0, 0.0));
this.line = new THREE.Line(geometry, material);
this.add(this.line);
this.numberOfPoints = 20;
this.createCircle();
this._shining = false;
this.t = 0;
}
createCircle() {
let map = new THREE.TextureLoader().load("assets/eye.png");
let material = new THREE.SpriteMaterial({
map: map,
color: 0xfffffff,
transparent: true,
});
let geometry = new THREE.Geometry();
this.circle = new THREE.Sprite(material);
this.add(this.circle);
}
length() {
return 25 * (Math.cos(this.t) + 5);
}
get shining() {
return this._shining;
}
set shining(other) {
this._shining = other;
if (!other) {
this.circle.material.color = new THREE.Color(1, 1, 1);
this.line.material.color = new THREE.Color(1, 1, 1);
}
}
update(camera) {
// super.update(camera);
/// assert(camera instanceof THREE.Camera);
let distance = this.localToWorld(this.position.clone()).distanceTo(camera.position);
this.t += 0.05;
let l = this.length();
this.circle.scale.x = l * Math.log(1 + distance);
this.circle.scale.y = l * Math.log(1 + distance);
this.circle.scale.z = l * Math.log(1 + distance);
this.line.geometry.vertices[1].y = -this.circle.scale.x / 2;
this.line.geometry.verticesNeedUpdate = true;
if (this.shining) {
let value = (1 + Math.cos(Math.PI / 2 + this.t * 2)) / 2;
this.circle.material.color = new THREE.Color(1 - value, value, 0);
this.line.material.color = new THREE.Color(1 - value, value, 0);
}
}
}

@ -0,0 +1,532 @@
/**
* Loads a Wavefront .mtl file specifying materials
*
* @author angelxuanchang
*/
THREE.MTLLoader = function ( manager ) {
THREE.Loader.call( this, manager );
};
THREE.MTLLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), {
constructor: THREE.MTLLoader,
/**
* Loads and parses a MTL asset from a URL.
*
* @param {String} url - URL to the MTL file.
* @param {Function} [onLoad] - Callback invoked with the loaded object.
* @param {Function} [onProgress] - Callback for download progress.
* @param {Function} [onError] - Callback for download errors.
*
* @see setPath setResourcePath
*
* @note In order for relative texture references to resolve correctly
* you must call setResourcePath() explicitly prior to load.
*/
load: function ( url, onLoad, onProgress, onError ) {
var scope = this;
var path = ( this.path === '' ) ? THREE.LoaderUtils.extractUrlBase( url ) : this.path;
var loader = new THREE.FileLoader( this.manager );
loader.setPath( this.path );
loader.load( url, function ( text ) {
onLoad( scope.parse( text, path ) );
}, onProgress, onError );
},
setMaterialOptions: function ( value ) {
this.materialOptions = value;
return this;
},
/**
* Parses a MTL file.
*
* @param {String} text - Content of MTL file
* @return {THREE.MTLLoader.MaterialCreator}
*
* @see setPath setResourcePath
*
* @note In order for relative texture references to resolve correctly
* you must call setResourcePath() explicitly prior to parse.
*/
parse: function ( text, path ) {
var lines = text.split( '\n' );
var info = {};
var delimiter_pattern = /\s+/;
var materialsInfo = {};
for ( var i = 0; i < lines.length; i ++ ) {
var line = lines[ i ];
line = line.trim();
if ( line.length === 0 || line.charAt( 0 ) === '#' ) {
// Blank line or comment ignore
continue;
}
var pos = line.indexOf( ' ' );
var key = ( pos >= 0 ) ? line.substring( 0, pos ) : line;
key = key.toLowerCase();
var value = ( pos >= 0 ) ? line.substring( pos + 1 ) : '';
value = value.trim();
if ( key === 'newmtl' ) {
// New material
info = { name: value };
materialsInfo[ value ] = info;
} else {
if ( key === 'ka' || key === 'kd' || key === 'ks' || key === 'ke' ) {
var ss = value.split( delimiter_pattern, 3 );
info[ key ] = [ parseFloat( ss[ 0 ] ), parseFloat( ss[ 1 ] ), parseFloat( ss[ 2 ] ) ];
} else {
info[ key ] = value;
}
}
}
var materialCreator = new THREE.MTLLoader.MaterialCreator( this.resourcePath || path, this.materialOptions );
materialCreator.setCrossOrigin( this.crossOrigin );
materialCreator.setManager( this.manager );
materialCreator.setMaterials( materialsInfo );
return materialCreator;
}
} );
/**
* Create a new THREE.MTLLoader.MaterialCreator
* @param baseUrl - Url relative to which textures are loaded
* @param options - Set of options on how to construct the materials
* side: Which side to apply the material
* THREE.FrontSide (default), THREE.BackSide, THREE.DoubleSide
* wrap: What type of wrapping to apply for textures
* THREE.RepeatWrapping (default), THREE.ClampToEdgeWrapping, THREE.MirroredRepeatWrapping
* normalizeRGB: RGBs need to be normalized to 0-1 from 0-255
* Default: false, assumed to be already normalized
* ignoreZeroRGBs: Ignore values of RGBs (Ka,Kd,Ks) that are all 0's
* Default: false
* @constructor
*/
THREE.MTLLoader.MaterialCreator = function ( baseUrl, options ) {
this.baseUrl = baseUrl || '';
this.options = options;
this.materialsInfo = {};
this.materials = {};
this.materialsArray = [];
this.nameLookup = {};
this.side = ( this.options && this.options.side ) ? this.options.side : THREE.FrontSide;
this.wrap = ( this.options && this.options.wrap ) ? this.options.wrap : THREE.RepeatWrapping;
};
THREE.MTLLoader.MaterialCreator.prototype = {
constructor: THREE.MTLLoader.MaterialCreator,
crossOrigin: 'anonymous',
setCrossOrigin: function ( value ) {
this.crossOrigin = value;
return this;
},
setManager: function ( value ) {
this.manager = value;
},
setMaterials: function ( materialsInfo ) {
this.materialsInfo = this.convert( materialsInfo );
this.materials = {};
this.materialsArray = [];
this.nameLookup = {};
},
convert: function ( materialsInfo ) {
if ( ! this.options ) return materialsInfo;
var converted = {};
for ( var mn in materialsInfo ) {
// Convert materials info into normalized form based on options
var mat = materialsInfo[ mn ];
var covmat = {};
converted[ mn ] = covmat;
for ( var prop in mat ) {
var save = true;
var value = mat[ prop ];
var lprop = prop.toLowerCase();
switch ( lprop ) {
case 'kd':
case 'ka':
case 'ks':
// Diffuse color (color under white light) using RGB values
if ( this.options && this.options.normalizeRGB ) {
value = [ value[ 0 ] / 255, value[ 1 ] / 255, value[ 2 ] / 255 ];
}
if ( this.options && this.options.ignoreZeroRGBs ) {
if ( value[ 0 ] === 0 && value[ 1 ] === 0 && value[ 2 ] === 0 ) {
// ignore
save = false;
}
}
break;
default:
break;
}
if ( save ) {
covmat[ lprop ] = value;
}
}
}
return converted;
},
preload: function () {
for ( var mn in this.materialsInfo ) {
this.create( mn );
}
},
getIndex: function ( materialName ) {
return this.nameLookup[ materialName ];
},
getAsArray: function () {
var index = 0;
for ( var mn in this.materialsInfo ) {
this.materialsArray[ index ] = this.create( mn );
this.nameLookup[ mn ] = index;
index ++;
}
return this.materialsArray;
},
create: function ( materialName ) {
if ( this.materials[ materialName ] === undefined ) {
this.createMaterial_( materialName );
}
return this.materials[ materialName ];
},
createMaterial_: function ( materialName ) {
// Create material
var scope = this;
var mat = this.materialsInfo[ materialName ];
var params = {
name: materialName,
side: this.side
};
function resolveURL( baseUrl, url ) {
if ( typeof url !== 'string' || url === '' )
return '';
// Absolute URL
if ( /^https?:\/\//i.test( url ) ) return url;
return baseUrl + url;
}
function setMapForType( mapType, value ) {
if ( params[ mapType ] ) return; // Keep the first encountered texture
var texParams = scope.getTextureParams( value, params );
var map = scope.loadTexture( resolveURL( scope.baseUrl, texParams.url ) );
map.repeat.copy( texParams.scale );
map.offset.copy( texParams.offset );
map.wrapS = scope.wrap;
map.wrapT = scope.wrap;
params[ mapType ] = map;
}
for ( var prop in mat ) {
var value = mat[ prop ];
var n;
if ( value === '' ) continue;
switch ( prop.toLowerCase() ) {
// Ns is material specular exponent
case 'kd':
// Diffuse color (color under white light) using RGB values
params.color = new THREE.Color().fromArray( value );
break;
case 'ks':
// Specular color (color when light is reflected from shiny surface) using RGB values
params.specular = new THREE.Color().fromArray( value );
break;
case 'ke':
// Emissive using RGB values
params.emissive = new THREE.Color().fromArray( value );
break;
case 'map_kd':
// Diffuse texture map
setMapForType( "map", value );
break;
case 'map_ks':
// Specular map
setMapForType( "specularMap", value );
break;
case 'map_ke':
// Emissive map
setMapForType( "emissiveMap", value );
break;
case 'norm':
setMapForType( "normalMap", value );
break;
case 'map_bump':
case 'bump':
// Bump texture map
setMapForType( "bumpMap", value );
break;
case 'map_d':
// Alpha map
setMapForType( "alphaMap", value );
params.transparent = true;
break;
case 'ns':
// The specular exponent (defines the focus of the specular highlight)
// A high exponent results in a tight, concentrated highlight. Ns values normally range from 0 to 1000.
params.shininess = parseFloat( value );
break;
case 'd':
n = parseFloat( value );
if ( n < 1 ) {
params.opacity = n;
params.transparent = true;
}
break;
case 'tr':
n = parseFloat( value );
if ( this.options && this.options.invertTrProperty ) n = 1 - n;
if ( n > 0 ) {
params.opacity = 1 - n;
params.transparent = true;
}
break;
default:
break;
}
}
this.materials[ materialName ] = new THREE.MeshPhongMaterial( params );
return this.materials[ materialName ];
},
getTextureParams: function ( value, matParams ) {
var texParams = {
scale: new THREE.Vector2( 1, 1 ),
offset: new THREE.Vector2( 0, 0 )
};
var items = value.split( /\s+/ );
var pos;
pos = items.indexOf( '-bm' );
if ( pos >= 0 ) {
matParams.bumpScale = parseFloat( items[ pos + 1 ] );
items.splice( pos, 2 );
}
pos = items.indexOf( '-s' );
if ( pos >= 0 ) {
texParams.scale.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) );
items.splice( pos, 4 ); // we expect 3 parameters here!
}
pos = items.indexOf( '-o' );
if ( pos >= 0 ) {
texParams.offset.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) );
items.splice( pos, 4 ); // we expect 3 parameters here!
}
texParams.url = items.join( ' ' ).trim();
return texParams;
},
loadTexture: function ( url, mapping, onLoad, onProgress, onError ) {
var texture;
var manager = ( this.manager !== undefined ) ? this.manager : THREE.DefaultLoadingManager;
var loader = manager.getHandler( url );
if ( loader === null ) {
loader = new THREE.TextureLoader( manager );
}
if ( loader.setCrossOrigin ) loader.setCrossOrigin( this.crossOrigin );
texture = loader.load( url, onLoad, onProgress, onError );
if ( mapping !== undefined ) texture.mapping = mapping;
return texture;
}
};

@ -0,0 +1,797 @@
/**
* @author mrdoob / http://mrdoob.com/
*/
THREE.OBJLoader = ( function () {
// o object_name | g group_name
var object_pattern = /^[og]\s*(.+)?/;
// mtllib file_reference
var material_library_pattern = /^mtllib /;
// usemtl material_name
var material_use_pattern = /^usemtl /;
// usemap map_name
var map_use_pattern = /^usemap /;
function ParserState() {
var state = {
objects: [],
object: {},
vertices: [],
normals: [],
colors: [],
uvs: [],
materialLibraries: [],
startObject: function ( name, fromDeclaration ) {
// If the current object (initial from reset) is not from a g/o declaration in the parsed
// file. We need to use it for the first parsed g/o to keep things in sync.
if ( this.object && this.object.fromDeclaration === false ) {
this.object.name = name;
this.object.fromDeclaration = ( fromDeclaration !== false );
return;
}
var previousMaterial = ( this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined );
if ( this.object && typeof this.object._finalize === 'function' ) {
this.object._finalize( true );
}
this.object = {
name: name || '',
fromDeclaration: ( fromDeclaration !== false ),
geometry: {
vertices: [],
normals: [],
colors: [],
uvs: []
},
materials: [],
smooth: true,
startMaterial: function ( name, libraries ) {
var previous = this._finalize( false );
// New usemtl declaration overwrites an inherited material, except if faces were declared
// after the material, then it must be preserved for proper MultiMaterial continuation.
if ( previous && ( previous.inherited || previous.groupCount <= 0 ) ) {
this.materials.splice( previous.index, 1 );
}
var material = {
index: this.materials.length,
name: name || '',
mtllib: ( Array.isArray( libraries ) && libraries.length > 0 ? libraries[ libraries.length - 1 ] : '' ),
smooth: ( previous !== undefined ? previous.smooth : this.smooth ),
groupStart: ( previous !== undefined ? previous.groupEnd : 0 ),
groupEnd: - 1,
groupCount: - 1,
inherited: false,
clone: function ( index ) {
var cloned = {
index: ( typeof index === 'number' ? index : this.index ),
name: this.name,
mtllib: this.mtllib,
smooth: this.smooth,
groupStart: 0,
groupEnd: - 1,
groupCount: - 1,
inherited: false
};
cloned.clone = this.clone.bind( cloned );
return cloned;
}
};
this.materials.push( material );
return material;
},
currentMaterial: function () {
if ( this.materials.length > 0 ) {
return this.materials[ this.materials.length - 1 ];
}
return undefined;
},
_finalize: function ( end ) {
var lastMultiMaterial = this.currentMaterial();
if ( lastMultiMaterial && lastMultiMaterial.groupEnd === - 1 ) {
lastMultiMaterial.groupEnd = this.geometry.vertices.length / 3;
lastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart;
lastMultiMaterial.inherited = false;
}
// Ignore objects tail materials if no face declarations followed them before a new o/g started.
if ( end && this.materials.length > 1 ) {
for ( var mi = this.materials.length - 1; mi >= 0; mi -- ) {
if ( this.materials[ mi ].groupCount <= 0 ) {
this.materials.splice( mi, 1 );
}
}
}
// Guarantee at least one empty material, this makes the creation later more straight forward.
if ( end && this.materials.length === 0 ) {
this.materials.push( {
name: '',
smooth: this.smooth
} );
}
return lastMultiMaterial;
}
};