fiore@5
|
1 /*
|
fiore@5
|
2 CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool
|
fiore@5
|
3
|
fiore@5
|
4 Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/)
|
fiore@5
|
5
|
fiore@5
|
6 This program is free software: you can redistribute it and/or modify
|
fiore@5
|
7 it under the terms of the GNU General Public License as published by
|
fiore@5
|
8 the Free Software Foundation, either version 3 of the License, or
|
fiore@5
|
9 (at your option) any later version.
|
fiore@5
|
10
|
fiore@5
|
11 This program is distributed in the hope that it will be useful,
|
fiore@5
|
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
fiore@5
|
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
fiore@5
|
14 GNU General Public License for more details.
|
fiore@5
|
15
|
fiore@5
|
16 You should have received a copy of the GNU General Public License
|
fiore@5
|
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
|
fiore@5
|
18 */
|
fiore@5
|
19
|
fiore@5
|
20 #include "CollectionsManager.h"
|
fiore@5
|
21
|
fiore@5
|
22 using namespace H3DUtil::ArithmeticTypes;
|
fiore@5
|
23
|
fiore@5
|
24 void CollectionsManager::init(void){
|
fiore@5
|
25 /**************** init jni variables **********************/
|
fiore@5
|
26 // --- classes ---
|
fiore@5
|
27 // get the java haptics class
|
fiore@5
|
28 hapticClass = env->GetObjectClass(*haptics);
|
fiore@5
|
29 if(hapticClass == NULL){
|
fiore@5
|
30 stopExecution("Could not find the Haptics class");
|
fiore@5
|
31 }
|
fiore@5
|
32
|
fiore@5
|
33 bitsetClass = env->FindClass("Ljava/util/BitSet;");
|
fiore@5
|
34 if(bitsetClass == NULL)
|
fiore@5
|
35 stopExecution("failed to find bitset class");
|
fiore@5
|
36
|
fiore@5
|
37 //get the node list class
|
fiore@5
|
38 listClass = env->FindClass("Ljava/util/ArrayList;");
|
fiore@5
|
39 if(listClass == NULL)
|
fiore@5
|
40 stopExecution("failed to find list class");
|
fiore@5
|
41
|
fiore@5
|
42 // get the Node class to call the get method on the node list
|
fiore@5
|
43 hapticNodeClass = env->FindClass("Luk/ac/qmul/eecs/ccmi/haptics/Node;");
|
fiore@5
|
44 if(hapticNodeClass == NULL){
|
fiore@5
|
45 stopExecution("Could not find the Node class");
|
fiore@5
|
46 }
|
fiore@5
|
47
|
fiore@5
|
48 // get the Edge class to call the get method on the edge list
|
fiore@5
|
49 hapticEdgeClass = env->FindClass("Luk/ac/qmul/eecs/ccmi/haptics/Edge;");
|
fiore@5
|
50 if(hapticEdgeClass == NULL){
|
fiore@5
|
51 stopExecution("Could not find the Edge class");
|
fiore@5
|
52 }
|
fiore@5
|
53 // --- methods ---
|
fiore@5
|
54 // "get" method id
|
fiore@5
|
55 getMethodId = env->GetMethodID(listClass, "get", "(I)Ljava/lang/Object;");
|
fiore@5
|
56 if(getMethodId == NULL)
|
fiore@5
|
57 stopExecution("Could not retrieve the get method id");
|
fiore@5
|
58
|
fiore@5
|
59 //size method id
|
fiore@5
|
60 sizeMethodId = env->GetMethodID(listClass, "size", "()I");
|
fiore@5
|
61 if(sizeMethodId == NULL)
|
fiore@5
|
62 stopExecution("failed to get size method id");
|
fiore@5
|
63
|
fiore@5
|
64 //get method of the BitSet class
|
fiore@5
|
65 getBitMethodId = env->GetMethodID(bitsetClass, "get","(I)Z");
|
fiore@5
|
66 if(getBitMethodId == NULL)
|
fiore@5
|
67 stopExecution("failed to get the get method id of the BitSet class");
|
fiore@5
|
68
|
fiore@5
|
69 // -- field id's --
|
fiore@5
|
70 //retrieve edgeList field id
|
fiore@5
|
71 edgeListfieldId = env->GetFieldID(hapticClass,"currentEdges", "Ljava/util/ArrayList;");
|
fiore@5
|
72 if(edgeListfieldId == NULL){
|
fiore@5
|
73 stopExecution("failed to find the edge list field id");
|
fiore@5
|
74 }
|
fiore@5
|
75
|
fiore@5
|
76 //retrieve nodeList field id
|
fiore@5
|
77 nodeListfieldId = env->GetFieldID(hapticClass,"currentNodes", "Ljava/util/ArrayList;");
|
fiore@5
|
78 if(nodeListfieldId == NULL){
|
fiore@5
|
79 stopExecution("failed to find the node list field id");
|
fiore@5
|
80 }
|
fiore@5
|
81
|
fiore@5
|
82 // Node fields id's
|
fiore@5
|
83 xFieldId = env->GetFieldID(hapticNodeClass,"x","D");
|
fiore@5
|
84 if(xFieldId == NULL)
|
fiore@5
|
85 stopExecution("Could not find the x field ID");
|
fiore@5
|
86
|
fiore@5
|
87
|
fiore@5
|
88 yFieldId = env->GetFieldID(hapticNodeClass,"y","D");
|
fiore@5
|
89 if(yFieldId == NULL)
|
fiore@5
|
90 stopExecution("Could not find the y field ID");
|
fiore@5
|
91
|
fiore@5
|
92 nodeHapticIdFieldId = env->GetFieldID(hapticNodeClass, "hapticId", "I");
|
fiore@5
|
93 if(nodeHapticIdFieldId == NULL)
|
fiore@5
|
94 stopExecution("Could not find the node hapticId field ID");
|
fiore@5
|
95
|
fiore@5
|
96 nodeDiagramIdFieldId = env->GetFieldID(hapticNodeClass, "diagramId", "I");
|
fiore@5
|
97 if(nodeDiagramIdFieldId == NULL)
|
fiore@5
|
98 stopExecution("Could not find the node diagramId field ID");
|
fiore@5
|
99
|
fiore@5
|
100 // Edge field id's
|
fiore@5
|
101 // edge.hapticId
|
fiore@5
|
102 edgeHapticIdFieldId = env->GetFieldID(hapticEdgeClass, "hapticId", "I");
|
fiore@5
|
103 if(edgeHapticIdFieldId == NULL)
|
fiore@5
|
104 stopExecution("Could not find the edge hapticId field ID");
|
fiore@5
|
105
|
fiore@5
|
106 edgeDiagramIdFieldId = env->GetFieldID(hapticEdgeClass, "diagramId", "I");
|
fiore@5
|
107 if(edgeDiagramIdFieldId == NULL)
|
fiore@5
|
108 stopExecution("Could not find the edge diagramId field ID");
|
fiore@5
|
109
|
fiore@5
|
110 // stipplePattern
|
fiore@5
|
111 stipplePatternfieldId = env->GetFieldID(hapticEdgeClass, "stipplePattern", "I");
|
fiore@5
|
112 if(stipplePatternfieldId == NULL){
|
fiore@5
|
113 stopExecution("Could not find the stipplePattern field ID");
|
fiore@5
|
114 }
|
fiore@5
|
115
|
fiore@5
|
116 edgeSizefieldId = env->GetFieldID(hapticEdgeClass, "size", "I");
|
fiore@5
|
117 if(edgeSizefieldId == NULL)
|
fiore@5
|
118 stopExecution("Could not find edge size field ID");
|
fiore@5
|
119
|
fiore@5
|
120 edgeXsFieldId = env->GetFieldID(hapticEdgeClass,"xs", "[D");
|
fiore@5
|
121 if(edgeXsFieldId == NULL)
|
fiore@5
|
122 stopExecution("Could not find edge xs field ID");
|
fiore@5
|
123
|
fiore@5
|
124 edgeYsFieldId = env->GetFieldID(hapticEdgeClass,"ys", "[D");
|
fiore@5
|
125 if(edgeYsFieldId == NULL)
|
fiore@5
|
126 stopExecution("Could not find edge ys field ID");
|
fiore@5
|
127
|
fiore@5
|
128 edgeAdjMatrixFieldId = env->GetFieldID(hapticEdgeClass,"adjMatrix", "[Ljava/util/BitSet;");
|
fiore@5
|
129 if(edgeAdjMatrixFieldId == NULL)
|
fiore@5
|
130 stopExecution("Could not find edge adjMatrix field ID");
|
fiore@5
|
131
|
fiore@5
|
132 attractPointXFieldId = env->GetFieldID(hapticEdgeClass, "attractPointX", "D");
|
fiore@5
|
133 if(attractPointXFieldId == NULL)
|
fiore@5
|
134 stopExecution("Could not find the edge attractPointX field ID");
|
fiore@5
|
135
|
fiore@5
|
136 attractPointYFieldId = env->GetFieldID(hapticEdgeClass, "attractPointY", "D");
|
fiore@5
|
137 if(attractPointYFieldId == NULL)
|
fiore@5
|
138 stopExecution("Could not find the edge attractPointY field ID");
|
fiore@5
|
139
|
fiore@5
|
140 edgeNodeStartFieldId = env->GetFieldID(hapticEdgeClass, "nodeStart", "I");
|
fiore@5
|
141 if(edgeNodeStartFieldId == NULL)
|
fiore@5
|
142 stopExecution("Could not find the edge nodeStart field ID");
|
fiore@5
|
143 }
|
fiore@5
|
144
|
fiore@5
|
145 const jint CollectionsManager::getNodesNum() {
|
fiore@5
|
146 /* to read the node list field into the nodeList variable each time we get the size is *
|
fiore@5
|
147 * needed as, when the tab is switched the nodeList variables still points to the previuos *
|
fiore@5
|
148 * tab's node list. We do it only here and not in getNodeData because getNodesData *
|
fiore@5
|
149 * follows this call before releasing the monitor, therefore data integrity is granted. */
|
fiore@5
|
150 env->DeleteLocalRef(nodeList);
|
fiore@5
|
151 nodeList = env->GetObjectField(*haptics, nodeListfieldId);
|
fiore@5
|
152 if(nodeList == NULL){
|
fiore@5
|
153 stopExecution("could not get the node list field of Haptic Class");
|
fiore@5
|
154 }
|
fiore@5
|
155 jint size = env->CallIntMethod( nodeList, sizeMethodId);
|
fiore@5
|
156 checkExceptions(env,"Could not call ArrayList<Node>.size()");
|
fiore@5
|
157 return size;
|
fiore@5
|
158 }
|
fiore@5
|
159
|
fiore@5
|
160 const jint CollectionsManager::getEdgesNum(){
|
fiore@5
|
161 env->DeleteLocalRef(edgeList);
|
fiore@5
|
162 edgeList = env->GetObjectField(*haptics, edgeListfieldId);
|
fiore@5
|
163 if(edgeList == NULL){
|
fiore@5
|
164 stopExecution("could not get the edge list field of Haptic Class");
|
fiore@5
|
165 }
|
fiore@5
|
166
|
fiore@5
|
167 jint size = env->CallIntMethod( edgeList, sizeMethodId);
|
fiore@5
|
168 checkExceptions(env, "Could not call ArrayList<Edge>.size()");
|
fiore@5
|
169 return size;
|
fiore@5
|
170 }
|
fiore@5
|
171
|
fiore@5
|
172 CollectionsManager::NodeData & CollectionsManager::getNodeData(const int i){
|
fiore@5
|
173 /* get the i-th node */
|
fiore@5
|
174 jobject currentNode = env->CallObjectMethod(nodeList,getMethodId,i);
|
fiore@5
|
175 checkExceptions(env,"Could not call ArrayList<Node>.size()");
|
fiore@5
|
176 fillupNodeData(nd,currentNode);
|
fiore@5
|
177 env->DeleteLocalRef(currentNode);
|
fiore@5
|
178 return nd;
|
fiore@5
|
179 }
|
fiore@5
|
180
|
fiore@5
|
181 CollectionsManager::EdgeData & CollectionsManager::getEdgeData(const int i){
|
fiore@5
|
182 /* first we look for the i-th edge in the Haptics java class. Once we get it, *
|
fiore@5
|
183 * we need all the coordinates of the node this edge is connecting, so that we *
|
fiore@5
|
184 * can draw it. The edge mantains a list of references to such nodes. */
|
fiore@5
|
185
|
fiore@5
|
186 /* get the i-th edge */
|
fiore@5
|
187 jobject currentEdge = env->CallObjectMethod(edgeList,getMethodId,i);
|
fiore@5
|
188 checkExceptions(env, "Could not call ArrayList<Edge>.get(int) in the haptics edges");
|
fiore@5
|
189 if(currentEdge == NULL)
|
fiore@5
|
190 stopExecution("Could not find get current Edge");
|
fiore@5
|
191 jint size = env->GetIntField(currentEdge, edgeSizefieldId);
|
fiore@5
|
192 ed.setSize(size);
|
fiore@5
|
193 fillupEdgeData(ed,currentEdge);
|
fiore@5
|
194 env->DeleteLocalRef(currentEdge);
|
fiore@5
|
195 return ed;
|
fiore@5
|
196 }
|
fiore@5
|
197
|
fiore@5
|
198 void CollectionsManager::fillupNodeData(NodeData & nd, jobject & currentNode){
|
fiore@5
|
199 //reads the fields of the current node
|
fiore@5
|
200 nd.x = env->GetDoubleField(currentNode,xFieldId);
|
fiore@5
|
201 nd.y = env->GetDoubleField(currentNode,yFieldId);
|
fiore@5
|
202 // takes coordinates from the screen. Needs to convert the y axis as in openGL (0,0) = bottom left corner
|
fiore@5
|
203 Vec3d & glCoordinatePosition = screenToHapticSpace(Vec3d(nd.x, nd.y, 0),screenWidth,screenHeight);
|
fiore@5
|
204 nd.x = glCoordinatePosition[0];
|
fiore@5
|
205 nd.y = glCoordinatePosition[1];
|
fiore@5
|
206 nd.hapticId = env->GetIntField(currentNode, nodeHapticIdFieldId);
|
fiore@5
|
207 nd.diagramId = env->GetIntField(currentNode, nodeDiagramIdFieldId);
|
fiore@5
|
208 }
|
fiore@5
|
209
|
fiore@5
|
210 void CollectionsManager::fillupEdgeData(EdgeData & ed, jobject & currentEdge){
|
fiore@5
|
211 /* get the array of x coordinates */
|
fiore@5
|
212 jobject xsAsObj = env->GetObjectField(currentEdge,edgeXsFieldId);
|
fiore@5
|
213 if(xsAsObj == NULL)
|
fiore@5
|
214 stopExecution("Cannot get the xs field");
|
fiore@5
|
215 jdoubleArray *jxs = reinterpret_cast<jdoubleArray*>(&xsAsObj);
|
fiore@5
|
216 double * xs = env->GetDoubleArrayElements(*jxs, NULL);
|
fiore@5
|
217 if(xs == NULL)
|
fiore@5
|
218 stopExecution("Cannot get the xs field array of double");
|
fiore@5
|
219
|
fiore@5
|
220 /* get the array of y coordinates */
|
fiore@5
|
221 jobject ysAsObj = env->GetObjectField(currentEdge,edgeYsFieldId);
|
fiore@5
|
222 if(ysAsObj == NULL)
|
fiore@5
|
223 stopExecution("Cannot get the xs field");
|
fiore@5
|
224
|
fiore@5
|
225 jdoubleArray *jys = reinterpret_cast<jdoubleArray*>(&ysAsObj);
|
fiore@5
|
226 double * ys = env->GetDoubleArrayElements(*jys, NULL);
|
fiore@5
|
227 if(ys == NULL)
|
fiore@5
|
228 stopExecution("Cannot get the ys field array of double");
|
fiore@5
|
229 // copy the data into the edgeData object
|
fiore@5
|
230 for(unsigned int i=0; i<ed.getSize(); i++){
|
fiore@5
|
231 ed.x[i] = xs[i];
|
fiore@5
|
232 ed.y[i] = ys[i];
|
fiore@5
|
233 // takes coordinates from the screen (needs to convert the y axis as in openGL 0 = bottom left corner
|
fiore@5
|
234 Vec3d & glCoordinatePosition = screenToHapticSpace(Vec3d(ed.x[i], ed.y[i], 0),screenWidth,screenHeight);
|
fiore@5
|
235 ed.x[i] = glCoordinatePosition[0];
|
fiore@5
|
236 ed.y[i] = glCoordinatePosition[1];
|
fiore@5
|
237 }
|
fiore@5
|
238 env->ReleaseDoubleArrayElements(*jxs, xs, 0);
|
fiore@5
|
239 env->ReleaseDoubleArrayElements(*jys, ys, 0);
|
fiore@5
|
240 env->DeleteLocalRef(xsAsObj);
|
fiore@5
|
241 env->DeleteLocalRef(ysAsObj);
|
fiore@5
|
242 jobject adjMatrixAsObj = env->GetObjectField(currentEdge, edgeAdjMatrixFieldId);
|
fiore@5
|
243 if(adjMatrixAsObj == NULL)
|
fiore@5
|
244 stopExecution("Cannot get the adjMatrix field");
|
fiore@5
|
245 jobjectArray *jadjMatrix = reinterpret_cast<jobjectArray*>(&adjMatrixAsObj);
|
fiore@5
|
246
|
fiore@5
|
247 for(unsigned int i=0; i<ed.getSize(); i++){
|
fiore@5
|
248 jobject adjMatrixBitSet = env->GetObjectArrayElement(*jadjMatrix,i);
|
fiore@5
|
249 if(adjMatrixBitSet == NULL)
|
fiore@5
|
250 stopExecution("Cannot get the adjMatrix field array element");
|
fiore@5
|
251 for(unsigned int j=0;j<ed.getSize(); j++){
|
fiore@5
|
252 jboolean b = env->CallBooleanMethod(adjMatrixBitSet,getBitMethodId,j);
|
fiore@5
|
253 checkExceptions(env,"Could not call BitSet.get()");
|
fiore@5
|
254 if(b == JNI_TRUE)
|
fiore@5
|
255 ed.adjMatrix[i][j] = true;
|
fiore@5
|
256 else
|
fiore@5
|
257 ed.adjMatrix[i][j] = false;
|
fiore@5
|
258 }
|
fiore@5
|
259 env->DeleteLocalRef(adjMatrixBitSet);
|
fiore@5
|
260 }
|
fiore@5
|
261 env->DeleteLocalRef(adjMatrixAsObj);
|
fiore@5
|
262
|
fiore@5
|
263 // set the haptic id used by the haptic device
|
fiore@5
|
264 ed.hapticId = env->GetIntField(currentEdge, edgeHapticIdFieldId);
|
fiore@5
|
265 // set the diagram id used in the java thread
|
fiore@5
|
266 ed.diagramId = env->GetIntField(currentEdge, edgeDiagramIdFieldId);
|
fiore@5
|
267 // set the stipple pattern
|
fiore@5
|
268 ed.stipplePattern = env->GetIntField(currentEdge, stipplePatternfieldId);
|
fiore@5
|
269 // set the attract point
|
fiore@5
|
270 ed.attractPoint[0] = env->GetDoubleField(currentEdge, attractPointXFieldId);
|
fiore@5
|
271 ed.attractPoint[1] = env->GetDoubleField(currentEdge, attractPointYFieldId);
|
fiore@5
|
272 Vec3d & glCoordinatePosition = screenToHapticSpace(Vec3d(ed.attractPoint[0], ed.attractPoint[1], 0),screenWidth,screenHeight);
|
fiore@5
|
273 ed.attractPoint[0] = glCoordinatePosition[0];
|
fiore@5
|
274 ed.attractPoint[1] = glCoordinatePosition[1];
|
fiore@5
|
275 //set the index from which the nodes start in the adjMatrix
|
fiore@5
|
276 ed.nodeStart = env->GetIntField(currentEdge, edgeNodeStartFieldId);
|
fiore@5
|
277 }
|