/* Transform.cxx * * Copyright (c) 2003, Tuomas J. Lukka * This file is part of LibVob. * * LibVob is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * LibVob is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General * Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with LibVob; if not, write to the Free * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * */ /* * Written by Tuomas J. Lukka */ #include #include "org_nongnu_libvob_gl_GL.h" #include "vobjnidef.hxx" namespace Vob { extern Primitives::HierarchicalTransform *defaultTransformFactory(int id) ; jf( jboolean , transform) (JNIEnv *env, jclass, jint ninds, jintArray j_inds, jfloatArray j_pts, jint coordsys, jboolean inverse, jfloatArray j_points, jfloatArray j_into) { jint *inds = env->GetIntArrayElements(j_inds, 0); jfloat *pts = env->GetFloatArrayElements(j_pts, 0); Coorder coordset(defaultTransformFactory); coordset.clean(); coordset.setPoints((int)ninds, (int*)inds, (float*)pts, (int*)0, (int*)0, (float*)0, (float)0, (bool)true); int arrayLength = env->GetArrayLength(j_points); jfloat *points = env->GetFloatArrayElements(j_points, 0); jfloat *into = env->GetFloatArrayElements(j_into, 0); Transform *cs = coordset.get(coordsys); if(cs != 0) { if(inverse) cs = cs->getInverse(); if(cs != 0) for(int i=0; itransform(pt); into[i] = pt2.x; into[i+1] = pt2.y; into[i+2] = pt2.z; } } env->ReleaseFloatArrayElements(j_points, points, JNI_ABORT); env->ReleaseFloatArrayElements(j_into, into, 0); // These were changed, commit. env->ReleaseIntArrayElements(j_inds, inds, JNI_ABORT); env->ReleaseFloatArrayElements(j_pts, pts, JNI_ABORT); return (cs != 0); } jf( jboolean , transform2) (JNIEnv *env, jclass, jint ninds, jintArray j_inds, jfloatArray j_pts, jintArray j_interpinds, jintArray j_inds2, jfloatArray j_pts2, jfloat fract, jboolean show1, jint coordsys, jboolean inverse, jfloatArray j_points, jfloatArray j_into) { jint *inds = env->GetIntArrayElements(j_inds, 0); jfloat *pts = env->GetFloatArrayElements(j_pts, 0); jint *interpinds = env->GetIntArrayElements(j_interpinds, 0); jint *inds2 = env->GetIntArrayElements(j_inds2, 0); jfloat *pts2 = env->GetFloatArrayElements(j_pts2, 0); Coorder coordset(defaultTransformFactory); coordset.clean(); coordset.setPoints((int)ninds, (int*)inds, (float*)pts, (int*)interpinds, (int*)inds2, (float*)pts2, (float)fract, (bool)show1); int arrayLength = env->GetArrayLength(j_points); jfloat *points = env->GetFloatArrayElements(j_points, 0); jfloat *into = env->GetFloatArrayElements(j_into, 0); Transform *cs = coordset.get(coordsys); if(cs != 0) { if(inverse) cs = cs->getInverse(); for(int i=0; itransform(pt); into[i] = pt2.x; into[i+1] = pt2.y; into[i+2] = pt2.z; } } env->ReleaseFloatArrayElements(j_points, points, JNI_ABORT); env->ReleaseFloatArrayElements(j_into, into, 0); // These were changed, commit. env->ReleaseIntArrayElements(j_inds, inds, JNI_ABORT); env->ReleaseFloatArrayElements(j_pts, pts, JNI_ABORT); env->ReleaseIntArrayElements(j_interpinds, interpinds, JNI_ABORT); env->ReleaseIntArrayElements(j_inds2, inds2, JNI_ABORT); env->ReleaseFloatArrayElements(j_pts2, pts2, JNI_ABORT); return (cs != 0); } struct Match { int ind; float depth; bool operator<(const Match &m) const { return depth < m.depth; } }; jf( jintArray , getAllCSAt) (JNIEnv *env, jclass, jint ninds, jintArray j_inds, jfloatArray j_pts, jint parent, jfloat x, jfloat y) { jint *inds = env->GetIntArrayElements(j_inds, 0); jfloat *pts = env->GetFloatArrayElements(j_pts, 0); std::vector matches; Coorder coordset(defaultTransformFactory); coordset.clean(); coordset.setPoints((int)ninds, (int*)inds, (float*)pts, (int*)0, (int*)0, (float*)0, (float)0, (bool)true); ZPt screenpt(x, y, 0); for(Coorder::iterator iter = coordset.begin(); iter != coordset.end(); iter++) { // XXX Break encapsulation badly if(!(inds[*iter] & Coords::CSFLAG_ACTIVE)) continue; Transform *cs = coordset.get(*iter); if(!cs) continue; // Transform screen point to inside coordsys ZPt pt = cs->getInverse()->transform(screenpt); Pt sq = cs->getSqSize(); // See whether inside unit square if(pt.x < 0 || pt.x > sq.x || pt.y < 0 || pt.y > sq.y) continue; // Project to zero plane pt.z = 0; // Transform back to screen coordinates pt = cs->transform(pt); // Add match object Match m = { *iter, pt.z }; matches.push_back(m); } // Sort the matches according to depth std::sort(matches.begin(), matches.end()); // Put the matching indices into the output array. jintArray arr = env->NewIntArray(matches.size()); jint *els = env->GetIntArrayElements(arr, 0); for(unsigned i = 0; iReleaseIntArrayElements(arr, els, 0); // Commit env->ReleaseIntArrayElements(j_inds, inds, JNI_ABORT); env->ReleaseFloatArrayElements(j_pts, pts, JNI_ABORT); return arr; } }