aboutsummaryrefslogtreecommitdiff
path: root/engine/src/tools/jme3tools/converters/model/strip/StripInfo.java
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/tools/jme3tools/converters/model/strip/StripInfo.java')
-rw-r--r--engine/src/tools/jme3tools/converters/model/strip/StripInfo.java355
1 files changed, 355 insertions, 0 deletions
diff --git a/engine/src/tools/jme3tools/converters/model/strip/StripInfo.java b/engine/src/tools/jme3tools/converters/model/strip/StripInfo.java
new file mode 100644
index 0000000..a9b1098
--- /dev/null
+++ b/engine/src/tools/jme3tools/converters/model/strip/StripInfo.java
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jme3tools.converters.model.strip;
+
+/**
+ *
+ */
+class StripInfo {
+
+ StripStartInfo m_startInfo;
+ FaceInfoVec m_faces = new FaceInfoVec();
+ int m_stripId;
+ int m_experimentId;
+
+ boolean visited;
+
+ int m_numDegenerates;
+
+
+ public StripInfo(StripStartInfo startInfo,int stripId, int experimentId) {
+
+ m_startInfo = startInfo;
+ m_stripId = stripId;
+ m_experimentId = experimentId;
+ visited = false;
+ m_numDegenerates = 0;
+ }
+
+ boolean isExperiment() {
+ return m_experimentId >= 0;
+ }
+
+ boolean isInStrip(FaceInfo faceInfo) {
+ if(faceInfo == null)
+ return false;
+
+ return (m_experimentId >= 0 ? faceInfo.m_testStripId == m_stripId : faceInfo.m_stripId == m_stripId);
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+// IsMarked()
+//
+// If either the faceInfo has a real strip index because it is
+// already assign to a committed strip OR it is assigned in an
+// experiment and the experiment index is the one we are building
+// for, then it is marked and unavailable
+ boolean isMarked(FaceInfo faceInfo){
+ return (faceInfo.m_stripId >= 0) || (isExperiment() && faceInfo.m_experimentId == m_experimentId);
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+// MarkTriangle()
+//
+// Marks the face with the current strip ID
+//
+ void markTriangle(FaceInfo faceInfo){
+ if (isExperiment()){
+ faceInfo.m_experimentId = m_experimentId;
+ faceInfo.m_testStripId = m_stripId;
+ }
+ else{
+ faceInfo.m_experimentId = -1;
+ faceInfo.m_stripId = m_stripId;
+ }
+ }
+
+
+ boolean unique(FaceInfoVec faceVec, FaceInfo face)
+ {
+ boolean bv0, bv1, bv2; //bools to indicate whether a vertex is in the faceVec or not
+ bv0 = bv1 = bv2 = false;
+
+ for(int i = 0; i < faceVec.size(); i++)
+ {
+ if(!bv0)
+ {
+ if( (faceVec.at(i).m_v0 == face.m_v0) ||
+ (faceVec.at(i).m_v1 == face.m_v0) ||
+ (faceVec.at(i).m_v2 == face.m_v0) )
+ bv0 = true;
+ }
+
+ if(!bv1)
+ {
+ if( (faceVec.at(i).m_v0 == face.m_v1) ||
+ (faceVec.at(i).m_v1 == face.m_v1) ||
+ (faceVec.at(i).m_v2 == face.m_v1) )
+ bv1 = true;
+ }
+
+ if(!bv2)
+ {
+ if( (faceVec.at(i).m_v0 == face.m_v2) ||
+ (faceVec.at(i).m_v1 == face.m_v2) ||
+ (faceVec.at(i).m_v2 == face.m_v2) )
+ bv2 = true;
+ }
+
+ //the face is not unique, all it's vertices exist in the face vector
+ if(bv0 && bv1 && bv2)
+ return false;
+ }
+
+ //if we get out here, it's unique
+ return true;
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+// Build()
+//
+// Builds a strip forward as far as we can go, then builds backwards, and joins the two lists
+//
+ void build(EdgeInfoVec edgeInfos, FaceInfoVec faceInfos)
+ {
+ // used in building the strips forward and backward
+ IntVec scratchIndices = new IntVec();
+
+ // build forward... start with the initial face
+ FaceInfoVec forwardFaces = new FaceInfoVec();
+ FaceInfoVec backwardFaces = new FaceInfoVec();
+ forwardFaces.add(m_startInfo.m_startFace);
+
+ markTriangle(m_startInfo.m_startFace);
+
+ int v0 = (m_startInfo.m_toV1 ? m_startInfo.m_startEdge.m_v0 : m_startInfo.m_startEdge.m_v1);
+ int v1 = (m_startInfo.m_toV1 ? m_startInfo.m_startEdge.m_v1 : m_startInfo.m_startEdge.m_v0);
+
+ // easiest way to get v2 is to use this function which requires the
+ // other indices to already be in the list.
+ scratchIndices.add(v0);
+ scratchIndices.add(v1);
+ int v2 = Stripifier.getNextIndex(scratchIndices, m_startInfo.m_startFace);
+ scratchIndices.add(v2);
+
+ //
+ // build the forward list
+ //
+ int nv0 = v1;
+ int nv1 = v2;
+
+ FaceInfo nextFace = Stripifier.findOtherFace(edgeInfos, nv0, nv1, m_startInfo.m_startFace);
+ while (nextFace != null && !isMarked(nextFace))
+ {
+ //check to see if this next face is going to cause us to die soon
+ int testnv0 = nv1;
+ int testnv1 = Stripifier.getNextIndex(scratchIndices, nextFace);
+
+ FaceInfo nextNextFace = Stripifier.findOtherFace(edgeInfos, testnv0, testnv1, nextFace);
+
+ if( (nextNextFace == null) || (isMarked(nextNextFace)) )
+ {
+ //uh, oh, we're following a dead end, try swapping
+ FaceInfo testNextFace = Stripifier.findOtherFace(edgeInfos, nv0, testnv1, nextFace);
+
+ if( ((testNextFace != null) && !isMarked(testNextFace)) )
+ {
+ //we only swap if it buys us something
+
+ //add a "fake" degenerate face
+ FaceInfo tempFace = new FaceInfo(nv0, nv1, nv0);
+
+ forwardFaces.add(tempFace);
+ markTriangle(tempFace);
+
+ scratchIndices.add(nv0);
+ testnv0 = nv0;
+
+ ++m_numDegenerates;
+ }
+
+ }
+
+ // add this to the strip
+ forwardFaces.add(nextFace);
+
+ markTriangle(nextFace);
+
+ // add the index
+ //nv0 = nv1;
+ //nv1 = NvStripifier::GetNextIndex(scratchIndices, nextFace);
+ scratchIndices.add(testnv1);
+
+ // and get the next face
+ nv0 = testnv0;
+ nv1 = testnv1;
+
+ nextFace = Stripifier.findOtherFace(edgeInfos, nv0, nv1, nextFace);
+
+ }
+
+ // tempAllFaces is going to be forwardFaces + backwardFaces
+ // it's used for Unique()
+ FaceInfoVec tempAllFaces = new FaceInfoVec();
+ for(int i = 0; i < forwardFaces.size(); i++)
+ tempAllFaces.add(forwardFaces.at(i));
+
+ //
+ // reset the indices for building the strip backwards and do so
+ //
+ scratchIndices.clear();
+ scratchIndices.add(v2);
+ scratchIndices.add(v1);
+ scratchIndices.add(v0);
+ nv0 = v1;
+ nv1 = v0;
+ nextFace = Stripifier.findOtherFace(edgeInfos, nv0, nv1, m_startInfo.m_startFace);
+ while (nextFace != null && !isMarked(nextFace))
+ {
+ //this tests to see if a face is "unique", meaning that its vertices aren't already in the list
+ // so, strips which "wrap-around" are not allowed
+ if(!unique(tempAllFaces, nextFace))
+ break;
+
+ //check to see if this next face is going to cause us to die soon
+ int testnv0 = nv1;
+ int testnv1 = Stripifier.getNextIndex(scratchIndices, nextFace);
+
+ FaceInfo nextNextFace = Stripifier.findOtherFace(edgeInfos, testnv0, testnv1, nextFace);
+
+ if( (nextNextFace == null) || (isMarked(nextNextFace)) )
+ {
+ //uh, oh, we're following a dead end, try swapping
+ FaceInfo testNextFace = Stripifier.findOtherFace(edgeInfos, nv0, testnv1, nextFace);
+ if( ((testNextFace != null) && !isMarked(testNextFace)) )
+ {
+ //we only swap if it buys us something
+
+ //add a "fake" degenerate face
+ FaceInfo tempFace = new FaceInfo(nv0, nv1, nv0);
+
+ backwardFaces.add(tempFace);
+ markTriangle(tempFace);
+ scratchIndices.add(nv0);
+ testnv0 = nv0;
+
+ ++m_numDegenerates;
+ }
+
+ }
+
+ // add this to the strip
+ backwardFaces.add(nextFace);
+
+ //this is just so Unique() will work
+ tempAllFaces.add(nextFace);
+
+ markTriangle(nextFace);
+
+ // add the index
+ //nv0 = nv1;
+ //nv1 = NvStripifier::GetNextIndex(scratchIndices, nextFace);
+ scratchIndices.add(testnv1);
+
+ // and get the next face
+ nv0 = testnv0;
+ nv1 = testnv1;
+ nextFace = Stripifier.findOtherFace(edgeInfos, nv0, nv1, nextFace);
+ }
+
+ // Combine the forward and backwards stripification lists and put into our own face vector
+ combine(forwardFaces, backwardFaces);
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+// Combine()
+//
+// Combines the two input face vectors and puts the result into m_faces
+//
+ void combine(FaceInfoVec forward, FaceInfoVec backward){
+
+ // add backward faces
+ int numFaces = backward.size();
+ for (int i = numFaces - 1; i >= 0; i--)
+ m_faces.add(backward.at(i));
+
+ // add forward faces
+ numFaces = forward.size();
+ for (int i = 0; i < numFaces; i++)
+ m_faces.add(forward.at(i));
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+// SharesEdge()
+//
+// Returns true if the input face and the current strip share an edge
+//
+ boolean sharesEdge(FaceInfo faceInfo, EdgeInfoVec edgeInfos)
+ {
+ //check v0.v1 edge
+ EdgeInfo currEdge = Stripifier.findEdgeInfo(edgeInfos, faceInfo.m_v0, faceInfo.m_v1);
+
+ if(isInStrip(currEdge.m_face0) || isInStrip(currEdge.m_face1))
+ return true;
+
+ //check v1.v2 edge
+ currEdge = Stripifier.findEdgeInfo(edgeInfos, faceInfo.m_v1, faceInfo.m_v2);
+
+ if(isInStrip(currEdge.m_face0) || isInStrip(currEdge.m_face1))
+ return true;
+
+ //check v2.v0 edge
+ currEdge = Stripifier.findEdgeInfo(edgeInfos, faceInfo.m_v2, faceInfo.m_v0);
+
+ if(isInStrip(currEdge.m_face0) || isInStrip(currEdge.m_face1))
+ return true;
+
+ return false;
+
+ }
+
+
+
+
+
+
+
+
+
+
+}