Multi-touch input is now redirected to AIS_ViewController.
GLSurfaceView.RENDERMODE_WHEN_DIRTY is now used by 3D Viewer.
AIS_ViewCube is now displayed instead of trihedron.
};
//! Empty constructor.
- OcctJniRenderer()
+ OcctJniRenderer (GLSurfaceView theView,
+ float theScreenDensity)
{
+ myView = theView; // this makes cyclic dependency, but it is OK for JVM
if (OcctJniActivity.areNativeLoaded)
{
- myCppViewer = cppCreate();
+ myCppViewer = cppCreate (theScreenDensity);
}
}
{
if (myCppViewer != 0)
{
- cppRedraw (myCppViewer);
+ if (cppRedraw (myCppViewer))
+ {
+ myView.requestRender(); // this method is allowed from any thread
+ }
}
}
}
}
- //! Initialize rotation (remember first point position)
- public void onStartRotation (int theStartX, int theStartY)
+ //! Add touch point.
+ public void onAddTouchPoint (int theId, float theX, float theY)
{
if (myCppViewer != 0)
{
- cppStartRotation (myCppViewer, theStartX, theStartY);
+ cppAddTouchPoint (myCppViewer, theId, theX, theY);
}
}
- //! Perform rotation (relative to first point)
- public void onRotation (int theX, int theY)
+ //! Update touch point.
+ public void onUpdateTouchPoint (int theId, float theX, float theY)
{
if (myCppViewer != 0)
{
- cppOnRotation (myCppViewer, theX, theY);
+ cppUpdateTouchPoint (myCppViewer, theId, theX, theY);
}
}
- //! Perform panning
- public void onPanning (int theDX, int theDY)
+ //! Remove touch point.
+ public void onRemoveTouchPoint (int theId)
{
if (myCppViewer != 0)
{
- cppOnPanning (myCppViewer, theDX, theDY);
+ cppRemoveTouchPoint (myCppViewer, theId);
}
}
- //! Perform selection
- public void onClick (int theX, int theY)
+ //! Select in 3D Viewer.
+ public void onSelectInViewer (float theX, float theY)
{
if (myCppViewer != 0)
{
- cppOnClick (myCppViewer, theX, theY);
- }
- }
-
- //! Stop previously active action (e.g. discard first rotation point)
- public void onStopAction()
- {
- if (myCppViewer != 0)
- {
- cppStopAction (myCppViewer);
+ cppSelectInViewer (myCppViewer, theX, theY);
}
}
}
//! Create instance of C++ class
- private native long cppCreate();
+ private native long cppCreate (float theDispDensity);
//! Destroy instance of C++ class
private native void cppDestroy (long theCppPtr);
//! Open CAD file
private native void cppOpen (long theCppPtr, String thePath);
- //! Handle detection in the viewer
- private native void cppMoveTo (long theCppPtr, int theX, int theY);
+ //! Add touch point
+ private native void cppAddTouchPoint (long theCppPtr, int theId, float theX, float theY);
+
+ //! Update touch point
+ private native void cppUpdateTouchPoint (long theCppPtr, int theId, float theX, float theY);
+
+ //! Remove touch point
+ private native void cppRemoveTouchPoint (long theCppPtr, int theId);
+
+ //! Select in 3D Viewer.
+ private native void cppSelectInViewer (long theCppPtr, float theX, float theY);
//! Redraw OCCT viewer
- private native void cppRedraw (long theCppPtr);
+ //! Returns TRUE if more frames are requested.
+ private native boolean cppRedraw (long theCppPtr);
//! Fit All
private native void cppFitAll (long theCppPtr);
//! Move camera
private native void cppSetZnegProj (long theCppPtr);
- //! Initialize rotation
- private native void cppStartRotation (long theCppPtr, int theStartX, int theStartY);
-
- //! Perform rotation
- private native void cppOnRotation (long theCppPtr, int theX, int theY);
-
- //! Perform panning
- private native void cppOnPanning (long theCppPtr, int theDX, int theDY);
-
- //! Perform selection
- private native void cppOnClick (long theCppPtr, int theX, int theY);
-
- //! Stop action (rotation / panning / scaling)
- private native void cppStopAction (long theCppPtr);
-
+ private GLSurfaceView myView = null; //!< back reference to the View
private long myCppViewer = 0; //!< pointer to c++ class instance
}
{
super (theContext, theAttrs);
+ android.util.DisplayMetrics aDispInfo = theContext.getResources().getDisplayMetrics();
+ myScreenDensity = aDispInfo.density;
+
setPreserveEGLContextOnPause (true);
setEGLContextFactory (new ContextFactory());
setEGLConfigChooser (new ConfigChooser());
RelativeLayout.LayoutParams aLParams = new RelativeLayout.LayoutParams (LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
aLParams.addRule (RelativeLayout.ALIGN_TOP);
- myRenderer = new OcctJniRenderer();
+ myRenderer = new OcctJniRenderer (this, myScreenDensity);
setRenderer (myRenderer);
+ setRenderMode (GLSurfaceView.RENDERMODE_WHEN_DIRTY); // render on request to spare battery
}
//! Open file.
{
final String aPath = thePath;
queueEvent (new Runnable() { public void run() { myRenderer.open (aPath); }});
+ requestRender();
}
//! Create OpenGL ES 2.0+ context
//! Callback to handle touch events
@Override public boolean onTouchEvent (MotionEvent theEvent)
{
- int aPointerIndex = theEvent.getActionIndex();
- int aPointerId = theEvent.getPointerId (aPointerIndex);
- int aMaskedAction = theEvent.getActionMasked();
+ final int aMaskedAction = theEvent.getActionMasked();
switch (aMaskedAction)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
{
- PointF aPntLast = null;
- if (myActivePointers.size() >= 1)
+ final int aPointerIndex = theEvent.getActionIndex();
+ final int aPointerId = theEvent.getPointerId (aPointerIndex);
+ final PointF aPnt = new PointF (theEvent.getX (aPointerIndex), theEvent.getY (aPointerIndex));
+
+ if (theEvent.getPointerCount() == 1)
{
- aPntLast = myActivePointers.get (myActivePointers.keyAt (0));
+ mySelectPoint = aPnt;
}
-
- final PointF aPnt = new PointF();
- aPnt.x = theEvent.getX (aPointerIndex);
- aPnt.y = theEvent.getY (aPointerIndex);
- myActivePointers.put (aPointerId, aPnt);
-
- switch (myActivePointers.size())
+ else
{
- case 1:
- {
- final int aStartX = (int )aPnt.x;
- final int aStartY = (int )aPnt.y;
- queueEvent (new Runnable() { public void run() { myRenderer.onStartRotation (aStartX, aStartY); }});
- break;
- }
- case 2:
- {
- myPanFrom.x = (aPntLast.x + aPnt.x) * 0.5f;
- myPanFrom.y = (aPntLast.y + aPnt.y) * 0.5f;
- break;
- }
+ mySelectPoint = null;
}
+ queueEvent (new Runnable() { public void run() { myRenderer.onAddTouchPoint (aPointerId, aPnt.x, aPnt.y); }});
break;
}
case MotionEvent.ACTION_MOVE:
{
for (int aNbPointers = theEvent.getPointerCount(), aPntIter = 0; aPntIter < aNbPointers; ++aPntIter)
{
- PointF aPnt = myActivePointers.get (theEvent.getPointerId (aPntIter));
- if (aPnt != null)
- {
- aPnt.x = theEvent.getX (aPntIter);
- aPnt.y = theEvent.getY (aPntIter);
- }
+ final int aPointerId = theEvent.getPointerId (aPntIter);
+ final PointF aPnt = new PointF (theEvent.getX (aPntIter), theEvent.getY (aPntIter));
+ queueEvent (new Runnable() { public void run() { myRenderer.onUpdateTouchPoint (aPointerId, aPnt.x, aPnt.y); }});
}
-
- switch (myActivePointers.size())
+ if (mySelectPoint != null)
{
- case 1:
- {
- PointF aPnt = myActivePointers.get (theEvent.getPointerId (0));
- final int anX = (int )aPnt.x;
- final int anY = (int )aPnt.y;
- queueEvent (new Runnable() { public void run() { myRenderer.onRotation (anX, anY); }});
- break;
- }
- case 2:
+ final float aTouchThreshold = 5.0f * myScreenDensity;
+ final int aPointerIndex = theEvent.getActionIndex();
+ final PointF aDelta = new PointF (theEvent.getX (aPointerIndex) - mySelectPoint.x, theEvent.getY (aPointerIndex) - mySelectPoint.y);
+ if (Math.abs (aDelta.x) > aTouchThreshold || Math.abs (aDelta.y) > aTouchThreshold)
{
- PointF aPnt1 = myActivePointers.get (myActivePointers.keyAt (0));
- PointF aPnt2 = myActivePointers.get (myActivePointers.keyAt (1));
- PointF aPntAver = new PointF ((aPnt1.x + aPnt2.x) * 0.5f,
- (aPnt1.y + aPnt2.y) * 0.5f);
- final int aDX = (int )(aPntAver.x - myPanFrom.x);
- final int aDY = (int )(myPanFrom.y -aPntAver.y);
- myPanFrom.x = aPntAver.x;
- myPanFrom.y = aPntAver.y;
- queueEvent (new Runnable() { public void run() { myRenderer.onPanning (aDX, aDY); }});
+ mySelectPoint = null;
}
}
break;
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_CANCEL:
{
- myActivePointers.remove (aPointerId);
- if (myActivePointers.size() == 0)
+ if (mySelectPoint != null)
{
- final int aPressX = (int )theEvent.getX (aPointerIndex);
- final int aPressY = (int )theEvent.getY (aPointerIndex);
- double aPressTimeMs = theEvent.getEventTime() - theEvent.getDownTime();
- if (aPressTimeMs < 100.0)
- {
- queueEvent (new Runnable() { public void run() { myRenderer.onClick (aPressX, aPressY); }});
- break;
- }
+ final float aSelX = mySelectPoint.x;
+ final float aSelY = mySelectPoint.y;
+ queueEvent (new Runnable() { public void run() { myRenderer.onSelectInViewer (aSelX, aSelY); }});
+ mySelectPoint = null;
}
- else if (myActivePointers.size() == 1)
- {
- PointF aPnt = myActivePointers.get (myActivePointers.keyAt (0));
- final int aStartX = (int )aPnt.x;
- final int aStartY = (int )aPnt.y;
- queueEvent (new Runnable() { public void run() { myRenderer.onStartRotation (aStartX, aStartY); }});
- }
- //queueEvent (new Runnable() { public void run() { myRenderer.onStopAction(); }});
- break;
+
+ final int aPointerIndex = theEvent.getActionIndex();
+ final int aPointerId = theEvent.getPointerId (aPointerIndex);
+ final PointF aPnt = new PointF (theEvent.getX (aPointerIndex), theEvent.getY (aPointerIndex));
+ queueEvent (new Runnable() { public void run() { myRenderer.onRemoveTouchPoint (aPointerId); }});
}
}
- ///invalidate();
+ requestRender();
return true;
}
public void fitAll()
{
queueEvent (new Runnable() { public void run() { myRenderer.fitAll(); }});
+ requestRender();
}
//! Move camera
public void setProj (final OcctJniRenderer.TypeOfOrientation theProj)
{
queueEvent (new Runnable() { public void run() { myRenderer.setProj (theProj); }});
+ requestRender();
}
//! OCCT viewer
- private OcctJniRenderer myRenderer = null;
-
- //! Touch events cache
- private SparseArray<PointF> myActivePointers = new SparseArray<PointF>();
-
- //! Starting point for panning event
- private PointF myPanFrom = new PointF (0.0f, 0.0f);
+ private OcctJniRenderer myRenderer = null;
+ private int mySelectId = -1;
+ private PointF mySelectPoint = null;
+ private float myScreenDensity = 1.0f;
}
#include "OcctJni_Viewer.hxx"
#include "OcctJni_MsgPrinter.hxx"
+#include <AIS_ViewCube.hxx>
#include <AIS_Shape.hxx>
#include <Aspect_NeutralWindow.hxx>
#include <Image_AlienPixMap.hxx>
#include <OpenGl_GraphicDriver.hxx>
#include <OSD_Environment.hxx>
#include <OSD_Timer.hxx>
+#include <Prs3d_DatumAspect.hxx>
#include <Standard_Version.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
// function : OcctJni_Viewer
// purpose :
// =======================================================================
-OcctJni_Viewer::OcctJni_Viewer()
+OcctJni_Viewer::OcctJni_Viewer (float theDispDensity)
+: myDevicePixelRatio (theDispDensity),
+ myIsJniMoreFrames (false)
{
+ SetTouchToleranceScale (theDispDensity);
#ifndef NDEBUG
// Register printer for logging messages into global Android log.
// Should never be used in production (or specify higher gravity for logging only failures).
setResourceEnv ("CSF_SHMessage", aResRoot + "/XSMessage", "SHAPE.us", Standard_False);
}
+// ================================================================
+// Function : dumpGlInfo
+// Purpose :
+// ================================================================
+void OcctJni_Viewer::dumpGlInfo (bool theIsBasic)
+{
+ TColStd_IndexedDataMapOfStringString aGlCapsDict;
+ myView->DiagnosticInformation (aGlCapsDict, Graphic3d_DiagnosticInfo_Basic); //theIsBasic ? Graphic3d_DiagnosticInfo_Basic : Graphic3d_DiagnosticInfo_Complete);
+ if (theIsBasic)
+ {
+ TCollection_AsciiString aViewport;
+ aGlCapsDict.FindFromKey ("Viewport", aViewport);
+ aGlCapsDict.Clear();
+ aGlCapsDict.Add ("Viewport", aViewport);
+ }
+ aGlCapsDict.Add ("Display scale", TCollection_AsciiString(myDevicePixelRatio));
+
+ // beautify output
+ {
+ TCollection_AsciiString* aGlVer = aGlCapsDict.ChangeSeek ("GLversion");
+ TCollection_AsciiString* aGlslVer = aGlCapsDict.ChangeSeek ("GLSLversion");
+ if (aGlVer != NULL
+ && aGlslVer != NULL)
+ {
+ *aGlVer = *aGlVer + " [GLSL: " + *aGlslVer + "]";
+ aGlslVer->Clear();
+ }
+ }
+
+ TCollection_AsciiString anInfo;
+ for (TColStd_IndexedDataMapOfStringString::Iterator aValueIter (aGlCapsDict); aValueIter.More(); aValueIter.Next())
+ {
+ if (!aValueIter.Value().IsEmpty())
+ {
+ if (!anInfo.IsEmpty())
+ {
+ anInfo += "\n";
+ }
+ anInfo += aValueIter.Key() + ": " + aValueIter.Value();
+ }
+ }
+
+ Message::Send (anInfo, Message_Warning);
+}
+
// =======================================================================
// function : init
// purpose :
return false;
}
- TCollection_AsciiString anEglInfo = TCollection_AsciiString()
- + "\n EGLVersion: " + eglQueryString (anEglDisplay, EGL_VERSION)
- + "\n EGLVendor: " + eglQueryString (anEglDisplay, EGL_VENDOR)
- + "\n EGLClient APIs: " + eglQueryString (anEglDisplay, EGL_CLIENT_APIS)
- + "\n GLvendor: " + (const char* )glGetString (GL_VENDOR)
- + "\n GLdevice: " + (const char* )glGetString (GL_RENDERER)
- + "\n GLversion: " + (const char* )glGetString (GL_VERSION) + " [GLSL: " + (const char* )glGetString (GL_SHADING_LANGUAGE_VERSION) + "]";
- ::Message::DefaultMessenger()->Send (anEglInfo, Message_Info);
-
if (!myViewer.IsNull())
{
Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (myViewer->Driver());
aWindow->SetSize (aWidth, aHeight);
myView->SetWindow (aWindow, (Aspect_RenderingContext )anEglContext);
+ dumpGlInfo (true);
return true;
}
return false;
}
+ myTextStyle = new Prs3d_TextAspect();
+ myTextStyle->SetFont (Font_NOF_ASCII_MONO);
+ myTextStyle->SetHeight (12);
+ myTextStyle->Aspect()->SetColor (Quantity_NOC_GRAY95);
+ myTextStyle->Aspect()->SetColorSubTitle (Quantity_NOC_BLACK);
+ myTextStyle->Aspect()->SetDisplayType (Aspect_TODT_SHADOW);
+ myTextStyle->Aspect()->SetTextFontAspect (Font_FA_Bold);
+ myTextStyle->Aspect()->SetTextZoomable (false);
+ myTextStyle->SetHorizontalJustification (Graphic3d_HTA_LEFT);
+ myTextStyle->SetVerticalJustification (Graphic3d_VTA_BOTTOM);
+
// create viewer
myViewer = new V3d_Viewer (aDriver);
myViewer->SetDefaultBackgroundColor (Quantity_NOC_BLACK);
// create AIS context
myContext = new AIS_InteractiveContext (myViewer);
- //myContext->SetDisplayMode (AIS_WireFrame, false);
+ myContext->SetPixelTolerance (int(myDevicePixelRatio * 6.0)); // increase tolerance and adjust to hi-dpi screens
myContext->SetDisplayMode (AIS_Shaded, false);
Handle(Aspect_NeutralWindow) aWindow = new Aspect_NeutralWindow();
aWindow->SetSize (aWidth, aHeight);
myView = myViewer->CreateView();
+ myView->SetImmediateUpdate (false);
+ myView->ChangeRenderingParams().Resolution = (unsigned int )(96.0 * myDevicePixelRatio + 0.5);
+ myView->ChangeRenderingParams().ToShowStats = true;
+ myView->ChangeRenderingParams().CollectedStats = (Graphic3d_RenderingParams::PerfCounters ) (Graphic3d_RenderingParams::PerfCounters_FrameRate | Graphic3d_RenderingParams::PerfCounters_Triangles);
+ myView->ChangeRenderingParams().StatsTextAspect = myTextStyle->Aspect();
+ myView->ChangeRenderingParams().StatsTextHeight = (int )myTextStyle->Height();
myView->SetWindow (aWindow, (Aspect_RenderingContext )anEglContext);
- myView->TriedronDisplay (Aspect_TOTP_RIGHT_LOWER, Quantity_NOC_WHITE, 0.08, V3d_ZBUFFER);
+ dumpGlInfo (false);
+ //myView->TriedronDisplay (Aspect_TOTP_RIGHT_LOWER, Quantity_NOC_WHITE, 0.08 * myDevicePixelRatio, V3d_ZBUFFER);
initContent();
return true;
//myView->MustBeResized(); // can be used instead of SetWindow() when EGLsurface has not been changed
EGLContext anEglContext = eglGetCurrentContext();
- myView->SetImmediateUpdate (Standard_False);
myView->SetWindow (aWindow, (Aspect_RenderingContext )anEglContext);
+ dumpGlInfo (true);
//saveSnapshot ("/sdcard/Download/tt.png", theWidth, theHeight);
}
{
myContext->RemoveAll (Standard_False);
+ if (myViewCube.IsNull())
+ {
+ myViewCube = new AIS_ViewCube();
+ {
+ // setup view cube size
+ static const double THE_CUBE_SIZE = 60.0;
+ myViewCube->SetSize (myDevicePixelRatio * THE_CUBE_SIZE, false);
+ myViewCube->SetBoxFacetExtension (myViewCube->Size() * 0.15);
+ myViewCube->SetAxesPadding (myViewCube->Size() * 0.10);
+ myViewCube->SetFontHeight (THE_CUBE_SIZE * 0.16);
+ }
+ // presentation parameters
+ myViewCube->SetTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_TriedronPers, Aspect_TOTP_RIGHT_LOWER, Graphic3d_Vec2i (200, 200)));
+ myViewCube->Attributes()->SetDatumAspect (new Prs3d_DatumAspect());
+ myViewCube->Attributes()->DatumAspect()->SetTextAspect (myTextStyle);
+ // animation parameters
+ myViewCube->SetViewAnimation (myViewAnimation);
+ myViewCube->SetFixedAnimationLoop (false);
+ myViewCube->SetAutoStartAnimation (true);
+ }
+ myContext->Display (myViewCube, false);
+
OSD_Timer aTimer;
aTimer.Start();
if (!myShape.IsNull())
if (!myContext.IsNull())
{
myContext->RemoveAll (Standard_False);
+ if (!myViewCube.IsNull())
+ {
+ myContext->Display (myViewCube, false);
+ }
}
if (thePath.IsEmpty())
{
return true;
}
+// ================================================================
+// Function : handleViewRedraw
+// Purpose :
+// ================================================================
+void OcctJni_Viewer::handleViewRedraw (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView)
+{
+ AIS_ViewController::handleViewRedraw (theCtx, theView);
+ myIsJniMoreFrames = myToAskNextFrame;
+}
+
// =======================================================================
// function : redraw
// purpose :
// =======================================================================
-void OcctJni_Viewer::redraw()
+bool OcctJni_Viewer::redraw()
{
if (myView.IsNull())
{
- return;
+ return false;
}
- myView->Redraw();
+ // handle user input
+ myIsJniMoreFrames = false;
+ myView->InvalidateImmediate();
+ FlushViewEvents (myContext, myView, true);
+ return myIsJniMoreFrames;
}
// =======================================================================
myView->Invalidate();
}
-// =======================================================================
-// function : startRotation
-// purpose :
-// =======================================================================
-void OcctJni_Viewer::startRotation (int theStartX,
- int theStartY)
-{
- if (myView.IsNull())
- {
- return;
- }
-
- myView->StartRotation (theStartX, theStartY, 0.45);
- myView->Invalidate();
-}
-
-// =======================================================================
-// function : onRotation
-// purpose :
-// =======================================================================
-void OcctJni_Viewer::onRotation (int theX,
- int theY)
-{
- if (myView.IsNull())
- {
- return;
- }
-
- myView->Rotation (theX, theY);
- myView->Invalidate();
-}
-
-// =======================================================================
-// function : onPanning
-// purpose :
-// =======================================================================
-void OcctJni_Viewer::onPanning (int theDX,
- int theDY)
-{
- if (myView.IsNull())
- {
- return;
- }
-
- myView->Pan (theDX, theDY);
- myView->Invalidate();
-}
-
-// =======================================================================
-// function : onClick
-// purpose :
-// =======================================================================
-void OcctJni_Viewer::onClick (int theX,
- int theY)
-{
- if (myView.IsNull())
- {
- return;
- }
-
- myContext->MoveTo (theX, theY, myView, Standard_False);
- myContext->Select (Standard_False);
- myView->Invalidate();
-}
-
-// =======================================================================
-// function : stopAction
-// purpose :
-// =======================================================================
-void OcctJni_Viewer::stopAction()
-{
- if (myView.IsNull())
- {
- return;
- }
-}
-
#define jexp extern "C" JNIEXPORT
jexp jlong JNICALL Java_com_opencascade_jnisample_OcctJniRenderer_cppCreate (JNIEnv* theEnv,
- jobject theObj)
+ jobject theObj,
+ jfloat theDispDensity)
{
- return jlong(new OcctJni_Viewer());
+ return jlong(new OcctJni_Viewer (theDispDensity));
}
jexp void JNICALL Java_com_opencascade_jnisample_OcctJniRenderer_cppDestroy (JNIEnv* theEnv,
((OcctJni_Viewer* )theCppPtr)->open (aPath);
}
-jexp void JNICALL Java_com_opencascade_jnisample_OcctJniRenderer_cppRedraw (JNIEnv* theEnv,
- jobject theObj,
- jlong theCppPtr)
+jexp jboolean JNICALL Java_com_opencascade_jnisample_OcctJniRenderer_cppRedraw (JNIEnv* theEnv,
+ jobject theObj,
+ jlong theCppPtr)
{
- ((OcctJni_Viewer* )theCppPtr)->redraw();
+ return ((OcctJni_Viewer* )theCppPtr)->redraw() ? JNI_TRUE : JNI_FALSE;
}
jexp void JNICALL Java_com_opencascade_jnisample_OcctJniRenderer_cppSetAxoProj (JNIEnv* theEnv,
((OcctJni_Viewer* )theCppPtr)->fitAll();
}
-jexp void JNICALL Java_com_opencascade_jnisample_OcctJniRenderer_cppStartRotation (JNIEnv* theEnv,
+jexp void JNICALL Java_com_opencascade_jnisample_OcctJniRenderer_cppAddTouchPoint (JNIEnv* theEnv,
jobject theObj,
jlong theCppPtr,
- jint theStartX,
- jint theStartY)
+ jint theId,
+ jfloat theX,
+ jfloat theY)
{
- ((OcctJni_Viewer* )theCppPtr)->startRotation (theStartX, theStartY);
+ ((OcctJni_Viewer* )theCppPtr)->AddTouchPoint (theId, Graphic3d_Vec2d (theX, theY));
}
-jexp void JNICALL Java_com_opencascade_jnisample_OcctJniRenderer_cppOnRotation (JNIEnv* theEnv,
- jobject theObj,
- jlong theCppPtr,
- jint theX,
- jint theY)
-{
- ((OcctJni_Viewer* )theCppPtr)->onRotation (theX, theY);
-}
-
-jexp void JNICALL Java_com_opencascade_jnisample_OcctJniRenderer_cppOnPanning (JNIEnv* theEnv,
- jobject theObj,
- jlong theCppPtr,
- jint theDX,
- jint theDY)
+jexp void JNICALL Java_com_opencascade_jnisample_OcctJniRenderer_cppUpdateTouchPoint (JNIEnv* theEnv,
+ jobject theObj,
+ jlong theCppPtr,
+ jint theId,
+ jfloat theX,
+ jfloat theY)
{
- ((OcctJni_Viewer* )theCppPtr)->onPanning (theDX, theDY);
+ ((OcctJni_Viewer* )theCppPtr)->UpdateTouchPoint (theId, Graphic3d_Vec2d (theX, theY));
}
-jexp void JNICALL Java_com_opencascade_jnisample_OcctJniRenderer_cppOnClick (JNIEnv* theEnv,
- jobject theObj,
- jlong theCppPtr,
- jint theX,
- jint theY)
+jexp void JNICALL Java_com_opencascade_jnisample_OcctJniRenderer_cppRemoveTouchPoint (JNIEnv* theEnv,
+ jobject theObj,
+ jlong theCppPtr,
+ jint theId)
{
- ((OcctJni_Viewer* )theCppPtr)->onClick (theX, theY);
+ ((OcctJni_Viewer* )theCppPtr)->RemoveTouchPoint (theId);
}
-jexp void JNICALL Java_com_opencascade_jnisample_OcctJniRenderer_cppStopAction (JNIEnv* theEnv,
- jobject theObj,
- jlong theCppPtr)
+jexp void JNICALL Java_com_opencascade_jnisample_OcctJniRenderer_cppSelectInViewer (JNIEnv* theEnv,
+ jobject theObj,
+ jlong theCppPtr,
+ jfloat theX,
+ jfloat theY)
{
- ((OcctJni_Viewer* )theCppPtr)->stopAction();
+ ((OcctJni_Viewer* )theCppPtr)->SelectInViewer (Graphic3d_Vec2i ((int )theX, (int )theY));
}
jexp jlong JNICALL Java_com_opencascade_jnisample_OcctJniActivity_cppOcctMajorVersion (JNIEnv* theEnv,
// commercial license or contractual agreement.
#include <AIS_InteractiveContext.hxx>
+#include <AIS_ViewController.hxx>
#include <TopoDS_Shape.hxx>
#include <V3d_Viewer.hxx>
#include <V3d_View.hxx>
+class AIS_ViewCube;
+
//! Main C++ back-end for activity.
-class OcctJni_Viewer
+class OcctJni_Viewer : public AIS_ViewController
{
public:
//! Empty constructor
- OcctJni_Viewer();
+ OcctJni_Viewer (float theDispDensity);
//! Initialize the viewer
bool init();
int theHeight = 0);
//! Viewer update.
- void redraw();
+ //! Returns TRUE if more frames should be requested.
+ bool redraw();
//! Move camera
- void setProj (V3d_TypeOfOrientation theProj) { if (!myView.IsNull()) myView->SetProj (theProj); }
+ void setProj (V3d_TypeOfOrientation theProj)
+ {
+ if (myView.IsNull())
+ {
+ return;
+ }
+
+ myView->SetProj (theProj);
+ myView->Invalidate();
+ }
//! Fit All.
void fitAll();
- //! Start rotation (remember first point position)
- void startRotation (int theStartX,
- int theStartY);
-
- //! Perform rotation (relative to first point)
- void onRotation (int theX,
- int theY);
-
- //! Perform panning
- void onPanning (int theDX,
- int theDY);
-
- //! Perform selection
- void onClick (int theX,
- int theY);
-
- //! Stop previously started action
- void stopAction();
-
protected:
//! Reset viewer content.
void initContent();
+ //! Print information about OpenGL ES context.
+ void dumpGlInfo (bool theIsBasic);
+
+ //! Handle redraw.
+ virtual void handleViewRedraw (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView) override;
+
protected:
Handle(V3d_Viewer) myViewer;
Handle(V3d_View) myView;
Handle(AIS_InteractiveContext) myContext;
+ Handle(Prs3d_TextAspect) myTextStyle; //!< text style for OSD elements
+ Handle(AIS_ViewCube) myViewCube; //!< view cube object
TopoDS_Shape myShape;
+ float myDevicePixelRatio; //!< device pixel ratio for handling high DPI displays
+ bool myIsJniMoreFrames; //!< need more frame flag
};