1/*
2 * Copyright (c) 2009-2010 jMonkeyEngine
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 *   notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 *   notice, this list of conditions and the following disclaimer in the
14 *   documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17 *   may be used to endorse or promote products derived from this software
18 *   without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33package com.jme3.animation;
34
35import com.jme3.export.*;
36import com.jme3.math.Vector3f;
37import com.jme3.util.BufferUtils;
38import java.io.IOException;
39import java.nio.FloatBuffer;
40
41/**
42 * A pose is a list of offsets that say where a mesh vertices should be for this pose.
43 */
44public final class Pose implements Savable, Cloneable {
45
46    private String name;
47    private int targetMeshIndex;
48
49    private Vector3f[] offsets;
50    private int[] indices;
51
52    private transient final Vector3f tempVec  = new Vector3f();
53    private transient final Vector3f tempVec2 = new Vector3f();
54
55    public Pose(String name, int targetMeshIndex, Vector3f[] offsets, int[] indices){
56        this.name = name;
57        this.targetMeshIndex = targetMeshIndex;
58        this.offsets = offsets;
59        this.indices = indices;
60    }
61
62    public int getTargetMeshIndex(){
63        return targetMeshIndex;
64    }
65
66
67    /**
68     * Applies the offsets of this pose to the vertex buffer given by the blend factor.
69     *
70     * @param blend Blend factor, 0 = no change to vertex buffer, 1 = apply full offsets
71     * @param vertbuf Vertex buffer to apply this pose to
72     */
73    public void apply(float blend, FloatBuffer vertbuf){
74        for (int i = 0; i < indices.length; i++){
75            Vector3f offset = offsets[i];
76            int vertIndex   = indices[i];
77
78            tempVec.set(offset).multLocal(blend);
79
80            // acquire vertex
81            BufferUtils.populateFromBuffer(tempVec2, vertbuf, vertIndex);
82
83            // add offset multiplied by factor
84            tempVec2.addLocal(tempVec);
85
86            // write modified vertex
87            BufferUtils.setInBuffer(tempVec2, vertbuf, vertIndex);
88        }
89    }
90
91    /**
92     * This method creates a clone of the current object.
93     * @return a clone of the current object
94     */
95    public Pose clone() {
96		try {
97			Pose result = (Pose) super.clone();
98            result.indices = this.indices.clone();
99            if(this.offsets!=null) {
100            	result.offsets = new Vector3f[this.offsets.length];
101            	for(int i=0;i<this.offsets.length;++i) {
102            		result.offsets[i] = this.offsets[i].clone();
103            	}
104            }
105    		return result;
106        } catch (CloneNotSupportedException e) {
107            throw new AssertionError();
108        }
109	}
110
111    public void write(JmeExporter e) throws IOException {
112        OutputCapsule out = e.getCapsule(this);
113        out.write(name, "name", "");
114        out.write(targetMeshIndex, "meshIndex", -1);
115        out.write(offsets, "offsets", null);
116        out.write(indices, "indices", null);
117    }
118
119    public void read(JmeImporter i) throws IOException {
120        InputCapsule in = i.getCapsule(this);
121        name = in.readString("name", "");
122        targetMeshIndex = in.readInt("meshIndex", -1);
123        offsets = (Vector3f[]) in.readSavableArray("offsets", null);
124        indices = in.readIntArray("indices", null);
125    }
126}
127