1package com.jme3.scene.mesh;
2
3import com.jme3.scene.Mesh.Mode;
4import java.nio.Buffer;
5
6/**
7 * IndexBuffer implementation that generates vertex indices sequentially
8 * based on a specific Mesh {@link Mode}.
9 * The generated indices are as if the mesh is in the given mode
10 * but contains no index buffer, thus this implementation will
11 * return the indices if the index buffer was there and contained sequential
12 * triangles.
13 * Example:
14 * <ul>
15 * <li>{@link Mode#Triangles}: 0, 1, 2 | 3, 4, 5 | 6, 7, 8 | ...</li>
16 * <li>{@link Mode#TriangleStrip}: 0, 1, 2 | 2, 1, 3 | 2, 3, 4 | ...</li>
17 * <li>{@link Mode#TriangleFan}: 0, 1, 2 | 0, 2, 3 | 0, 3, 4 | ...</li>
18 * </ul>
19 *
20 * @author Kirill Vainer
21 */
22public class VirtualIndexBuffer extends IndexBuffer {
23
24    protected int numVerts = 0;
25    protected int numIndices = 0;
26    protected Mode meshMode;
27
28    public VirtualIndexBuffer(int numVerts, Mode meshMode){
29        this.numVerts = numVerts;
30        this.meshMode = meshMode;
31        switch (meshMode) {
32            case Points:
33                numIndices = numVerts;
34                return;
35            case LineLoop:
36                numIndices = (numVerts - 1) * 2 + 1;
37                return;
38            case LineStrip:
39                numIndices = (numVerts - 1) * 2;
40                return;
41            case Lines:
42                numIndices = numVerts;
43                return;
44            case TriangleFan:
45                numIndices = (numVerts - 2) * 3;
46                return;
47            case TriangleStrip:
48                numIndices = (numVerts - 2) * 3;
49                return;
50            case Triangles:
51                numIndices = numVerts;
52                return;
53            case Hybrid:
54                throw new UnsupportedOperationException();
55        }
56    }
57
58    @Override
59    public int get(int i) {
60        if (meshMode == Mode.Triangles || meshMode == Mode.Lines || meshMode == Mode.Points){
61            return i;
62        }else if (meshMode == Mode.LineStrip){
63            return (i + 1) / 2;
64        }else if (meshMode == Mode.LineLoop){
65            return (i == (numVerts-1)) ? 0 : ((i + 1) / 2);
66        }else if (meshMode == Mode.TriangleStrip){
67           int triIndex   = i/3;
68           int vertIndex  = i%3;
69           boolean isBack = (i/3)%2==1;
70           if (!isBack){
71                return triIndex + vertIndex;
72           }else{
73               switch (vertIndex){
74                   case 0: return triIndex + 1;
75                   case 1: return triIndex;
76                   case 2: return triIndex + 2;
77                   default: throw new AssertionError();
78               }
79            }
80        }else if (meshMode == Mode.TriangleFan){
81            int vertIndex = i%3;
82            if (vertIndex == 0)
83                return 0;
84            else
85                return (i / 3) + vertIndex;
86        }else{
87            throw new UnsupportedOperationException();
88        }
89    }
90
91    @Override
92    public void put(int i, int value) {
93        throw new UnsupportedOperationException("Does not represent index buffer");
94    }
95
96    @Override
97    public int size() {
98        return numIndices;
99    }
100
101    @Override
102    public Buffer getBuffer() {
103        return null;
104    }
105
106}
107