added shellAnimation without shell asset

This commit is contained in:
Cedric Beck
2024-12-07 13:30:30 +01:00
parent 29c6b13300
commit 32f49a6181
30 changed files with 879576 additions and 75 deletions

View File

@@ -28,7 +28,7 @@ public enum Asset {
ship(0.8f),
smallTent,
tank,
world(1.2f),
world("Models/world/world_export_newTex.obj", "Models/world/world_diff.png",1.2f),
shieldRing("Models/shieldRing/shieldRing.j3o", null),
treeSmall(1.2f),
treeBig(1.2f),
@@ -38,7 +38,11 @@ public enum Asset {
swapSymbol("Models/swapCard/swapSymbol.j3o", "Models/swapCard/swapCard_diff.png"),
shieldCard,
shieldSymbol("Models/shieldCard/shieldSymbol.j3o", "Models/shieldCard/shieldCard_diff.png"),
dice
dice,
tankShoot("Models/tank/tank_shoot_bot.obj", "Models/tank/tank_diff.png"),
tankShootTop("Models/tank/tank_shoot_top.obj", "Models/tank/tank_diff.png"),
treesSmallBackground("Models/treeSmall/small_trees_background.obj", "Models/treeSmall/treeSmall_diff.png", 1.2f),
treesBigBackground("Models/treeBig/big_trees_background.obj", "Models/treeBig/treeBig_diff.png", 1.2f)
;
private final String modelPath;

View File

@@ -156,10 +156,14 @@ else if(boardSelect != null) {
p = UUID.randomUUID();
gameView.getBoardHandler().addPlayer(Color.AIRFORCE,List.of(p,UUID.randomUUID(),UUID.randomUUID(),UUID.randomUUID()));
gameView.getBoardHandler().movePieceStartAnim(p,0);
gameView.getBoardHandler().movePieceAnim(p,0, 8);
// gameView.getBoardHandler().movePieceAnim(p,0, 8);
} else {
// gameView.getBoardHandler().throwBombAnim(p);
gameView.getBoardHandler().throwPiece(p,Color.CYBER);
gameView.getBoardHandler().throwPiece(p,Color.ARMY);
// gameView.getBoardHandler().movePieceAnim(p,0,20);
// gameView.getBoardHandler().throwPiece(p,Color.CYBER);
// gameView.getBoardHandler().throwPiece(p,Color.AIRFORCE);
//gameView.getBoardHandler().movePieceStartAnim(p,0);
}

View File

@@ -138,7 +138,7 @@ private void handleGame(Notification notification) {
}
guiHandler.hideText();
} else if (notification instanceof ThrowPieceNotification n) {
boardHandler.throwBombAnim(n.getPieceId());
boardHandler.throwPiece(n.getPieceId(), n.getThrowColor());
} else if (notification instanceof NoShieldNotification n) {
boardHandler.unshieldPiece(n.getPieceId());
} else if (notification instanceof PlayCardNotification n) {

View File

@@ -0,0 +1,47 @@
package pp.mdga.client;
import com.jme3.math.Vector3f;
public class Util {
private Util(){}
/**
* Performs linear interpolation between two values.
*
* @param start The starting value.
* @param end The ending value.
* @param t A parameter between 0 and 1 representing the interpolation progress.
* @return The interpolated value.
*/
public static float linInt(float start, float end, float t) {
return start + t * (end - start);
}
/**
* Performs quadratic interpolation between three points.
*
* @param p1 The initial point.
* @param p2 The middle point.
* @param p3 The final point.
* @param t The interpolation parameter (0 <= t <= 1).
* @return The interpolated point.
*/
public static Vector3f quadInt(Vector3f p1, Vector3f p2, Vector3f p3, float t) {
// Quadratic interpolation: (1-t)^2 * p1 + 2 * (1-t) * t * p2 + t^2 * p3
float oneMinusT = 1 - t;
return p1.mult(oneMinusT * oneMinusT)
.add(p2.mult(2 * oneMinusT * t))
.add(p3.mult(t * t));
}
/**
* A smooth ease-in-out function for interpolation.
* It accelerates and decelerates the interpolation for a smoother effect.
*
* @param x The interpolation parameter (0 <= x <= 1).
* @return The adjusted interpolation value.
*/
public static float easeInOut(float x){
return x < 0.5 ? 4 * x * x * x : (float) (1 - Math.pow(-2 * x + 2, 3) / 2);
}
}

View File

@@ -123,6 +123,15 @@ public void playSound(MdgaSound sound) {
case BONUS:
assets.add(new SoundAssetDelayVolume(SoundAsset.BONUS, 1.0f, 0.0f));
break;
case TURRET_ROTATE:
assets.add(new SoundAssetDelayVolume(SoundAsset.TURRET_ROTATE, 0.7f, 0f));
break;
case TANK_SHOOT:
assets.add(new SoundAssetDelayVolume(SoundAsset.TANK_SHOOT, 0.7f, 0f));
break;
case TANK_EXPLOSION:
assets.add(new SoundAssetDelayVolume(SoundAsset.EXPLOSION_1, 1.0f, 0f));
break;
default:
break;
}

View File

@@ -35,4 +35,7 @@ public enum MdgaSound {
EXPLOSION,
LOSE,
BONUS,
TURRET_ROTATE,
TANK_SHOOT,
TANK_EXPLOSION
}

View File

@@ -35,7 +35,11 @@ enum SoundAsset {
UI90("ui90.ogg"),
BONUS("bonus.ogg"),
LOSE("lose.ogg"),
CONNECTED("connected.wav");
CONNECTED("connected.wav"),
TURRET_ROTATE("turret_rotate.ogg"),
TANK_SHOOT("tank_shoot.ogg")
;
private final String path;

View File

@@ -0,0 +1,18 @@
package pp.mdga.client.animation;
import pp.mdga.client.InitControl;
public class ActionControl extends InitControl {
private final Runnable runnable;
public ActionControl(Runnable runnable){
this.runnable = runnable;
}
protected void action(){
if(runnable == null) throw new RuntimeException("runnable is null");
else runnable.run();
}
}

View File

@@ -6,6 +6,8 @@
import com.jme3.math.ColorRGBA;
import pp.mdga.client.InitControl;
import static pp.mdga.client.Util.linInt;
public class FadeControl extends InitControl {
private float duration; // Duration of the fade effect
private float timeElapsed = 0;
@@ -69,16 +71,4 @@ protected void controlUpdate(float tpf) {
} else throw new RuntimeException("Material is null");
} else throw new RuntimeException("Spatial is not instance of Geometry");
}
/**
* Performs linear interpolation between two values.
*
* @param start The starting value.
* @param end The ending value.
* @param t A parameter between 0 and 1 representing the interpolation progress.
* @return The interpolated value.
*/
private float linInt(float start, float end, float t) {
return start + t * (end - start);
}
}

View File

@@ -39,7 +39,6 @@ public MatrixAnimation(MdgaApp app, float duration, Vector3f radarPos, Runnable
@Override
protected void initSpatial() {
state = MatrixState.RADAR_ON;
System.out.println("RADAR ON");
timeElapsed = 0;
init = true;
radar();

View File

@@ -1,7 +1,8 @@
package pp.mdga.client.animation;
import com.jme3.math.Vector3f;
import pp.mdga.client.InitControl;
import static pp.mdga.client.Util.*;
/**
* A control that smoothly moves a spatial from an initial position to an end position
@@ -12,16 +13,16 @@
* an ease-in-out curve to create a smooth start and stop effect.
* </p>
*/
public class MoveControl extends InitControl {
public class MoveControl extends ActionControl {
private boolean moving;
private final Vector3f initPos;
private final Vector3f endPos;
private final Vector3f middlePos;
private final static float HEIGHT = 2;
private final static float MOVE_SPEED = 1f;
private float progress = 0;
private final Runnable actionAfter;
private final float height;
private final float duration;
private float timer = 0;
private boolean easing;
/**
* Creates a new MoveControl with specified initial and end positions, and an action to run after the movement.
@@ -32,15 +33,22 @@ public class MoveControl extends InitControl {
* @param actionAfter A Runnable that will be executed after the movement finishes.
*/
public MoveControl(Vector3f initPos, Vector3f endPos, Runnable actionAfter){
this(initPos, endPos, actionAfter, 2, 1, true);
}
public MoveControl(Vector3f initPos, Vector3f endPos, Runnable actionAfter, float height, float duration, boolean easing){
super(actionAfter);
moving = false;
this.initPos = initPos;
this.endPos = endPos;
this.height = height;
this.duration = duration;
this.easing = easing;
middlePos = new Vector3f(
(initPos.x + endPos.x) / 2,
(initPos.y + endPos.y) / 2,
HEIGHT
(initPos.x + endPos.x) / 2,
(initPos.y + endPos.y) / 2,
height
);
this.actionAfter = actionAfter;
}
/**
@@ -50,7 +58,7 @@ public MoveControl(Vector3f initPos, Vector3f endPos, Runnable actionAfter){
@Override
protected void initSpatial() {
moving = true;
progress = 0;
timer = 0;
}
/**
@@ -63,10 +71,16 @@ protected void initSpatial() {
@Override
protected void controlUpdate(float tpf) {
if(!moving) return;
progress += tpf * MOVE_SPEED;
if(progress > 1) progress = 1;
spatial.setLocalTranslation(quadInt(initPos,middlePos,endPos, easeInOut(progress)));
if(progress == 1) end();
timer += tpf;
float t = timer / duration;
if (t >= 1) t = 1;
float interpolated = easing ? easeInOut(t) : t;
spatial.setLocalTranslation(quadInt(initPos,middlePos,endPos, interpolated));
if(t >= 1) end();
}
/**
@@ -75,35 +89,11 @@ protected void controlUpdate(float tpf) {
*/
private void end(){
moving = false;
actionAfter.run();
spatial.removeControl(this);
action();
}
/**
* Performs quadratic interpolation between three points.
*
* @param p1 The initial point.
* @param p2 The middle point.
* @param p3 The final point.
* @param t The interpolation parameter (0 <= t <= 1).
* @return The interpolated point.
*/
private Vector3f quadInt(Vector3f p1, Vector3f p2, Vector3f p3, float t) {
// Quadratic interpolation: (1-t)^2 * p1 + 2 * (1-t) * t * p2 + t^2 * p3
float oneMinusT = 1 - t;
return p1.mult(oneMinusT * oneMinusT)
.add(p2.mult(2 * oneMinusT * t))
.add(p3.mult(t * t));
}
/**
* A smooth ease-in-out function for interpolation.
* It accelerates and decelerates the interpolation for a smoother effect.
*
* @param x The interpolation parameter (0 <= x <= 1).
* @return The adjusted interpolation value.
*/
private float easeInOut(float x){
return x < 0.5 ? 4 * x * x * x : (float) (1 - Math.pow(-2 * x + 2, 3) / 2);
}
}

View File

@@ -0,0 +1,140 @@
package pp.mdga.client.animation;
import com.jme3.effect.ParticleEmitter;
import com.jme3.effect.ParticleMesh;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import pp.mdga.client.InitControl;
import pp.mdga.client.MdgaApp;
import pp.mdga.client.acoustic.MdgaSound;
import pp.mdga.client.board.TankTopControl;
import java.util.Timer;
import java.util.TimerTask;
import static com.jme3.material.Materials.UNSHADED;
public class ShellAnimation extends ActionControl {
private static final float FLYING_DURATION = 1.25f;
private static final float FLYING_HEIGHT = 12f;
private TankTopControl tankTopControl;
private MdgaApp app;
public ShellAnimation(TankTopControl tankTopControl, MdgaApp app, Runnable actionAfter){
super(actionAfter);
this.tankTopControl = tankTopControl;
this.app = app;
}
@Override
protected void initSpatial() {
tankTopControl.rotate(spatial.getLocalTranslation(), this::shoot);
app.getAcousticHandler().playSound(MdgaSound.TURRET_ROTATE);
}
private Vector3f getShootPos(){
Vector3f localOffset = new Vector3f(0, -5.4f, 2.9f);
Quaternion turretRotation = tankTopControl.getSpatial().getLocalRotation();
Vector3f transformedOffset = turretRotation.mult(localOffset);
return tankTopControl.getSpatial().getLocalTranslation().add(transformedOffset);
}
private void shoot(){
app.getAcousticHandler().playSound(MdgaSound.TANK_SHOOT);
Vector3f shootPos = getShootPos();
createEffect(
shootPos,
"Images/particle/flame.png",
2, 2,
1, 3,
1f,
0.3f, 0.7f,
new ColorRGBA(1f, 0.8f, 0.4f, 0.5f),
new ColorRGBA(1f, 0f, 0f, 0f)
);
createEffect(
shootPos,
"Images/particle/vapor_cloud.png",
3, 3,
0.3f, 0.8f,
10,
0.1f, 0.35f,
new ColorRGBA(0.5f,0.5f,0.5f,0.5f),
ColorRGBA.Black
);
Geometry test = new Geometry("test", new Box(0.25f,0.25f,0.25f));
test.setMaterial(new Material(app.getAssetManager(), UNSHADED));
test.addControl(new MoveControl(shootPos, spatial.getLocalTranslation(),
()->{
app.getRootNode().detachChild(test);
hitExplosion();
}, FLYING_HEIGHT, FLYING_DURATION, false));
app.getRootNode().attachChild(test);
}
private void hitExplosion(){
app.getAcousticHandler().playSound(MdgaSound.TANK_EXPLOSION);
createEffect(
spatial.getLocalTranslation().setZ(1),
"Images/particle/flame.png",
2, 2,
1, 5,
2f,
0.3f, 0.7f,
new ColorRGBA(1f, 0.8f, 0.4f, 0.5f),
new ColorRGBA(1f, 0f, 0f, 0f)
);
new Timer().schedule(new TimerTask() {
@Override
public void run() {
action();
}
}, 800);
}
private void createEffect(Vector3f shootPos,
String image,
int x, int y,
float startSize, float endSize,
float velocity,
float lowLife, float highLife,
ColorRGBA start, ColorRGBA end){
// Create a particle emitter for the explosion
ParticleEmitter explosionEmitter = new ParticleEmitter("Explosion", ParticleMesh.Type.Triangle, 100);
Material explosionMat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Particle.j3md");
explosionMat.setTexture("Texture", app.getAssetManager().loadTexture(image));
explosionEmitter.setMaterial(explosionMat);
// Particle properties
explosionEmitter.setImagesX(x); // Columns in the texture
explosionEmitter.setImagesY(y); // Rows in the texture
explosionEmitter.setSelectRandomImage(true); // Randomize images for variety
explosionEmitter.setStartColor(start); // Bright yellowish orange
explosionEmitter.setEndColor(end); // Fade to transparent red
explosionEmitter.setStartSize(startSize); // Initial size
explosionEmitter.setEndSize(endSize); // Final size
explosionEmitter.setLowLife(lowLife); // Minimum lifetime of particles
explosionEmitter.setHighLife(highLife); // Maximum lifetime of particles
explosionEmitter.setGravity(0, 0, 1); // Gravity to pull particles down
explosionEmitter.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 0, velocity));
explosionEmitter.getParticleInfluencer().setVelocityVariation(1f); // Adds randomness to the initial velocity
explosionEmitter.setFacingVelocity(true); // Particles face their velocity direction
explosionEmitter.setLocalTranslation(shootPos);
explosionEmitter.setParticlesPerSec(0);
explosionEmitter.emitAllParticles();
app.getRootNode().attachChild(explosionEmitter);
new Timer().schedule(new TimerTask() {
@Override
public void run() {
app.getRootNode().detachChild(explosionEmitter);
}
}, 1000);
}
}

View File

@@ -13,10 +13,7 @@
import pp.mdga.client.Asset;
import pp.mdga.client.MdgaApp;
import pp.mdga.client.acoustic.MdgaSound;
import pp.mdga.client.animation.FadeControl;
import pp.mdga.client.animation.MatrixAnimation;
import pp.mdga.client.animation.MoveControl;
import pp.mdga.client.animation.JetAnimation;
import pp.mdga.client.animation.*;
import pp.mdga.client.gui.DiceControl;
import pp.mdga.game.Color;
@@ -62,6 +59,8 @@ public class BoardHandler {
private DiceControl diceControl;
//Radar Position for Matrix animation
private Vector3f radarPos;
//TankTop for shellAnimation
private TankTopControl tankTop;
/**
* Creates a new BoardHandler.
@@ -155,12 +154,18 @@ private void initMap() {
case node_wait_green -> addHomeNode(waitingNodesMap, Color.ARMY, assetOnMap);
case node_wait_yellow -> addHomeNode(waitingNodesMap, Color.CYBER, assetOnMap);
case radar -> addRadar(assetOnMap);
case tankShoot -> addTankShoot(assetOnMap);
default -> displayAsset(assetOnMap);
}
}
}
private void addTankShoot(AssetOnMap assetOnMap) {
displayAsset(assetOnMap);
tankTop = displayAndControl(new AssetOnMap(Asset.tankShootTop, assetOnMap.x(), assetOnMap.y(), assetOnMap.rot()), new TankTopControl());
}
private void addRadar(AssetOnMap assetOnMap) {
radarPos = gridToWorld(assetOnMap.x(), assetOnMap.y());
displayAsset(assetOnMap);
@@ -768,8 +773,9 @@ private void throwBomb(UUID uuid) {
}
private void throwMatrix(UUID uuid) {
//app.getAcousticHandler().playSound(MdgaSound.MATRIX);
Spatial piece = pieces.get(uuid).getSpatial();
piece.addControl(new MatrixAnimation(app, 1, radarPos,()->{
piece.addControl(new MatrixAnimation(app, 1, radarPos,()-> {
piece.addControl(new FadeControl(1,1,0,
() -> {
throwPiece(uuid);
@@ -777,8 +783,6 @@ private void throwMatrix(UUID uuid) {
}
));
}));
}
private void throwMissle(UUID uuid) {
@@ -786,12 +790,7 @@ private void throwMissle(UUID uuid) {
}
private void throwShell(UUID uuid) {
}
public void throwBombAnim(UUID uuid){
pieces.get(uuid).getSpatial().addControl(new ShellAnimation(tankTop, app, ()-> throwPieceAnim(uuid)));
}
/**

View File

@@ -109,6 +109,9 @@ private static Asset getLoadedAsset(String assetName) {
case "tank" -> Asset.tank;
case "treeSmall" -> Asset.treeSmall;
case "treeBig" -> Asset.treeBig;
case "tank_shoot" -> Asset.tankShoot;
case "treesBigBackground" -> Asset.treesBigBackground;
case "treesSmallBackground" -> Asset.treesSmallBackground;
default -> throw new IllegalStateException("Unexpected value: " + assetName);
};
}

View File

@@ -0,0 +1,105 @@
package pp.mdga.client.board;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import pp.mdga.client.InitControl;
import static pp.mdga.client.Util.linInt;
public class TankTopControl extends InitControl {
private float timer = 0; // Time elapsed
private final static float DURATION = 1.5f; // Total rotation duration in seconds
private boolean rotating = false; // Flag to track if rotation is active
private float startAngle = 0;
private float endAngle = 0;
private Runnable actionAfter = null;
@Override
protected void controlUpdate(float tpf) {
if (!rotating) return;
// Update the timer
timer += tpf;
// Calculate interpolation factor (0 to 1)
float t = timer / DURATION;
if (t >= 1) t = 1;
float curAngle = linInt(startAngle, endAngle, t);
// Interpolate the rotation
Quaternion interpolatedRotation = new Quaternion();
interpolatedRotation.fromAngleAxis((float) Math.toRadians(curAngle), Vector3f.UNIT_Z);
// Apply the interpolated rotation to the spatial
spatial.setLocalRotation(interpolatedRotation);
if(t >= 1){
rotating = false;
if(actionAfter != null) actionAfter.run();
}
}
public void rotate(Vector3f enemyPos, Runnable actionAfter) {
if (spatial == null) throw new RuntimeException("spatial is null");
startAngle = getOwnAngle();
endAngle = getEnemyAngle(enemyPos);
// Adjust endAngle to ensure the shortest path
float deltaAngle = endAngle - startAngle;
if (deltaAngle > 180) {
endAngle -= 360; // Rotate counterclockwise
} else if (deltaAngle < -180) {
endAngle += 360; // Rotate clockwise
}
timer = 0;
rotating = true;
this.actionAfter = actionAfter; // Store the action to execute after rotation
}
private float getEnemyAngle(Vector3f enemyPos){
// Direction to the enemy in the XY plane
Vector3f direction = enemyPos.subtract(spatial.getLocalTranslation());
direction.z = 0; // Project to XY plane
direction.normalizeLocal();
Vector3f reference = Vector3f.UNIT_Y.mult(-1);
// Calculate the angle between the direction vector and the reference vector
float angle = FastMath.acos(reference.dot(direction));
// Determine rotation direction using the cross product
Vector3f cross = reference.cross(direction);
if (cross.z < 0) {
angle = -angle;
}
return (float) Math.toDegrees(angle); // Return the absolute angle in degrees
}
private float getOwnAngle() {
// Tank's forward direction in the XY plane
Vector3f forward = spatial.getLocalRotation().mult(Vector3f.UNIT_Y);
forward.z = 0; // Project to XY plane
forward.normalizeLocal();
// Reference vector: Positive X-axis
Vector3f reference = Vector3f.UNIT_Y;
// Calculate the angle between the forward vector and the reference vector
float angle = FastMath.acos(reference.dot(forward));
// Determine rotation direction using the cross product
Vector3f cross = reference.cross(forward);
if (cross.z < 0) { // For Z-up, check the Z component of the cross product
angle = -angle;
}
return (float) Math.toDegrees(angle); // Return the absolute angle in radians
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -1,4 +1,6 @@
world 0,0 90
treesBigBackground 0,0 90
treesSmallBackground 0,0 90
#Marine Pos
@@ -56,7 +58,8 @@ big_tent -10,-9 130
big_tent 9,-10 225
radar 0,10 -20
tank -1,-10 135
tank 0,-18 180
#tank 0,-18 180
tank_shoot 0,-18 180
tank 3,-18 180
tank -3,-18 180
@@ -270,3 +273,4 @@ treeBig 12,22 360

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,554 @@
# Blender 3.6.5
# www.blender.org
o tank_top
v 0.136104 -4.382030 2.447842
v 0.136104 -4.313100 2.681757
v -0.107755 -4.382030 2.447842
v -0.107755 -4.313100 2.681757
v 0.136104 -5.171963 2.680617
v 0.136104 -5.103033 2.914532
v -0.107755 -5.171963 2.680617
v -0.107755 -5.103033 2.914532
v 0.104217 -1.266581 1.563035
v 0.104217 -1.215678 1.735777
v -0.075869 -1.266581 1.563035
v -0.075869 -1.215678 1.735777
v 0.104218 -5.321341 2.757877
v 0.104218 -5.270438 2.930620
v -0.075868 -5.321341 2.757877
v -0.075868 -5.270438 2.930620
v 0.170290 -1.697908 1.621255
v 0.170290 -1.609653 1.920754
v -0.141942 -1.697908 1.621255
v -0.141942 -1.609653 1.920754
v 0.229706 -1.077489 1.376490
v 0.229706 -0.955645 1.789975
v -0.201358 -1.077489 1.376490
v -0.201358 -0.955645 1.789975
v 0.514900 0.276165 1.806222
v 0.514900 0.588869 2.433130
v -0.442998 0.276164 1.806222
v -0.442998 0.588869 2.433130
v 0.514900 0.342851 1.772958
v 0.514900 0.655556 2.399867
v -0.442998 0.342851 1.772958
v -0.442998 0.655556 2.399867
v -0.571633 -0.809063 1.704162
v -0.571633 -0.809063 2.393599
v -0.723737 -0.809063 1.704162
v -0.723737 -0.809063 2.393599
v -0.571633 -0.656959 1.704161
v -0.571633 -0.656959 2.393600
v -0.723737 -0.656959 1.704161
v -0.723737 -0.656959 2.393600
v -0.950927 -0.897974 2.389141
v -0.950927 -0.803313 2.389141
v -0.861627 -0.897974 2.604730
v -0.861627 -0.803313 2.604730
v -0.646038 -0.897974 2.694029
v -0.646038 -0.803313 2.694029
v -0.430449 -0.897974 2.604729
v -0.430449 -0.803313 2.604730
v -0.341149 -0.897974 2.389141
v -0.341149 -0.803313 2.389141
v -0.430449 -0.897974 2.173552
v -0.430449 -0.803313 2.173552
v -0.646038 -0.897974 2.084251
v -0.646038 -0.803313 2.084251
v -0.861627 -0.897974 2.173552
v -0.861627 -0.803313 2.173552
v -0.799948 -0.357073 2.051851
v -0.784767 0.368207 2.051851
v -0.423762 0.888095 2.051851
v 0.525389 0.907164 2.051851
v 0.864924 0.401350 2.051851
v 0.849742 -0.323930 2.051851
v 0.387428 -1.063397 2.051851
v -0.368214 -1.078578 2.051851
v -1.026731 -0.445682 1.384443
v -1.007409 0.477460 1.384443
v -0.547920 1.139177 1.384443
v 0.660166 1.163448 1.384443
v 1.092329 0.519645 1.384443
v 1.073006 -0.403497 1.384443
v 0.484569 -1.344695 1.384443
v -0.477218 -1.364018 1.384443
v -1.077985 -0.465708 1.887314
v -1.057726 0.502151 1.887314
v -0.575980 1.195922 1.887314
v 0.690626 1.221368 1.887314
v 1.143722 0.546380 1.887314
v 1.123464 -0.421479 1.887314
v 0.506523 -1.408269 1.887314
v -0.501853 -1.428528 1.887314
v -1.085964 0.516008 1.535923
v -0.591726 1.227766 1.535923
v 0.707720 1.253873 1.535923
v 1.172564 0.561383 1.535923
v 1.151780 -0.431571 1.535923
v 0.518844 -1.443946 1.535923
v -0.515678 -1.464730 1.535923
v -1.106748 -0.476946 1.535923
v 0.612842 -0.142856 2.090828
v 0.612842 0.599197 2.091472
v -0.540940 -0.142856 2.090828
v -0.540940 0.599197 2.091472
v 0.612842 -0.142788 2.011893
v 0.612842 0.599266 2.012537
v -0.540940 -0.142788 2.011893
v -0.540940 0.599265 2.012537
v 0.445467 -0.035209 2.095495
v 0.445467 0.491550 2.095952
v -0.373565 -0.035210 2.095495
v -0.373565 0.491550 2.095952
vn -0.0000 0.9592 -0.2827
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -0.9592 0.2827
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -0.2827 -0.9592
vn -0.0000 0.2827 0.9592
vn -0.9960 -0.0855 0.0252
vn 0.9960 -0.0855 0.0252
vn -0.0000 -0.3670 -0.9302
vn -0.0000 0.1961 0.9806
vn -0.0000 -0.8949 0.4464
vn -0.0000 0.8949 -0.4464
vn -0.0000 -0.4464 -0.8949
vn -0.0000 0.4464 0.8949
vn -0.0000 -1.0000 -0.0000
vn -0.0000 1.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vn -0.0000 -0.0000 1.0000
vn -0.9239 -0.0000 0.3827
vn -0.3827 -0.0000 0.9239
vn 0.3827 -0.0000 0.9239
vn 0.9239 -0.0000 0.3827
vn 0.9239 -0.0000 -0.3827
vn 0.3827 -0.0000 -0.9239
vn -0.3827 -0.0000 -0.9239
vn -0.9239 -0.0000 -0.3827
vn -0.5124 0.0107 0.8587
vn -0.3944 0.2739 0.8772
vn -0.0094 0.4678 0.8838
vn 0.3870 0.2598 0.8847
vn 0.5124 -0.0107 0.8587
vn 0.4253 -0.2659 0.8651
vn 0.0086 -0.4282 0.9037
vn -0.4187 -0.2505 0.8729
vn -0.8549 -0.5116 0.0863
vn 0.0200 -0.9946 0.1017
vn 0.8450 -0.5283 0.0833
vn 0.9965 -0.0209 0.0809
vn 0.8268 0.5550 0.0916
vn -0.0200 0.9956 0.0911
vn -0.8182 0.5681 0.0882
vn -0.9965 0.0209 0.0809
vn -0.8856 0.0185 -0.4640
vn -0.7133 0.4953 -0.4959
vn -0.0173 0.8609 -0.5085
vn 0.7140 0.4793 -0.5103
vn 0.8856 -0.0185 -0.4640
vn 0.7463 -0.4666 -0.4746
vn 0.0168 -0.8346 -0.5506
vn -0.7489 -0.4482 -0.4881
vn -0.0000 -0.0009 1.0000
vn -0.0000 0.0009 -1.0000
vn -0.0000 -1.0000 -0.0009
vn -0.0000 1.0000 0.0009
vt 0.302708 0.924112
vt 0.288040 0.909443
vt 0.302708 0.909443
vt 0.693823 0.755933
vt 0.708491 0.805468
vt 0.693821 0.805468
vt 0.933974 0.202686
vt 0.919330 0.188017
vt 0.933973 0.188017
vt 0.651344 0.857452
vt 0.636674 0.807918
vt 0.651343 0.807918
vt 0.134278 0.805715
vt 0.119609 0.855249
vt 0.119609 0.805715
vt 0.708491 0.751615
vt 0.693871 0.702081
vt 0.708540 0.702096
vt 0.766441 0.570082
vt 0.755608 0.559249
vt 0.766441 0.559249
vt 0.537931 0.359392
vt 0.548757 0.613657
vt 0.537924 0.613657
vt 0.781573 0.570082
vt 0.770759 0.559250
vt 0.781572 0.559250
vt 0.579073 0.613652
vt 0.568233 0.359392
vt 0.579066 0.359392
vt 0.563915 0.359392
vt 0.553082 0.613655
vt 0.553082 0.359392
vt 0.437696 0.622253
vt 0.448781 0.368077
vt 0.448529 0.622264
vt 0.615148 0.975854
vt 0.633896 0.957072
vt 0.633897 0.975854
vt 0.948652 0.917591
vt 0.926304 0.957587
vt 0.929870 0.917591
vt 0.106854 0.798464
vt 0.132782 0.772534
vt 0.132782 0.798464
vt 0.952676 0.496495
vt 0.930312 0.536496
vt 0.926746 0.496495
vt 0.938021 0.614748
vt 0.960377 0.574830
vt 0.956803 0.614748
vt 0.948620 0.913273
vt 0.926304 0.873209
vt 0.952234 0.873235
vt 0.288040 0.924112
vt 0.708492 0.755933
vt 0.919331 0.202686
vt 0.636675 0.857452
vt 0.134278 0.855249
vt 0.693822 0.751601
vt 0.755609 0.570082
vt 0.548764 0.359392
vt 0.770759 0.570082
vt 0.568241 0.613652
vt 0.563915 0.613655
vt 0.437949 0.368066
vt 0.615148 0.957072
vt 0.952234 0.957587
vt 0.106853 0.772534
vt 0.949094 0.536496
vt 0.934447 0.574830
vt 0.929838 0.913255
vt 0.040925 0.927951
vt 0.002159 0.870340
vt 0.040923 0.870330
vt 0.834247 0.352865
vt 0.838729 0.310724
vt 0.838729 0.352865
vt 0.508750 0.936735
vt 0.546231 0.879133
vt 0.546232 0.936754
vt 0.843047 0.310724
vt 0.847530 0.352865
vt 0.843047 0.352865
vt 0.697810 0.640142
vt 0.693822 0.697763
vt 0.693822 0.640142
vt 0.323097 0.582179
vt 0.319198 0.524554
vt 0.323154 0.524558
vt 0.768084 0.828693
vt 0.777234 0.870091
vt 0.768084 0.870092
vt 0.499788 0.814544
vt 0.508937 0.856016
vt 0.499788 0.856016
vt 0.218712 0.819723
vt 0.227862 0.861192
vt 0.218712 0.861192
vt 0.420031 0.812900
vt 0.429180 0.854372
vt 0.420031 0.854372
vt 0.785891 0.559250
vt 0.795040 0.568399
vt 0.785891 0.568399
vt 0.537924 0.700847
vt 0.547080 0.691706
vt 0.547071 0.700856
vt 0.966064 0.285237
vt 0.971814 0.298192
vt 0.966120 0.298192
vt 0.453257 0.607137
vt 0.458792 0.620111
vt 0.453099 0.620105
vt 0.453125 0.594168
vt 0.458949 0.607142
vt 0.961680 0.298192
vt 0.956052 0.285237
vt 0.961746 0.285237
vt 0.961746 0.311174
vt 0.955987 0.298192
vt 0.578003 0.963076
vt 0.583636 0.950107
vt 0.583697 0.963076
vt 0.713986 0.956996
vt 0.737947 0.947070
vt 0.747872 0.971032
vt 0.578003 0.937139
vt 0.577943 0.950107
vt 0.971758 0.311174
vt 0.966064 0.311174
vt 0.307851 0.954728
vt 0.317762 0.944793
vt 0.331777 0.978655
vt 0.921986 0.878344
vt 0.905406 0.827575
vt 0.921986 0.820132
vt 0.884350 0.795866
vt 0.893886 0.777817
vt 0.827291 0.793524
vt 0.817744 0.774692
vt 0.789645 0.814701
vt 0.806235 0.823505
vt 0.789645 0.872913
vt 0.833108 0.912166
vt 0.825506 0.933015
vt 0.878533 0.914030
vt 0.886125 0.935503
vt 0.036904 0.863435
vt 0.057955 0.805815
vt 0.058039 0.865604
vt 0.893784 0.134399
vt 0.914942 0.195798
vt 0.893712 0.196631
vt 0.011369 0.804651
vt 0.032412 0.863875
vt 0.011276 0.866012
vt 0.032503 0.745834
vt 0.011370 0.744910
vt 0.032435 0.705568
vt 0.011300 0.703600
vt 0.297104 0.788044
vt 0.318245 0.865182
vt 0.297086 0.866212
vt 0.057959 0.746102
vt 0.036897 0.705526
vt 0.058032 0.703600
vt 0.036826 0.746953
vt 0.067083 0.748470
vt 0.067078 0.803985
vt 0.067151 0.708957
vt 0.288040 0.863346
vt 0.288056 0.790674
vt 0.002181 0.709075
vt 0.002246 0.747480
vt 0.002245 0.803021
vt 0.002159 0.860067
vt 0.884977 0.194314
vt 0.885044 0.136458
vt 0.067157 0.859570
vt 0.709979 0.282916
vt 0.754532 0.352364
vt 0.709910 0.352320
vt 0.702128 0.640146
vt 0.706914 0.684776
vt 0.702166 0.684781
vt 0.415360 0.813107
vt 0.370725 0.882511
vt 0.370725 0.813107
vt 0.427272 0.808484
vt 0.432057 0.763854
vt 0.432020 0.808488
vt 0.542664 0.617975
vt 0.537927 0.687379
vt 0.537924 0.617975
vt 0.457848 0.589850
vt 0.453099 0.520446
vt 0.457847 0.520446
vt 0.919379 0.134399
vt 0.951006 0.183699
vt 0.919330 0.183667
vt 0.002161 0.927961
vt 0.834247 0.310724
vt 0.508749 0.879113
vt 0.847530 0.310724
vt 0.697810 0.697763
vt 0.319140 0.582175
vt 0.777234 0.828693
vt 0.508937 0.814544
vt 0.227862 0.819722
vt 0.429180 0.812900
vt 0.795040 0.559250
vt 0.537933 0.691697
vt 0.971758 0.285237
vt 0.458817 0.594174
vt 0.956052 0.311174
vt 0.723911 0.980958
vt 0.713986 0.971033
vt 0.723911 0.947070
vt 0.747872 0.956995
vt 0.737947 0.980958
vt 0.583697 0.937139
vt 0.331777 0.944776
vt 0.341688 0.954686
vt 0.341688 0.968720
vt 0.317762 0.978673
vt 0.307851 0.968762
vt 0.905406 0.871198
vt 0.806235 0.867128
vt 0.036821 0.805157
vt 0.915012 0.135139
vt 0.032502 0.804065
vt 0.318263 0.788989
vt 0.754601 0.282960
vt 0.706876 0.640142
vt 0.415360 0.882511
vt 0.427309 0.763850
vt 0.542666 0.687379
vt 0.453100 0.589850
vt 0.951055 0.134431
s 1
f 3/1/1 2/2/1 1/3/1
f 7/4/2 4/5/2 3/6/2
f 5/7/3 8/8/3 7/9/3
f 1/10/4 6/11/4 5/12/4
f 1/13/5 7/14/5 3/15/5
f 8/16/6 2/17/6 4/18/6
f 11/19/1 10/20/1 9/21/1
f 15/22/2 12/23/2 11/24/2
f 13/25/3 16/26/3 15/27/3
f 9/28/4 14/29/4 13/30/4
f 9/31/5 15/32/5 11/33/5
f 14/34/6 12/35/6 16/36/6
f 18/37/3 19/38/3 17/39/3
f 20/40/7 23/41/7 19/42/7
f 24/43/1 21/44/1 23/45/1
f 22/46/8 17/47/8 21/48/8
f 19/49/9 21/50/9 17/51/9
f 20/52/10 22/53/10 24/54/10
f 3/1/1 4/55/1 2/2/1
f 7/4/2 8/56/2 4/5/2
f 5/7/3 6/57/3 8/8/3
f 1/10/4 2/58/4 6/11/4
f 1/13/5 5/59/5 7/14/5
f 8/16/6 6/60/6 2/17/6
f 11/19/1 12/61/1 10/20/1
f 15/22/2 16/62/2 12/23/2
f 13/25/3 14/63/3 16/26/3
f 9/28/4 10/64/4 14/29/4
f 9/31/5 13/65/5 15/32/5
f 14/34/6 10/66/6 12/35/6
f 18/37/3 20/67/3 19/38/3
f 20/40/7 24/68/7 23/41/7
f 24/43/1 22/69/1 21/44/1
f 22/46/8 18/70/8 17/47/8
f 19/49/9 23/71/9 21/50/9
f 20/52/10 18/72/10 22/53/10
f 25/73/11 28/74/11 27/75/11
f 27/76/2 32/77/2 31/78/2
f 32/79/12 29/80/12 31/81/12
f 30/82/4 25/83/4 29/84/4
f 31/85/13 25/86/13 27/87/13
f 32/88/14 26/89/14 30/90/14
f 34/91/15 35/92/15 33/93/15
f 36/94/2 39/95/2 35/96/2
f 40/97/16 37/98/16 39/99/16
f 38/100/4 33/101/4 37/102/4
f 35/103/17 37/104/17 33/105/17
f 36/106/18 38/107/18 40/108/18
f 43/109/19 42/110/19 41/111/19
f 45/112/20 44/113/20 43/114/20
f 47/115/21 46/116/21 45/112/21
f 49/117/22 48/118/22 47/119/22
f 51/120/23 50/121/23 49/117/23
f 51/122/24 54/123/24 52/124/24
f 46/125/16 50/126/16 54/127/16
f 55/128/25 54/123/25 53/129/25
f 41/111/26 56/130/26 55/131/26
f 45/132/15 43/133/15 51/134/15
f 73/135/27 58/136/27 74/137/27
f 74/137/28 59/138/28 75/139/28
f 75/139/29 60/140/29 76/141/29
f 60/140/30 77/142/30 76/141/30
f 61/143/31 78/144/31 77/142/31
f 78/144/32 63/145/32 79/146/32
f 61/143/18 60/140/18 59/138/18
f 79/146/33 64/147/33 80/148/33
f 64/147/34 73/135/34 80/148/34
f 80/149/35 88/150/35 87/151/35
f 86/152/36 80/153/36 87/154/36
f 85/155/37 79/156/37 86/157/37
f 77/158/38 85/155/38 84/159/38
f 76/160/39 84/159/39 83/161/39
f 82/162/40 76/163/40 83/164/40
f 81/165/41 75/166/41 82/167/41
f 88/150/42 74/168/42 81/165/42
f 88/150/43 66/169/43 65/170/43
f 81/165/44 67/171/44 66/169/44
f 82/162/45 68/172/45 67/173/45
f 68/174/46 84/159/46 69/175/46
f 69/175/47 85/155/47 70/176/47
f 85/155/48 71/177/48 70/176/48
f 86/152/49 72/178/49 71/179/49
f 72/180/50 88/150/50 65/170/50
f 89/181/51 92/182/51 91/183/51
f 92/184/2 95/185/2 91/186/2
f 96/187/52 93/188/52 95/189/52
f 93/190/4 90/191/4 89/192/4
f 95/193/53 89/194/53 91/195/53
f 96/196/54 90/197/54 94/198/54
f 97/199/51 100/200/51 99/201/51
f 25/73/11 26/202/11 28/74/11
f 27/76/2 28/203/2 32/77/2
f 32/79/12 30/204/12 29/80/12
f 30/82/4 26/205/4 25/83/4
f 31/85/13 29/206/13 25/86/13
f 32/88/14 28/207/14 26/89/14
f 34/91/15 36/208/15 35/92/15
f 36/94/2 40/209/2 39/95/2
f 40/97/16 38/210/16 37/98/16
f 38/100/4 34/211/4 33/101/4
f 35/103/17 39/212/17 37/104/17
f 36/106/18 34/213/18 38/107/18
f 43/109/19 44/214/19 42/110/19
f 45/112/20 46/116/20 44/113/20
f 47/115/21 48/215/21 46/116/21
f 49/117/22 50/121/22 48/118/22
f 51/120/23 52/216/23 50/121/23
f 51/122/24 53/129/24 54/123/24
f 42/217/16 44/218/16 46/125/16
f 46/125/16 48/219/16 50/126/16
f 50/126/16 52/220/16 54/127/16
f 54/127/16 56/221/16 42/217/16
f 42/217/16 46/125/16 54/127/16
f 55/128/25 56/222/25 54/123/25
f 41/111/26 42/110/26 56/130/26
f 43/133/15 41/223/15 51/134/15
f 41/223/15 55/224/15 51/134/15
f 55/224/15 53/225/15 51/134/15
f 51/134/15 49/226/15 47/227/15
f 47/227/15 45/132/15 51/134/15
f 73/135/27 57/228/27 58/136/27
f 74/137/28 58/136/28 59/138/28
f 75/139/29 59/138/29 60/140/29
f 60/140/30 61/143/30 77/142/30
f 61/143/31 62/229/31 78/144/31
f 78/144/32 62/229/32 63/145/32
f 59/138/18 58/136/18 61/143/18
f 58/136/18 57/228/18 62/229/18
f 61/143/18 58/136/18 62/229/18
f 57/228/18 64/147/18 63/145/18
f 63/145/18 62/229/18 57/228/18
f 79/146/33 63/145/33 64/147/33
f 64/147/34 57/228/34 73/135/34
f 80/149/35 73/230/35 88/150/35
f 86/152/36 79/231/36 80/153/36
f 85/155/37 78/232/37 79/156/37
f 77/158/38 78/232/38 85/155/38
f 76/160/39 77/158/39 84/159/39
f 82/162/40 75/233/40 76/163/40
f 81/165/41 74/168/41 75/166/41
f 88/150/42 73/230/42 74/168/42
f 88/150/43 81/165/43 66/169/43
f 81/165/44 82/167/44 67/171/44
f 82/162/45 83/164/45 68/172/45
f 68/174/46 83/161/46 84/159/46
f 69/175/47 84/159/47 85/155/47
f 85/155/48 86/157/48 71/177/48
f 86/152/49 87/154/49 72/178/49
f 72/180/50 87/151/50 88/150/50
f 89/181/51 90/234/51 92/182/51
f 92/184/2 96/235/2 95/185/2
f 96/187/52 94/236/52 93/188/52
f 93/190/4 94/237/4 90/191/4
f 95/193/53 93/238/53 89/194/53
f 96/196/54 92/239/54 90/197/54
f 97/199/51 98/240/51 100/200/51

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 MiB

After

Width:  |  Height:  |  Size: 13 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 MiB

File diff suppressed because it is too large Load Diff