mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-12-02 10:24:11 +01:00
Merge branch 'android_revo' into revo-mini
This commit is contained in:
commit
8d0d697b5c
@ -1,61 +1,96 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="org.openpilot.androidgcs" android:versionCode="1"
|
|
||||||
android:versionName="1.0">
|
|
||||||
<uses-sdk android:minSdkVersion="14" />
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
package="org.openpilot.androidgcs"
|
||||||
|
android:versionCode="1"
|
||||||
|
android:versionName="1.0" >
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
<uses-sdk android:minSdkVersion="14" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
|
||||||
<uses-feature android:name="android.hardware.usb.host" />
|
|
||||||
|
|
||||||
<application android:icon="@drawable/ic_logo" android:label="@string/app_name" android:theme="@android:style/Theme.Holo">
|
<uses-feature android:glEsVersion="0x00020000" /> <!-- OpenGL min requierements (2.0) -->
|
||||||
<!-- for map overlay -->
|
|
||||||
<uses-library android:name="com.google.android.maps" />
|
|
||||||
|
|
||||||
<!-- Object browser - main activity at the moment -->
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<activity android:name="HomePage" android:label="@string/app_name">
|
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
|
||||||
<intent-filter>
|
<uses-feature android:name="android.hardware.usb.host" />
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
|
||||||
</intent-filter>
|
|
||||||
|
|
||||||
<!-- <intent-filter> -->
|
<application
|
||||||
<!-- <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> -->
|
android:icon="@drawable/ic_logo"
|
||||||
<!-- </intent-filter> -->
|
android:label="@string/app_name"
|
||||||
|
android:theme="@android:style/Theme.Holo" >
|
||||||
|
|
||||||
<!-- <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" -->
|
<!-- for map overlay -->
|
||||||
<!-- android:resource="@xml/device_filter" /> -->
|
<uses-library android:name="com.google.android.maps" />
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity android:name="ObjectBrowser" android:label="@string/object_browser_name" />
|
<!-- Object browser - main activity at the moment -->
|
||||||
<activity android:name="PfdActivity" android:label="PFD" />
|
<activity
|
||||||
<activity android:name="Controller" android:label="@string/controller_name" />
|
android:name="org.openpilot.androidgcs.HomePage"
|
||||||
<activity android:name="Preferences" android:label="@string/preference_title" />
|
android:label="@string/app_name" >
|
||||||
<activity android:name="UAVLocation" android:label="@string/location_name" />
|
<intent-filter>
|
||||||
<activity android:name="SystemAlarmActivity" android:label="System Alarms" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<activity android:name="ObjectEditor" android:label="ObjectEditor"
|
|
||||||
android:theme="@android:style/Theme.Dialog" />
|
|
||||||
<activity android:name="Logger" android:label="Logger"
|
|
||||||
android:theme="@android:style/Theme.Dialog" />
|
|
||||||
<activity android:name="FragmentTester" android:label="FragmentTester" />
|
|
||||||
|
|
||||||
<receiver android:name="TelemetryWidget">
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
<intent-filter>
|
</intent-filter>
|
||||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
|
||||||
</intent-filter>
|
<!-- <intent-filter> -->
|
||||||
<intent-filter>
|
<!-- <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> -->
|
||||||
<action android:name="org.openpilot.intent.action.CONNECTED" />
|
<!-- </intent-filter> -->
|
||||||
<action android:name="org.openpilot.intent.action.DISCONNECTED" />
|
|
||||||
</intent-filter>
|
|
||||||
<meta-data android:name="android.appwidget.provider"
|
<!-- <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" -->
|
||||||
android:resource="@xml/telemetry_widget_info" />
|
<!-- android:resource="@xml/device_filter" /> -->
|
||||||
</receiver>
|
</activity>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="ObjectBrowser"
|
||||||
|
android:label="@string/object_browser_name" />
|
||||||
|
<activity
|
||||||
|
android:name="PfdActivity"
|
||||||
|
android:label="PFD" />
|
||||||
|
<activity
|
||||||
|
android:name="Controller"
|
||||||
|
android:label="@string/controller_name" />
|
||||||
|
<activity
|
||||||
|
android:name="Preferences"
|
||||||
|
android:label="@string/preference_title" />
|
||||||
|
<activity
|
||||||
|
android:name="UAVLocation"
|
||||||
|
android:label="@string/location_name" />
|
||||||
|
<activity
|
||||||
|
android:name="SystemAlarmActivity"
|
||||||
|
android:label="System Alarms" />
|
||||||
|
<activity
|
||||||
|
android:name="ObjectEditor"
|
||||||
|
android:label="ObjectEditor"
|
||||||
|
android:theme="@android:style/Theme.Dialog" />
|
||||||
|
<activity
|
||||||
|
android:name="Logger"
|
||||||
|
android:label="Logger"
|
||||||
|
android:theme="@android:style/Theme.Dialog" />
|
||||||
|
<activity android:name="FragmentTester" android:label="FragmentTester" />
|
||||||
|
<activity
|
||||||
|
android:name="OsgViewer"
|
||||||
|
android:label="3DView" />
|
||||||
|
|
||||||
|
<receiver android:name="TelemetryWidget" >
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||||
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="org.openpilot.intent.action.CONNECTED" />
|
||||||
|
<action android:name="org.openpilot.intent.action.DISCONNECTED" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="android.appwidget.provider"
|
||||||
|
android:resource="@xml/telemetry_widget_info" />
|
||||||
|
</receiver>
|
||||||
|
|
||||||
|
<service android:name="org.openpilot.androidgcs.telemetry.OPTelemetryService" >
|
||||||
|
</service>
|
||||||
|
</application>
|
||||||
|
|
||||||
<service android:name="org.openpilot.androidgcs.telemetry.OPTelemetryService"></service>
|
|
||||||
</application>
|
|
||||||
</manifest>
|
</manifest>
|
137179
androidgcs/assets/models/quad.osg
Normal file
137179
androidgcs/assets/models/quad.osg
Normal file
File diff suppressed because it is too large
Load Diff
70
androidgcs/jni/Android.mk
Normal file
70
androidgcs/jni/Android.mk
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := osgNativeLib
|
||||||
|
### Main Install dir
|
||||||
|
OSG_ANDROID_DIR := ../../osg_android_git/osg-install
|
||||||
|
LIBDIR := $(OSG_ANDROID_DIR)/obj/local/armeabi
|
||||||
|
|
||||||
|
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
||||||
|
LOCAL_ARM_NEON := true
|
||||||
|
LIBDIR := $(OSG_ANDROID_DIR)/obj/local/armeabi-v7a
|
||||||
|
endif
|
||||||
|
|
||||||
|
### Add all source file names to be included in lib separated by a whitespace
|
||||||
|
|
||||||
|
LOCAL_C_INCLUDES:= $(OSG_ANDROID_DIR)/include
|
||||||
|
LOCAL_CFLAGS := -Werror -fno-short-enums
|
||||||
|
LOCAL_CPPFLAGS := -DOSG_LIBRARY_STATIC
|
||||||
|
|
||||||
|
LOCAL_LDLIBS := -llog -lGLESv2 -ldl -lz -lgnustl_static -ljpeg -lpng
|
||||||
|
LOCAL_SRC_FILES := osgNativeLib.cpp OsgMainApp.cpp OsgAndroidNotifyHandler.cpp
|
||||||
|
LOCAL_LDFLAGS := -L $(LIBDIR) \
|
||||||
|
-losgdb_dds \
|
||||||
|
-losgdb_openflight \
|
||||||
|
-losgdb_tga \
|
||||||
|
-losgdb_rgb \
|
||||||
|
-losgdb_osgterrain \
|
||||||
|
-losgdb_osg \
|
||||||
|
-losgdb_ive \
|
||||||
|
-losgdb_3ds \
|
||||||
|
-losgdb_jpeg \
|
||||||
|
-losgdb_png \
|
||||||
|
-losgdb_deprecated_osgviewer \
|
||||||
|
-losgdb_deprecated_osgvolume \
|
||||||
|
-losgdb_deprecated_osgtext \
|
||||||
|
-losgdb_deprecated_osgterrain \
|
||||||
|
-losgdb_deprecated_osgsim \
|
||||||
|
-losgdb_deprecated_osgshadow \
|
||||||
|
-losgdb_deprecated_osgparticle \
|
||||||
|
-losgdb_deprecated_osgfx \
|
||||||
|
-losgdb_deprecated_osganimation \
|
||||||
|
-losgdb_deprecated_osg \
|
||||||
|
-losgdb_serializers_osgvolume \
|
||||||
|
-losgdb_serializers_osgtext \
|
||||||
|
-losgdb_serializers_osgterrain \
|
||||||
|
-losgdb_serializers_osgsim \
|
||||||
|
-losgdb_serializers_osgshadow \
|
||||||
|
-losgdb_serializers_osgparticle \
|
||||||
|
-losgdb_serializers_osgmanipulator \
|
||||||
|
-losgdb_serializers_osgfx \
|
||||||
|
-losgdb_serializers_osganimation \
|
||||||
|
-losgdb_serializers_osg \
|
||||||
|
-losgViewer \
|
||||||
|
-losgVolume \
|
||||||
|
-losgTerrain \
|
||||||
|
-losgText \
|
||||||
|
-losgShadow \
|
||||||
|
-losgSim \
|
||||||
|
-losgParticle \
|
||||||
|
-losgManipulator \
|
||||||
|
-losgGA \
|
||||||
|
-losgFX \
|
||||||
|
-losgDB \
|
||||||
|
-losgAnimation \
|
||||||
|
-losgUtil \
|
||||||
|
-losg \
|
||||||
|
-lOpenThreads
|
||||||
|
|
||||||
|
include $(BUILD_SHARED_LIBRARY)
|
11
androidgcs/jni/Application.mk
Normal file
11
androidgcs/jni/Application.mk
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ANDROID APPLICATION MAKEFILE
|
||||||
|
APP_BUILD_SCRIPT := $(call my-dir)/Android.mk
|
||||||
|
#APP_PROJECT_PATH := $(call my-dir)
|
||||||
|
|
||||||
|
APP_OPTIM := release
|
||||||
|
|
||||||
|
APP_PLATFORM := android-7
|
||||||
|
APP_STL := gnustl_static
|
||||||
|
APP_CPPFLAGS := -fexceptions -frtti
|
||||||
|
APP_ABI := armeabi armeabi-v7a
|
||||||
|
APP_MODULES := osgNativeLib
|
38
androidgcs/jni/OsgAndroidNotifyHandler.cpp
Normal file
38
androidgcs/jni/OsgAndroidNotifyHandler.cpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* OsgAndroidNotifyHandler.cpp
|
||||||
|
*
|
||||||
|
* Created on: 31/05/2011
|
||||||
|
* Author: Jorge Izquierdo Ciges
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "OsgAndroidNotifyHandler.hpp"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
void OsgAndroidNotifyHandler::setTag(std::string tag){
|
||||||
|
_tag = tag;
|
||||||
|
}
|
||||||
|
void OsgAndroidNotifyHandler::notify(osg::NotifySeverity severity, const char *message){
|
||||||
|
|
||||||
|
switch ( severity ) {
|
||||||
|
case osg::DEBUG_FP:
|
||||||
|
__android_log_write(ANDROID_LOG_VERBOSE,_tag.c_str(),message);
|
||||||
|
break;
|
||||||
|
case osg::DEBUG_INFO:
|
||||||
|
__android_log_write(ANDROID_LOG_DEBUG,_tag.c_str(),message);
|
||||||
|
break;
|
||||||
|
case osg::NOTICE:
|
||||||
|
case osg::INFO:
|
||||||
|
__android_log_write(ANDROID_LOG_INFO,_tag.c_str(),message);
|
||||||
|
break;
|
||||||
|
case osg::WARN:
|
||||||
|
__android_log_write(ANDROID_LOG_WARN,_tag.c_str(),message);
|
||||||
|
break;
|
||||||
|
case osg::FATAL:
|
||||||
|
case osg::ALWAYS:
|
||||||
|
__android_log_write(ANDROID_LOG_ERROR,_tag.c_str(),message);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
__android_log_write(ANDROID_LOG_DEBUG,_tag.c_str(),message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
26
androidgcs/jni/OsgAndroidNotifyHandler.hpp
Normal file
26
androidgcs/jni/OsgAndroidNotifyHandler.hpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* OsgAndroidNotifyHandler.hpp
|
||||||
|
*
|
||||||
|
* Created on: 31/05/2011
|
||||||
|
* Author: Jorge Izquierdo Ciges
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OSGANDROIDNOTIFYHANDLER_HPP_
|
||||||
|
#define OSGANDROIDNOTIFYHANDLER_HPP_
|
||||||
|
|
||||||
|
#include <android/log.h>
|
||||||
|
|
||||||
|
#include <osg/Notify>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class OSG_EXPORT OsgAndroidNotifyHandler : public osg::NotifyHandler
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string _tag;
|
||||||
|
public:
|
||||||
|
void setTag(std::string tag);
|
||||||
|
void notify(osg::NotifySeverity severity, const char *message);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* OSGANDROIDNOTIFYHANDLER_HPP_ */
|
247
androidgcs/jni/OsgMainApp.cpp
Normal file
247
androidgcs/jni/OsgMainApp.cpp
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
#include "OsgMainApp.hpp"
|
||||||
|
#include <osg/Quat>
|
||||||
|
|
||||||
|
OsgMainApp::OsgMainApp(){
|
||||||
|
|
||||||
|
_lodScale = 1.0f;
|
||||||
|
_prevFrame = 0;
|
||||||
|
|
||||||
|
_initialized = false;
|
||||||
|
_clean_scene = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
OsgMainApp::~OsgMainApp(){
|
||||||
|
|
||||||
|
}
|
||||||
|
void OsgMainApp::loadModels(){
|
||||||
|
if(_vModelsToLoad.size()==0) return;
|
||||||
|
|
||||||
|
osg::notify(osg::ALWAYS)<<"There are "<<_vModelsToLoad.size()<<" models to load"<<std::endl;
|
||||||
|
|
||||||
|
Model newModel;
|
||||||
|
for(unsigned int i=0; i<_vModelsToLoad.size(); i++){
|
||||||
|
newModel = _vModelsToLoad[i];
|
||||||
|
osg::notify(osg::ALWAYS)<<"Loading: "<<newModel.filename<<std::endl;
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(newModel.filename);
|
||||||
|
if (loadedModel == 0) {
|
||||||
|
osg::notify(osg::ALWAYS)<<"Model not loaded"<<std::endl;
|
||||||
|
} else {
|
||||||
|
osg::notify(osg::ALWAYS)<<"Model loaded"<<std::endl;
|
||||||
|
_vModels.push_back(newModel);
|
||||||
|
|
||||||
|
loadedModel->setName(newModel.name);
|
||||||
|
|
||||||
|
osg::Shader * vshader = new osg::Shader(osg::Shader::VERTEX, gVertexShader );
|
||||||
|
osg::Shader * fshader = new osg::Shader(osg::Shader::FRAGMENT, gFragmentShader );
|
||||||
|
|
||||||
|
osg::Program * prog = new osg::Program;
|
||||||
|
prog->addShader ( vshader );
|
||||||
|
prog->addShader ( fshader );
|
||||||
|
|
||||||
|
loadedModel->getOrCreateStateSet()->setAttribute ( prog );
|
||||||
|
|
||||||
|
// Woohoo leaky code. This no longer works for multiple models
|
||||||
|
uavAttitudeAndScale = new osg::MatrixTransform();
|
||||||
|
|
||||||
|
// Set the rotation to normal
|
||||||
|
float q[4] = {1.0, 0, 0, 0};
|
||||||
|
setQuat(q);
|
||||||
|
|
||||||
|
osg::MatrixTransform *rotateModelNED = new osg::MatrixTransform();
|
||||||
|
rotateModelNED->setMatrix(osg::Matrixd::rotate(M_PI, osg::Vec3d(0,0,1)));
|
||||||
|
rotateModelNED->addChild( loadedModel );
|
||||||
|
|
||||||
|
uavAttitudeAndScale->addChild( rotateModelNED );
|
||||||
|
|
||||||
|
_root->addChild(uavAttitudeAndScale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
osgViewer::Viewer::Windows windows;
|
||||||
|
_viewer->getWindows(windows);
|
||||||
|
for(osgViewer::Viewer::Windows::iterator itr = windows.begin();itr != windows.end();++itr)
|
||||||
|
{
|
||||||
|
(*itr)->getState()->setUseModelViewAndProjectionUniforms(true);
|
||||||
|
(*itr)->getState()->setUseVertexAttributeAliasing(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
_viewer->setSceneData(NULL);
|
||||||
|
_viewer->setSceneData(_root.get());
|
||||||
|
_manipulator->getNode();
|
||||||
|
_viewer->home();
|
||||||
|
|
||||||
|
_viewer->getDatabasePager()->clear();
|
||||||
|
_viewer->getDatabasePager()->registerPagedLODs(_root.get());
|
||||||
|
_viewer->getDatabasePager()->setUpThreads(3, 1);
|
||||||
|
_viewer->getDatabasePager()->setTargetMaximumNumberOfPageLOD(2);
|
||||||
|
_viewer->getDatabasePager()->setUnrefImageDataAfterApplyPolicy(true, true);
|
||||||
|
|
||||||
|
_vModelsToLoad.clear();
|
||||||
|
|
||||||
|
}
|
||||||
|
void OsgMainApp::deleteModels(){
|
||||||
|
if(_vModelsToDelete.size()==0) return;
|
||||||
|
|
||||||
|
osg::notify(osg::ALWAYS)<<"There are "<<_vModelsToDelete.size()<<" models to delete"<<std::endl;
|
||||||
|
|
||||||
|
Model modelToDelete;
|
||||||
|
for(unsigned int i=0; i<_vModelsToDelete.size(); i++){
|
||||||
|
modelToDelete = _vModelsToDelete[i];
|
||||||
|
osg::notify(osg::ALWAYS)<<"Deleting: "<<modelToDelete.name<<std::endl;
|
||||||
|
|
||||||
|
for(unsigned int j=_root->getNumChildren(); j>0; j--){
|
||||||
|
osg::ref_ptr<osg::Node> children = _root->getChild(j-1);
|
||||||
|
if(children->getName() == modelToDelete.name){
|
||||||
|
_root->removeChild(children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_vModelsToDelete.clear();
|
||||||
|
osg::notify(osg::ALWAYS)<<"finished"<<std::endl;
|
||||||
|
}
|
||||||
|
//Initialization function
|
||||||
|
void OsgMainApp::initOsgWindow(int x,int y,int width,int height){
|
||||||
|
|
||||||
|
__android_log_write(ANDROID_LOG_ERROR, "OSGANDROID",
|
||||||
|
"Initializing geometry");
|
||||||
|
|
||||||
|
//Pending
|
||||||
|
_notifyHandler = new OsgAndroidNotifyHandler();
|
||||||
|
_notifyHandler->setTag("Osg Viewer");
|
||||||
|
osg::setNotifyHandler(_notifyHandler);
|
||||||
|
osg::setNotifyLevel(osg::DEBUG_INFO);
|
||||||
|
|
||||||
|
_viewer = new osgViewer::Viewer();
|
||||||
|
_viewer->setUpViewerAsEmbeddedInWindow(x, y, width, height);
|
||||||
|
_viewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);
|
||||||
|
|
||||||
|
_root = new osg::Group();
|
||||||
|
|
||||||
|
_viewer->realize();
|
||||||
|
|
||||||
|
_viewer->addEventHandler(new osgViewer::StatsHandler);
|
||||||
|
_viewer->addEventHandler(new osgGA::StateSetManipulator(_viewer->getCamera()->getOrCreateStateSet()));
|
||||||
|
_viewer->addEventHandler(new osgViewer::ThreadingHandler);
|
||||||
|
_viewer->addEventHandler(new osgViewer::LODScaleHandler);
|
||||||
|
|
||||||
|
_manipulator = new osgGA::KeySwitchMatrixManipulator;
|
||||||
|
|
||||||
|
_manipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
|
||||||
|
_manipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
|
||||||
|
_manipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );
|
||||||
|
_manipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );
|
||||||
|
_manipulator->addMatrixManipulator( '5', "Orbit", new osgGA::OrbitManipulator() );
|
||||||
|
_manipulator->addMatrixManipulator( '6', "FirstPerson", new osgGA::FirstPersonManipulator() );
|
||||||
|
_manipulator->addMatrixManipulator( '7', "Spherical", new osgGA::SphericalManipulator() );
|
||||||
|
|
||||||
|
_viewer->setCameraManipulator( _manipulator.get() );
|
||||||
|
|
||||||
|
_viewer->getViewerStats()->collectStats("scene", true);
|
||||||
|
|
||||||
|
_initialized = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
//Draw
|
||||||
|
void OsgMainApp::draw(){
|
||||||
|
//Every load o remove has to be done before any drawing
|
||||||
|
loadModels();
|
||||||
|
deleteModels();
|
||||||
|
|
||||||
|
_viewer->frame();
|
||||||
|
}
|
||||||
|
//Events
|
||||||
|
void OsgMainApp::mouseButtonPressEvent(float x,float y,int button){
|
||||||
|
_viewer->getEventQueue()->mouseButtonPress(x, y, button);
|
||||||
|
}
|
||||||
|
void OsgMainApp::mouseButtonReleaseEvent(float x,float y,int button){
|
||||||
|
_viewer->getEventQueue()->mouseButtonRelease(x, y, button);
|
||||||
|
}
|
||||||
|
void OsgMainApp::mouseMoveEvent(float x,float y){
|
||||||
|
_viewer->getEventQueue()->mouseMotion(x, y);
|
||||||
|
}
|
||||||
|
void OsgMainApp::keyboardDown(int key){
|
||||||
|
_viewer->getEventQueue()->keyPress(key);
|
||||||
|
}
|
||||||
|
void OsgMainApp::keyboardUp(int key){
|
||||||
|
_viewer->getEventQueue()->keyRelease(key);
|
||||||
|
}
|
||||||
|
//Loading and unloading
|
||||||
|
void OsgMainApp::loadObject(std::string filePath){
|
||||||
|
Model newModel;
|
||||||
|
newModel.filename = filePath;
|
||||||
|
newModel.name = filePath;
|
||||||
|
|
||||||
|
int num = 0;
|
||||||
|
for(unsigned int i=0;i<_vModels.size();i++){
|
||||||
|
if(_vModels[i].name==newModel.name)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_vModelsToLoad.push_back(newModel);
|
||||||
|
|
||||||
|
}
|
||||||
|
void OsgMainApp::loadObject(std::string name,std::string filePath){
|
||||||
|
|
||||||
|
Model newModel;
|
||||||
|
newModel.filename = filePath;
|
||||||
|
newModel.name = name;
|
||||||
|
|
||||||
|
for(unsigned int i=0;i<_vModels.size();i++){
|
||||||
|
if(_vModels[i].name==newModel.name){
|
||||||
|
osg::notify(osg::ALWAYS)<<"Name already used"<<std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_vModelsToLoad.push_back(newModel);
|
||||||
|
}
|
||||||
|
void OsgMainApp::unLoadObject(int number){
|
||||||
|
if(_vModels.size() <= number){
|
||||||
|
osg::notify(osg::FATAL)<<"Index number error"<<std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Model modelToDelete = _vModels[number];
|
||||||
|
_vModels.erase(_vModels.begin()+number);
|
||||||
|
_vModelsToDelete.push_back(modelToDelete);
|
||||||
|
}
|
||||||
|
void OsgMainApp::clearScene(){
|
||||||
|
_vModelsToDelete = _vModels;
|
||||||
|
_vModels.clear();
|
||||||
|
}
|
||||||
|
//Other Functions
|
||||||
|
int OsgMainApp::getNumberObjects(){
|
||||||
|
return _vModels.size();
|
||||||
|
}
|
||||||
|
std::string OsgMainApp::getObjectName(int number){
|
||||||
|
return _vModels[number].name;
|
||||||
|
}
|
||||||
|
void OsgMainApp::setClearColor(osg::Vec4f color){
|
||||||
|
osg::notify(osg::ALWAYS)<<"Setting Clear Color"<<std::endl;
|
||||||
|
_viewer->getCamera()->setClearColor(color);
|
||||||
|
}
|
||||||
|
osg::Vec4f OsgMainApp::getClearColor(){
|
||||||
|
osg::notify(osg::ALWAYS)<<"Getting Clear Color"<<std::endl;
|
||||||
|
return _viewer->getCamera()->getClearColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OsgMainApp::setQuat(float *q){
|
||||||
|
osg::Quat quat(q[1], q[2], q[3], q[0]);
|
||||||
|
|
||||||
|
// Have to rotate the axes from OP NED frame to OSG frame (X east, Y north, Z down)
|
||||||
|
double angle;
|
||||||
|
osg::Vec3d axis;
|
||||||
|
quat.getRotate(angle,axis);
|
||||||
|
quat.makeRotate(angle, osg::Vec3d(axis[1],axis[0],-axis[2]));
|
||||||
|
osg::Matrixd rot = osg::Matrixd::rotate(quat);
|
||||||
|
|
||||||
|
if (uavAttitudeAndScale) {
|
||||||
|
osg::notify(osg::ALWAYS)<<"Setting attitude"<<std::endl;
|
||||||
|
uavAttitudeAndScale->setMatrix(rot);
|
||||||
|
} else {
|
||||||
|
osg::notify(osg::ALWAYS)<<"Pointer missing"<<std::endl;
|
||||||
|
}
|
||||||
|
}
|
191
androidgcs/jni/OsgMainApp.hpp
Normal file
191
androidgcs/jni/OsgMainApp.hpp
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
/*
|
||||||
|
* OsgMainApp.hpp
|
||||||
|
*
|
||||||
|
* Created on: 29/05/2011
|
||||||
|
* Author: Jorge Izquierdo Ciges
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OSGMAINAPP_HPP_
|
||||||
|
#define OSGMAINAPP_HPP_
|
||||||
|
|
||||||
|
//Android log
|
||||||
|
#include <android/log.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
//Standard libraries
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
//osg
|
||||||
|
#include <osg/GL>
|
||||||
|
#include <osg/GLExtensions>
|
||||||
|
#include <osg/Depth>
|
||||||
|
#include <osg/Program>
|
||||||
|
#include <osg/Shader>
|
||||||
|
#include <osg/MatrixTransform>
|
||||||
|
#include <osg/Node>
|
||||||
|
#include <osg/Notify>
|
||||||
|
//osgText
|
||||||
|
#include <osgText/Text>
|
||||||
|
//osgDB
|
||||||
|
#include <osgDB/DatabasePager>
|
||||||
|
#include <osgDB/Registry>
|
||||||
|
#include <osgDB/ReadFile>
|
||||||
|
#include <osgDB/WriteFile>
|
||||||
|
//osg_viewer
|
||||||
|
#include <osgViewer/Viewer>
|
||||||
|
#include <osgViewer/Renderer>
|
||||||
|
#include <osgViewer/ViewerEventHandlers>
|
||||||
|
//osgGA
|
||||||
|
#include <osgGA/GUIEventAdapter>
|
||||||
|
#include <osgGA/MultiTouchTrackballManipulator>
|
||||||
|
#include <osgGA/TrackballManipulator>
|
||||||
|
#include <osgGA/FlightManipulator>
|
||||||
|
#include <osgGA/DriveManipulator>
|
||||||
|
#include <osgGA/KeySwitchMatrixManipulator>
|
||||||
|
#include <osgGA/StateSetManipulator>
|
||||||
|
#include <osgGA/AnimationPathManipulator>
|
||||||
|
#include <osgGA/TerrainManipulator>
|
||||||
|
#include <osgGA/SphericalManipulator>
|
||||||
|
//Self headers
|
||||||
|
#include "OsgAndroidNotifyHandler.hpp"
|
||||||
|
|
||||||
|
//Static plugins Macro
|
||||||
|
USE_OSGPLUGIN(ive)
|
||||||
|
USE_OSGPLUGIN(osg)
|
||||||
|
USE_OSGPLUGIN(osg2)
|
||||||
|
USE_OSGPLUGIN(terrain)
|
||||||
|
USE_OSGPLUGIN(rgb)
|
||||||
|
USE_OSGPLUGIN(OpenFlight)
|
||||||
|
USE_OSGPLUGIN(dds)
|
||||||
|
USE_OSGPLUGIN(3ds)
|
||||||
|
USE_OSGPLUGIN(jpeg)
|
||||||
|
USE_OSGPLUGIN(png)
|
||||||
|
|
||||||
|
//Static DOTOSG
|
||||||
|
USE_DOTOSGWRAPPER_LIBRARY(osg)
|
||||||
|
USE_DOTOSGWRAPPER_LIBRARY(osgFX)
|
||||||
|
USE_DOTOSGWRAPPER_LIBRARY(osgParticle)
|
||||||
|
USE_DOTOSGWRAPPER_LIBRARY(osgTerrain)
|
||||||
|
USE_DOTOSGWRAPPER_LIBRARY(osgText)
|
||||||
|
USE_DOTOSGWRAPPER_LIBRARY(osgViewer)
|
||||||
|
USE_DOTOSGWRAPPER_LIBRARY(osgVolume)
|
||||||
|
//Static serializer
|
||||||
|
USE_SERIALIZER_WRAPPER_LIBRARY(osg)
|
||||||
|
USE_SERIALIZER_WRAPPER_LIBRARY(osgAnimation)
|
||||||
|
USE_SERIALIZER_WRAPPER_LIBRARY(osgFX)
|
||||||
|
USE_SERIALIZER_WRAPPER_LIBRARY(osgManipulator)
|
||||||
|
USE_SERIALIZER_WRAPPER_LIBRARY(osgParticle)
|
||||||
|
USE_SERIALIZER_WRAPPER_LIBRARY(osgTerrain)
|
||||||
|
USE_SERIALIZER_WRAPPER_LIBRARY(osgText)
|
||||||
|
USE_SERIALIZER_WRAPPER_LIBRARY(osgVolume)
|
||||||
|
|
||||||
|
#define LOG_TAG "osgNativeLib"
|
||||||
|
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
|
||||||
|
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
|
||||||
|
|
||||||
|
struct Model{
|
||||||
|
std::string filename;
|
||||||
|
std::string name;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char gVertexShader[] =
|
||||||
|
"varying vec4 color; \n"
|
||||||
|
"const vec3 lightPos =vec3(0.0, 0.0, 10.0); \n"
|
||||||
|
"const vec4 cessnaColor =vec4(0.8, 0.8, 0.8, 1.0); \n"
|
||||||
|
"const vec4 lightAmbient =vec4(0.1, 0.1, 0.1, 1.0); \n"
|
||||||
|
"const vec4 lightDiffuse =vec4(0.4, 0.4, 0.4, 1.0); \n"
|
||||||
|
"const vec4 lightSpecular =vec4(0.8, 0.8, 0.8, 1.0); \n"
|
||||||
|
"void DirectionalLight(in vec3 normal, \n"
|
||||||
|
" in vec3 ecPos, \n"
|
||||||
|
" inout vec4 ambient, \n"
|
||||||
|
" inout vec4 diffuse, \n"
|
||||||
|
" inout vec4 specular) \n"
|
||||||
|
"{ \n"
|
||||||
|
" float nDotVP; \n"
|
||||||
|
" vec3 L = normalize(gl_ModelViewMatrix*vec4(lightPos, 0.0)).xyz; \n"
|
||||||
|
" nDotVP = max(0.0, dot(normal, L)); \n"
|
||||||
|
" \n"
|
||||||
|
" if (nDotVP > 0.0) { \n"
|
||||||
|
" vec3 E = normalize(-ecPos); \n"
|
||||||
|
" vec3 R = normalize(reflect( L, normal )); \n"
|
||||||
|
" specular = pow(max(dot(R, E), 0.0), 16.0) * lightSpecular; \n"
|
||||||
|
" } \n"
|
||||||
|
" ambient = lightAmbient; \n"
|
||||||
|
" diffuse = lightDiffuse * nDotVP; \n"
|
||||||
|
"} \n"
|
||||||
|
"void main() { \n"
|
||||||
|
" vec4 ambiCol = vec4(0.0); \n"
|
||||||
|
" vec4 diffCol = vec4(0.0); \n"
|
||||||
|
" vec4 specCol = vec4(0.0); \n"
|
||||||
|
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; \n"
|
||||||
|
" vec3 normal = normalize(gl_NormalMatrix * gl_Normal); \n"
|
||||||
|
" vec4 ecPos = gl_ModelViewMatrix * gl_Vertex; \n"
|
||||||
|
" DirectionalLight(normal, ecPos.xyz, ambiCol, diffCol, specCol); \n"
|
||||||
|
" color = cessnaColor * (ambiCol + diffCol + specCol); \n"
|
||||||
|
"} \n";
|
||||||
|
|
||||||
|
static const char gFragmentShader[] =
|
||||||
|
"precision mediump float; \n"
|
||||||
|
"varying mediump vec4 color; \n"
|
||||||
|
"void main() { \n"
|
||||||
|
" gl_FragColor = color; \n"
|
||||||
|
"} \n";
|
||||||
|
|
||||||
|
|
||||||
|
class OsgMainApp{
|
||||||
|
private:
|
||||||
|
osg::ref_ptr<osgViewer::Viewer> _viewer;
|
||||||
|
osg::ref_ptr<osg::Group> _root;
|
||||||
|
osg::ref_ptr<osg::StateSet> _state;
|
||||||
|
osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> _manipulator;
|
||||||
|
|
||||||
|
float _lodScale;
|
||||||
|
unsigned int _prevFrame;
|
||||||
|
|
||||||
|
bool _initialized;
|
||||||
|
bool _clean_scene;
|
||||||
|
|
||||||
|
OsgAndroidNotifyHandler *_notifyHandler;
|
||||||
|
|
||||||
|
std::vector<Model> _vModels;
|
||||||
|
std::vector<Model> _vModelsToLoad;
|
||||||
|
std::vector<Model> _vModelsToDelete;
|
||||||
|
|
||||||
|
void loadModels();
|
||||||
|
void deleteModels();
|
||||||
|
|
||||||
|
public:
|
||||||
|
OsgMainApp();
|
||||||
|
~OsgMainApp();
|
||||||
|
|
||||||
|
//Initialization function
|
||||||
|
void initOsgWindow(int x,int y,int width,int height);
|
||||||
|
//Draw
|
||||||
|
void draw();
|
||||||
|
//Events
|
||||||
|
void mouseButtonPressEvent(float x,float y,int button);
|
||||||
|
void mouseButtonReleaseEvent(float x,float y,int button);
|
||||||
|
void mouseMoveEvent(float x,float y);
|
||||||
|
void keyboardDown(int key);
|
||||||
|
void keyboardUp(int key);
|
||||||
|
//Loading and unloading
|
||||||
|
void loadObject(std::string filePath);
|
||||||
|
void loadObject(std::string name,std::string filePath);
|
||||||
|
void unLoadObject(int number);
|
||||||
|
void clearScene();
|
||||||
|
//Other functions
|
||||||
|
int getNumberObjects();
|
||||||
|
std::string getObjectName(int nunmber);
|
||||||
|
|
||||||
|
void setClearColor(osg::Vec4f color);
|
||||||
|
osg::Vec4f getClearColor();
|
||||||
|
|
||||||
|
//Manipulating the view
|
||||||
|
void setQuat(float *q);
|
||||||
|
osg::MatrixTransform *uavAttitudeAndScale;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* OSGMAINAPP_HPP_ */
|
119
androidgcs/jni/osgNativeLib.cpp
Normal file
119
androidgcs/jni/osgNativeLib.cpp
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include <jni.h>
|
||||||
|
#include <android/log.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "OsgMainApp.hpp"
|
||||||
|
|
||||||
|
OsgMainApp mainApp;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_init(JNIEnv * env, jobject obj, jint width, jint height);
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_step(JNIEnv * env, jobject obj);
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_clearContents(JNIEnv * env, jobject obj);
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_mouseButtonPressEvent(JNIEnv * env, jobject obj, jfloat x, jfloat y, jint button);
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_mouseButtonReleaseEvent(JNIEnv * env, jobject obj, jfloat x, jfloat y, jint button);
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_mouseMoveEvent(JNIEnv * env, jobject obj, jfloat x, jfloat y);
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_keyboardDown(JNIEnv * env, jobject obj, jint key);
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_keyboardUp(JNIEnv * env, jobject obj, jint key);
|
||||||
|
JNIEXPORT jintArray JNICALL Java_org_openpilot_osg_osgNativeLib_getClearColor(JNIEnv * env, jobject obj);
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_setClearColor(JNIEnv * env, jobject obj, jint red, jint green, jint blue);
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_loadObject(JNIEnv * env, jobject obj, jstring address);
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_unLoadObject(JNIEnv * env, jobject obj, jint number);
|
||||||
|
JNIEXPORT jobjectArray JNICALL Java_org_openpilot_osg_osgNativeLib_getObjectNames(JNIEnv * env, jobject obj);
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_setQuat(JNIEnv * env, jobject obj, jfloat q1, jfloat q2, jfloat q3, jfloat q4);
|
||||||
|
};
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_init(JNIEnv * env, jobject obj, jint width, jint height){
|
||||||
|
mainApp.initOsgWindow(0,0,width,height);
|
||||||
|
}
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_step(JNIEnv * env, jobject obj){
|
||||||
|
mainApp.draw();
|
||||||
|
}
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_clearContents(JNIEnv * env, jobject obj){
|
||||||
|
mainApp.clearScene();
|
||||||
|
}
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_mouseButtonPressEvent(JNIEnv * env, jobject obj, jfloat x, jfloat y, jint button){
|
||||||
|
mainApp.mouseButtonPressEvent(x,y,button);
|
||||||
|
}
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_mouseButtonReleaseEvent(JNIEnv * env, jobject obj, jfloat x, jfloat y, jint button){
|
||||||
|
mainApp.mouseButtonReleaseEvent(x,y,button);
|
||||||
|
}
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_mouseMoveEvent(JNIEnv * env, jobject obj, jfloat x, jfloat y){
|
||||||
|
mainApp.mouseMoveEvent(x,y);
|
||||||
|
}
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_keyboardDown(JNIEnv * env, jobject obj, jint key){
|
||||||
|
mainApp.keyboardDown(key);
|
||||||
|
}
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_keyboardUp(JNIEnv * env, jobject obj, jint key){
|
||||||
|
mainApp.keyboardUp(key);
|
||||||
|
}
|
||||||
|
JNIEXPORT jintArray JNICALL Java_org_openpilot_osg_osgNativeLib_getClearColor(JNIEnv * env, jobject obj){
|
||||||
|
|
||||||
|
jintArray color;
|
||||||
|
color = env->NewIntArray(3);
|
||||||
|
if (color == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
osg::Vec4 vTemp1 = mainApp.getClearColor();
|
||||||
|
|
||||||
|
jint vTemp2[3];
|
||||||
|
|
||||||
|
vTemp2[0] = (int) (vTemp1.r() * 255);
|
||||||
|
vTemp2[1] = (int) (vTemp1.g() * 255);
|
||||||
|
vTemp2[2] = (int) (vTemp1.b() * 255);
|
||||||
|
|
||||||
|
std::cout<<vTemp2[0]<<" "<<vTemp2[1]<<" "<<vTemp2[2]<<" "<<std::endl;
|
||||||
|
|
||||||
|
env->SetIntArrayRegion(color, 0, 3, vTemp2);
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_setClearColor(JNIEnv * env, jobject obj, jint red, jint green, jint blue){
|
||||||
|
osg::Vec4 tVec((float) red / 255.0f, (float) green / 255.0f, (float) blue / 255.0f, 0.0f);
|
||||||
|
mainApp.setClearColor(tVec);
|
||||||
|
}
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_loadObject(JNIEnv * env, jobject obj, jstring address){
|
||||||
|
//Import Strings from JNI
|
||||||
|
const char *nativeAddress = env->GetStringUTFChars(address, JNI_FALSE);
|
||||||
|
|
||||||
|
mainApp.loadObject(std::string(nativeAddress));
|
||||||
|
|
||||||
|
//Release Strings to JNI
|
||||||
|
env->ReleaseStringUTFChars(address, nativeAddress);
|
||||||
|
}
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_loadObject(JNIEnv * env, jobject obj, jstring address, jstring name){
|
||||||
|
//Import Strings from JNI
|
||||||
|
const char *nativeAddress = env->GetStringUTFChars(address, JNI_FALSE);
|
||||||
|
const char *nativeName = env->GetStringUTFChars(name, JNI_FALSE);
|
||||||
|
|
||||||
|
mainApp.loadObject(std::string(nativeName),std::string(nativeAddress));
|
||||||
|
|
||||||
|
//Release Strings to JNI
|
||||||
|
env->ReleaseStringUTFChars(address, nativeAddress);
|
||||||
|
env->ReleaseStringUTFChars(address, nativeName);
|
||||||
|
}
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_unLoadObject(JNIEnv * env, jobject obj, jint number){
|
||||||
|
|
||||||
|
mainApp.unLoadObject(number);
|
||||||
|
|
||||||
|
}
|
||||||
|
JNIEXPORT jobjectArray JNICALL Java_org_openpilot_osg_osgNativeLib_getObjectNames(JNIEnv * env, jobject obj){
|
||||||
|
|
||||||
|
jobjectArray fileNames;
|
||||||
|
unsigned int numModels = mainApp.getNumberObjects();
|
||||||
|
fileNames = (jobjectArray)env->NewObjectArray(numModels,env->FindClass("java/lang/String"),env->NewStringUTF(""));
|
||||||
|
|
||||||
|
for(unsigned int i=0;i < numModels;i++){
|
||||||
|
std::string name = mainApp.getObjectName(i);
|
||||||
|
env->SetObjectArrayElement(fileNames,i,env->NewStringUTF(name.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_org_openpilot_osg_osgNativeLib_setQuat(JNIEnv * env, jobject obj, jfloat q1, jfloat q2, jfloat q3, jfloat q4){
|
||||||
|
float q[4] = {q1, q2, q3, q4};
|
||||||
|
mainApp.setQuat(q);
|
||||||
|
}
|
@ -81,13 +81,24 @@
|
|||||||
android:id="@+id/launch_tester"
|
android:id="@+id/launch_tester"
|
||||||
android:layout_width="132dp"
|
android:layout_width="132dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_row="6"
|
||||||
android:layout_column="0"
|
android:layout_column="0"
|
||||||
|
android:layout_rowSpan="2"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:drawableTop="@drawable/ic_alarms"
|
||||||
|
android:text="@string/tester" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/launch_osgViewer"
|
||||||
|
android:layout_width="132dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_column="1"
|
||||||
android:layout_gravity="right"
|
android:layout_gravity="right"
|
||||||
android:layout_row="6"
|
android:layout_row="6"
|
||||||
android:layout_rowSpan="2"
|
android:layout_rowSpan="2"
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
android:drawableTop="@drawable/ic_alarms"
|
android:drawableTop="@drawable/ic_alarms"
|
||||||
android:text="@string/tester" />
|
android:text="@string/_3dview" />
|
||||||
|
|
||||||
<Space
|
<Space
|
||||||
android:layout_width="1dp"
|
android:layout_width="1dp"
|
||||||
|
44
androidgcs/res/layout/ui_layout_gles.xml
Normal file
44
androidgcs/res/layout/ui_layout_gles.xml
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent">
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_weight="1">
|
||||||
|
<org.openpilot.osg.EGLview android:id="@+id/surfaceGLES"
|
||||||
|
android:visibility="visible"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
/>
|
||||||
|
</FrameLayout>
|
||||||
|
<RelativeLayout android:id="@+id/uiNavigation"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center">
|
||||||
|
<Button android:id="@+id/uiButtonLight"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="light"/>
|
||||||
|
<Button android:id="@+id/uiButtonCenter"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="center"/>
|
||||||
|
<Button android:id="@+id/uiButtonChangeNavigation"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="navigation"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -33,4 +33,5 @@
|
|||||||
<string name="txrate">TxRate: </string>
|
<string name="txrate">TxRate: </string>
|
||||||
<string name="rxrate">RxRate: </string>
|
<string name="rxrate">RxRate: </string>
|
||||||
<string name="tester">Tester</string>
|
<string name="tester">Tester</string>
|
||||||
|
<string name="_3dview">3DView</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -91,6 +91,14 @@ public class HomePage extends ObjectManagerActivity {
|
|||||||
startActivity(new Intent(HomePage.this, FragmentTester.class));
|
startActivity(new Intent(HomePage.this, FragmentTester.class));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Button osgViewer = (Button) findViewById(R.id.launch_osgViewer);
|
||||||
|
osgViewer.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View arg0) {
|
||||||
|
startActivity(new Intent(HomePage.this, OsgViewer.class));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ public abstract class ObjectManagerActivity extends Activity {
|
|||||||
private HashMap<Observer, UAVObject> listeners;
|
private HashMap<Observer, UAVObject> listeners;
|
||||||
/** Called when the activity is first created. */
|
/** Called when the activity is first created. */
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
373
androidgcs/src/org/openpilot/androidgcs/OsgViewer.java
Normal file
373
androidgcs/src/org/openpilot/androidgcs/OsgViewer.java
Normal file
@ -0,0 +1,373 @@
|
|||||||
|
package org.openpilot.androidgcs;
|
||||||
|
|
||||||
|
import org.openpilot.osg.ColorPickerDialog;
|
||||||
|
import org.openpilot.osg.EGLview;
|
||||||
|
import org.openpilot.osg.osgNativeLib;
|
||||||
|
import org.openpilot.uavtalk.UAVObject;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.PointF;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
public class OsgViewer extends ObjectManagerActivity implements View.OnTouchListener, View.OnKeyListener, ColorPickerDialog.OnColorChangeListener {
|
||||||
|
private static final String TAG = OsgViewer.class.getSimpleName();
|
||||||
|
private static final int LOGLEVEL = 2;
|
||||||
|
// private static boolean WARN = LOGLEVEL > 1;
|
||||||
|
private static final boolean DEBUG = LOGLEVEL > 0;
|
||||||
|
|
||||||
|
|
||||||
|
enum moveTypes { NONE , DRAG, MDRAG, ZOOM ,ACTUALIZE}
|
||||||
|
enum navType { PRINCIPAL , SECONDARY }
|
||||||
|
enum lightType { ON , OFF }
|
||||||
|
|
||||||
|
moveTypes mode=moveTypes.NONE;
|
||||||
|
navType navMode = navType.PRINCIPAL;
|
||||||
|
lightType lightMode = lightType.ON;
|
||||||
|
|
||||||
|
PointF oneFingerOrigin = new PointF(0,0);
|
||||||
|
long timeOneFinger=0;
|
||||||
|
PointF twoFingerOrigin = new PointF(0,0);
|
||||||
|
long timeTwoFinger=0;
|
||||||
|
float distanceOrigin;
|
||||||
|
|
||||||
|
int backgroundColor;
|
||||||
|
|
||||||
|
//Ui elements
|
||||||
|
EGLview mView;
|
||||||
|
Button uiCenterViewButton;
|
||||||
|
Button uiNavigationChangeButton;
|
||||||
|
ImageButton uiNavigationLeft;
|
||||||
|
ImageButton uiNavigationRight;
|
||||||
|
Button uiLightChangeButton;
|
||||||
|
|
||||||
|
//Toasts
|
||||||
|
Toast msgUiNavPrincipal;
|
||||||
|
Toast msgUiNavSecondary;
|
||||||
|
Toast msgUiLightOn;
|
||||||
|
Toast msgUiLightOff;
|
||||||
|
|
||||||
|
//Dialogs
|
||||||
|
AlertDialog removeLayerDialog;
|
||||||
|
AlertDialog loadLayerAddress;
|
||||||
|
|
||||||
|
//Main Android Activity life cycle
|
||||||
|
@Override protected void onCreate(Bundle icicle) {
|
||||||
|
super.onCreate(icicle);
|
||||||
|
setContentView(R.layout.ui_layout_gles);
|
||||||
|
//Obtain every Ui element
|
||||||
|
mView= (EGLview) findViewById(R.id.surfaceGLES);
|
||||||
|
mView.setOnTouchListener(this);
|
||||||
|
mView.setOnKeyListener(this);
|
||||||
|
|
||||||
|
uiCenterViewButton = (Button) findViewById(R.id.uiButtonCenter);
|
||||||
|
uiCenterViewButton.setOnClickListener(uiListenerCenterView);
|
||||||
|
uiNavigationChangeButton = (Button) findViewById(R.id.uiButtonChangeNavigation);
|
||||||
|
uiNavigationChangeButton.setOnClickListener(uiListenerChangeNavigation);
|
||||||
|
uiLightChangeButton = (Button) findViewById(R.id.uiButtonLight);
|
||||||
|
uiLightChangeButton.setOnClickListener(uiListenerChangeLight);
|
||||||
|
|
||||||
|
//Creating Toasts
|
||||||
|
msgUiNavPrincipal = Toast.makeText(getApplicationContext(), "toast1", Toast.LENGTH_SHORT);
|
||||||
|
msgUiNavSecondary = Toast.makeText(getApplicationContext(), "toast2", Toast.LENGTH_SHORT);
|
||||||
|
msgUiLightOn = Toast.makeText(getApplicationContext(), "toast3", Toast.LENGTH_SHORT);
|
||||||
|
msgUiLightOff = Toast.makeText(getApplicationContext(), "toast4", Toast.LENGTH_SHORT);
|
||||||
|
|
||||||
|
String address = Environment.getExternalStorageDirectory().getPath() + "/Models/J14-QT_X.3DS"; //quad.osg";
|
||||||
|
Log.d(TAG, "Address: " + address);
|
||||||
|
osgNativeLib.loadObject(address);
|
||||||
|
}
|
||||||
|
@Override protected void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
mView.onPause();
|
||||||
|
}
|
||||||
|
@Override protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
mView.onResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Main view event processing
|
||||||
|
@Override
|
||||||
|
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean onKeyDown(int keyCode, KeyEvent event){
|
||||||
|
//DO NOTHING this will render useless every menu key except Home
|
||||||
|
int keyChar= event.getUnicodeChar();
|
||||||
|
osgNativeLib.keyboardDown(keyChar);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean onKeyUp(int keyCode, KeyEvent event){
|
||||||
|
switch (keyCode){
|
||||||
|
case KeyEvent.KEYCODE_BACK:
|
||||||
|
super.onDestroy();
|
||||||
|
this.finish();
|
||||||
|
break;
|
||||||
|
case KeyEvent.KEYCODE_SEARCH:
|
||||||
|
break;
|
||||||
|
case KeyEvent.KEYCODE_MENU:
|
||||||
|
this.openOptionsMenu();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
int keyChar= event.getUnicodeChar();
|
||||||
|
osgNativeLib.keyboardUp(keyChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
|
|
||||||
|
//dumpEvent(event);
|
||||||
|
|
||||||
|
long time_arrival = event.getEventTime();
|
||||||
|
int n_points = event.getPointerCount();
|
||||||
|
int action = event.getAction() & MotionEvent.ACTION_MASK;
|
||||||
|
|
||||||
|
switch(n_points){
|
||||||
|
case 1:
|
||||||
|
switch(action){
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
mode = moveTypes.DRAG;
|
||||||
|
|
||||||
|
osgNativeLib.mouseMoveEvent(event.getX(0), event.getY(0));
|
||||||
|
if(navMode==navType.PRINCIPAL)
|
||||||
|
osgNativeLib.mouseButtonPressEvent(event.getX(0), event.getY(0), 2);
|
||||||
|
else
|
||||||
|
osgNativeLib.mouseButtonPressEvent(event.getX(0), event.getY(0), 1);
|
||||||
|
|
||||||
|
oneFingerOrigin.x=event.getX(0);
|
||||||
|
oneFingerOrigin.y=event.getY(0);
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_CANCEL:
|
||||||
|
switch(mode){
|
||||||
|
case DRAG:
|
||||||
|
osgNativeLib.mouseMoveEvent(event.getX(0), event.getY(0));
|
||||||
|
if(navMode==navType.PRINCIPAL)
|
||||||
|
osgNativeLib.mouseButtonReleaseEvent(event.getX(0), event.getY(0), 2);
|
||||||
|
else
|
||||||
|
osgNativeLib.mouseButtonReleaseEvent(event.getX(0), event.getY(0), 1);
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
Log.e(TAG,"There has been an anomaly in touch input 1point/action");
|
||||||
|
}
|
||||||
|
mode = moveTypes.NONE;
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
|
||||||
|
osgNativeLib.mouseMoveEvent(event.getX(0), event.getY(0));
|
||||||
|
|
||||||
|
oneFingerOrigin.x=event.getX(0);
|
||||||
|
oneFingerOrigin.y=event.getY(0);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
switch(mode){
|
||||||
|
case DRAG:
|
||||||
|
if(navMode==navType.PRINCIPAL)
|
||||||
|
osgNativeLib.mouseButtonReleaseEvent(event.getX(0), event.getY(0), 2);
|
||||||
|
else
|
||||||
|
osgNativeLib.mouseButtonReleaseEvent(event.getX(0), event.getY(0), 1);
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
Log.e(TAG,"There has been an anomaly in touch input 1 point/action");
|
||||||
|
}
|
||||||
|
mode = moveTypes.NONE;
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
Log.e(TAG,"1 point Action not captured");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
switch (action){
|
||||||
|
case MotionEvent.ACTION_POINTER_DOWN:
|
||||||
|
//Free previous Action
|
||||||
|
switch(mode){
|
||||||
|
case DRAG:
|
||||||
|
if(navMode==navType.PRINCIPAL)
|
||||||
|
osgNativeLib.mouseButtonReleaseEvent(event.getX(0), event.getY(0), 2);
|
||||||
|
else
|
||||||
|
osgNativeLib.mouseButtonReleaseEvent(event.getX(0), event.getY(0), 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mode = moveTypes.ZOOM;
|
||||||
|
distanceOrigin = sqrDistance(event);
|
||||||
|
twoFingerOrigin.x=event.getX(1);
|
||||||
|
twoFingerOrigin.y=event.getY(1);
|
||||||
|
oneFingerOrigin.x=event.getX(0);
|
||||||
|
oneFingerOrigin.y=event.getY(0);
|
||||||
|
|
||||||
|
osgNativeLib.mouseMoveEvent(oneFingerOrigin.x,oneFingerOrigin.y);
|
||||||
|
osgNativeLib.mouseButtonPressEvent(oneFingerOrigin.x,oneFingerOrigin.y, 3);
|
||||||
|
osgNativeLib.mouseMoveEvent(oneFingerOrigin.x,oneFingerOrigin.y);
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
float distance = sqrDistance(event);
|
||||||
|
float result = distance-distanceOrigin;
|
||||||
|
distanceOrigin=distance;
|
||||||
|
|
||||||
|
if(result>1||result<-1){
|
||||||
|
oneFingerOrigin.y=oneFingerOrigin.y+result;
|
||||||
|
osgNativeLib.mouseMoveEvent(oneFingerOrigin.x,oneFingerOrigin.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_POINTER_UP:
|
||||||
|
mode =moveTypes.NONE;
|
||||||
|
osgNativeLib.mouseButtonReleaseEvent(oneFingerOrigin.x,oneFingerOrigin.y, 3);
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
mode =moveTypes.NONE;
|
||||||
|
osgNativeLib.mouseButtonReleaseEvent(oneFingerOrigin.x,oneFingerOrigin.y, 3);
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
Log.e(TAG,"2 point Action not captured");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Ui Listeners
|
||||||
|
OnClickListener uiListenerCenterView = new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
//Log.d(TAG, "Center View");
|
||||||
|
osgNativeLib.keyboardDown(32);
|
||||||
|
osgNativeLib.keyboardUp(32);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
OnClickListener uiListenerChangeNavigation = new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
//Log.d(TAG, "Change Navigation");
|
||||||
|
if(navMode==navType.PRINCIPAL){
|
||||||
|
msgUiNavSecondary.show();
|
||||||
|
navMode=navType.SECONDARY;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
msgUiNavPrincipal.show();
|
||||||
|
navMode=navType.PRINCIPAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
OnClickListener uiListenerChangeLight = new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
//Log.d(TAG, "Change Light");
|
||||||
|
if(lightMode==lightType.ON){
|
||||||
|
msgUiLightOff.show();
|
||||||
|
lightMode=lightType.OFF;
|
||||||
|
osgNativeLib.keyboardDown(108);
|
||||||
|
osgNativeLib.keyboardUp(108);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
msgUiLightOn.show();
|
||||||
|
lightMode=lightType.ON;
|
||||||
|
osgNativeLib.keyboardDown(108);
|
||||||
|
osgNativeLib.keyboardUp(108);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//Menu
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void colorChange(int color) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
// Do nothing
|
||||||
|
int red = Color.red(color);
|
||||||
|
int green = Color.green(color);
|
||||||
|
int blue = Color.blue(color);
|
||||||
|
//Log.d(TAG,"BACK color "+red+" "+green+" "+blue+" ");
|
||||||
|
osgNativeLib.setClearColor(red,green,blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Android Life Cycle Menu
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
MenuInflater inflater = getMenuInflater();
|
||||||
|
// inflater.inflate(R.menu.appmenu, menu);
|
||||||
|
return super.onCreateOptionsMenu(menu);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
// Handle item selection
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
default:
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Utilities
|
||||||
|
/** Show an event in the LogCat view, for debugging */
|
||||||
|
private void dumpEvent(MotionEvent event) {
|
||||||
|
String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
|
||||||
|
"POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
int action = event.getAction();
|
||||||
|
int actionCode = action & MotionEvent.ACTION_MASK;
|
||||||
|
sb.append("event ACTION_").append(names[actionCode]);
|
||||||
|
if (actionCode == MotionEvent.ACTION_POINTER_DOWN
|
||||||
|
|| actionCode == MotionEvent.ACTION_POINTER_UP) {
|
||||||
|
sb.append("(pid ").append(
|
||||||
|
action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
|
||||||
|
sb.append(")");
|
||||||
|
}
|
||||||
|
sb.append("[");
|
||||||
|
for (int i = 0; i < event.getPointerCount(); i++) {
|
||||||
|
sb.append("#").append(i);
|
||||||
|
sb.append("(pid ").append(event.getPointerId(i));
|
||||||
|
sb.append(")=").append((int) event.getX(i));
|
||||||
|
sb.append(",").append((int) event.getY(i));
|
||||||
|
if (i + 1 < event.getPointerCount())
|
||||||
|
sb.append(";");
|
||||||
|
}
|
||||||
|
sb.append("]");
|
||||||
|
//Log.d(TAG, sb.toString());
|
||||||
|
}
|
||||||
|
private float sqrDistance(MotionEvent event) {
|
||||||
|
float x = event.getX(0) - event.getX(1);
|
||||||
|
float y = event.getY(0) - event.getY(1);
|
||||||
|
return (float)(Math.sqrt(x * x + y * y));
|
||||||
|
}
|
||||||
|
|
||||||
|
// The below methods should all be called by the parent activity at the appropriate times
|
||||||
|
@Override
|
||||||
|
public void onOPConnected() {
|
||||||
|
super.onOPConnected();
|
||||||
|
|
||||||
|
registerObjectUpdates(objMngr.getObject("AttitudeActual"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void objectUpdated(UAVObject obj) {
|
||||||
|
float q[] = new float[4];
|
||||||
|
|
||||||
|
q[0] = (float) obj.getField("q1").getDouble();
|
||||||
|
q[1] = (float) obj.getField("q2").getDouble();
|
||||||
|
q[2] = (float) obj.getField("q3").getDouble();
|
||||||
|
q[3] = (float) obj.getField("q4").getDouble();
|
||||||
|
if (DEBUG) Log.d(TAG, "Attitude: " + q[0] + " " + q[1] + " " + q[2] + " " + q[3]);
|
||||||
|
|
||||||
|
osgNativeLib.setQuat(q[0], q[1], q[2], q[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
251
androidgcs/src/org/openpilot/osg/ColorPickerDialog.java
Normal file
251
androidgcs/src/org/openpilot/osg/ColorPickerDialog.java
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
package org.openpilot.osg;
|
||||||
|
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.LinearGradient;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Shader;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
public class ColorPickerDialog extends Dialog{
|
||||||
|
|
||||||
|
public interface OnColorChangeListener{
|
||||||
|
void colorChange(int color);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final OnColorChangeListener tListener;
|
||||||
|
private final int tInitialColor;
|
||||||
|
|
||||||
|
private static class ColorPickerView extends View{
|
||||||
|
|
||||||
|
private final Paint tPaint;
|
||||||
|
private float tCurrentHue = 0;
|
||||||
|
private int tCurrentX = 0;
|
||||||
|
private int tCurrentY = 0;
|
||||||
|
private int tCurrentColor;
|
||||||
|
private final int[] tHueGradientColors = new int [258];
|
||||||
|
private final int [] tGradientColors = new int[65536]; //256X256 colors
|
||||||
|
private final OnColorChangeListener tListener;
|
||||||
|
private boolean tQSelected = false;
|
||||||
|
|
||||||
|
public ColorPickerView(Context context, OnColorChangeListener listener, int color) {
|
||||||
|
super(context);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
tListener = listener;
|
||||||
|
|
||||||
|
//Get Hue from tCurrentColor and update the Gradient of Color
|
||||||
|
float[] newHSV = new float[3];
|
||||||
|
Color.colorToHSV(color, newHSV);
|
||||||
|
tCurrentHue = newHSV[0];
|
||||||
|
updateGradientColors();
|
||||||
|
tCurrentColor = color;
|
||||||
|
|
||||||
|
//Initialize of colors in Hue slider
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
for(float i=0; i<256; i += 256/42 , index++){
|
||||||
|
tHueGradientColors[index] = Color.rgb(255, 0, (int)i);
|
||||||
|
}
|
||||||
|
for(float i=0; i<256; i += 256/42 , index++){
|
||||||
|
tHueGradientColors[index] = Color.rgb(255-(int)i, 0, 255);
|
||||||
|
}
|
||||||
|
for(float i=0; i<256; i += 256/42 , index++){
|
||||||
|
tHueGradientColors[index] = Color.rgb(0, (int) i, 255);
|
||||||
|
}
|
||||||
|
for(float i=0; i<256; i += 256/42 , index++){
|
||||||
|
tHueGradientColors[index] = Color.rgb(0, 255, 255-(int)i);
|
||||||
|
}
|
||||||
|
for(float i=0; i<256; i += 256/42 , index++){
|
||||||
|
tHueGradientColors[index] = Color.rgb((int)i, 255, 0);
|
||||||
|
}
|
||||||
|
for(float i=0; i<256; i += 256/42 , index++){
|
||||||
|
tHueGradientColors[index] = Color.rgb(255, 255-(int)i, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Paint initialized
|
||||||
|
tPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
tPaint.setTextAlign(Paint.Align.CENTER);
|
||||||
|
tPaint.setTextSize(12);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the Color from Hue Bar
|
||||||
|
private int getCurrentGradientColor(){
|
||||||
|
|
||||||
|
int currentHue = 255 - (int)(tCurrentHue*255/360);
|
||||||
|
int index = 0;
|
||||||
|
for (float i=0; i<256; i += 256/42, index++){
|
||||||
|
if (index == currentHue) return Color.rgb(255, 0, (int) i );
|
||||||
|
}
|
||||||
|
for (float i=0; i<256; i += 256/42, index++){
|
||||||
|
if (index == currentHue) return Color.rgb(255-(int)i, 0, 255 );
|
||||||
|
}
|
||||||
|
for (float i=0; i<256; i += 256/42, index++){
|
||||||
|
if (index == currentHue) return Color.rgb(0, (int) i, 255 );
|
||||||
|
}
|
||||||
|
for (float i=0; i<256; i += 256/42, index++){
|
||||||
|
if (index == currentHue) return Color.rgb(0, 255, 255-(int) i );
|
||||||
|
}
|
||||||
|
for (float i=0; i<256; i += 256/42, index++){
|
||||||
|
if (index == currentHue) return Color.rgb((int) i, 255, 0 );
|
||||||
|
}
|
||||||
|
for (float i=0; i<256; i += 256/42, index++){
|
||||||
|
if (index == currentHue) return Color.rgb(255, 255-(int) i, 0);
|
||||||
|
}
|
||||||
|
return Color.RED;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateGradientColors(){
|
||||||
|
|
||||||
|
int actualColor = getCurrentGradientColor();
|
||||||
|
int index = 0;
|
||||||
|
int[] colColors = new int[256];
|
||||||
|
for(int y=0; y<256; y++){
|
||||||
|
for(int x=0; x<256; x++ , index++){
|
||||||
|
if(y==0){
|
||||||
|
tGradientColors[index] = Color.rgb(255-(255-Color.red(actualColor))*x/255, 255-(255-Color.green(actualColor))*x/255, 255-(255-Color.blue(actualColor))*x/255);
|
||||||
|
colColors[x] = tGradientColors[index];
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
tGradientColors[index] = Color.rgb((255-y)*Color.red(colColors[x])/255, (255-y)*Color.green(colColors[x])/255, (255-y)*Color.blue(colColors[x])/255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas){
|
||||||
|
int translatedHue = 255 - (int)(tCurrentHue*255/360);
|
||||||
|
//Display HUE with bar lines
|
||||||
|
|
||||||
|
for(int x=0; x<256; x++){
|
||||||
|
//We display the color or a big white bar
|
||||||
|
if(translatedHue != x){
|
||||||
|
tPaint.setColor(tHueGradientColors[x]);
|
||||||
|
tPaint.setStrokeWidth(1);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
tPaint.setColor(Color.WHITE);
|
||||||
|
tPaint.setStrokeWidth(3);
|
||||||
|
}
|
||||||
|
canvas.drawLine(x+10, 0, x+10, 40, tPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display Gradient Box
|
||||||
|
for(int x=0; x<256;x++){
|
||||||
|
int[] colors = new int[2];
|
||||||
|
colors[0] = tGradientColors[x];
|
||||||
|
colors[1] = Color.BLACK;
|
||||||
|
Shader shader = new LinearGradient(0,50,0,306,colors,null, Shader.TileMode.REPEAT);
|
||||||
|
tPaint.setShader(shader);
|
||||||
|
canvas.drawLine(x+10, 50, x+10, 306, tPaint);
|
||||||
|
}
|
||||||
|
tPaint.setShader(null);
|
||||||
|
|
||||||
|
//Display the circle around the currently selected color in the main field
|
||||||
|
if(tCurrentX !=0 && tCurrentY != 0){
|
||||||
|
tPaint.setStyle(Paint.Style.STROKE);
|
||||||
|
tPaint.setColor(Color.BLACK);
|
||||||
|
canvas.drawCircle(tCurrentX, tCurrentY, 10, tPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Draw a button
|
||||||
|
|
||||||
|
tPaint.setStyle(Paint.Style.FILL);
|
||||||
|
if(tQSelected){
|
||||||
|
tPaint.setColor(Color.WHITE);
|
||||||
|
canvas.drawCircle(138, 336, 30, tPaint);
|
||||||
|
}
|
||||||
|
tPaint.setColor(tCurrentColor);
|
||||||
|
canvas.drawCircle(138, 336, 20, tPaint);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int width,int height){
|
||||||
|
setMeasuredDimension(276, 366);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent event){
|
||||||
|
if(event.getAction() != MotionEvent.ACTION_DOWN && event.getAction() != MotionEvent.ACTION_MOVE && event.getAction() != MotionEvent.ACTION_UP) return true;
|
||||||
|
float x = event.getX();
|
||||||
|
float y = event.getY();
|
||||||
|
|
||||||
|
tQSelected=false;
|
||||||
|
|
||||||
|
// if in Hue Bar
|
||||||
|
if(x >10 && x <266 && y>0 && y<40){
|
||||||
|
//Update gradient
|
||||||
|
tCurrentHue = (255-x)*360/255;
|
||||||
|
updateGradientColors();
|
||||||
|
|
||||||
|
//Update current Selected Color
|
||||||
|
int nX = tCurrentX-10;
|
||||||
|
int nY = tCurrentY-60;
|
||||||
|
int index = 256 * (nY-1)+nX;
|
||||||
|
|
||||||
|
if(index>0 && index < tGradientColors.length)
|
||||||
|
tCurrentColor = tGradientColors[256*(nY-1)+nX];
|
||||||
|
|
||||||
|
invalidate(); //By invalidating we are forcing a redraw;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If Main gradient
|
||||||
|
|
||||||
|
if ( x >10 && x< 266 && y>50 && y <306){
|
||||||
|
tCurrentX = (int) x;
|
||||||
|
tCurrentY = (int) y;
|
||||||
|
int nX = tCurrentX - 10;
|
||||||
|
int nY = tCurrentY - 60;
|
||||||
|
int index = 256*(nY-1)+nX;
|
||||||
|
if (index >0 && index < tGradientColors.length){
|
||||||
|
tCurrentColor = tGradientColors[index];
|
||||||
|
|
||||||
|
invalidate(); //By invalidating we are forcing a redraw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( x>118 && x<158 && y > 316 && y <356){
|
||||||
|
if(event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE){
|
||||||
|
tQSelected=true;
|
||||||
|
}
|
||||||
|
if(event.getAction() == MotionEvent.ACTION_UP){
|
||||||
|
tQSelected=false;
|
||||||
|
tListener.colorChange(tCurrentColor);
|
||||||
|
}
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ColorPickerDialog(Context context, OnColorChangeListener listener, int initialColor){
|
||||||
|
super(context);
|
||||||
|
|
||||||
|
tListener = listener;
|
||||||
|
tInitialColor = initialColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate( Bundle savedInstanceState){
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
OnColorChangeListener l = new OnColorChangeListener(){
|
||||||
|
@Override
|
||||||
|
public void colorChange(int color){
|
||||||
|
tListener.colorChange(color);
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
setContentView(new ColorPickerView(getContext(),l,tInitialColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
333
androidgcs/src/org/openpilot/osg/EGLview.java
Normal file
333
androidgcs/src/org/openpilot/osg/EGLview.java
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
|
||||||
|
package org.openpilot.osg;
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2008 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import javax.microedition.khronos.egl.EGL10;
|
||||||
|
import javax.microedition.khronos.egl.EGLConfig;
|
||||||
|
import javax.microedition.khronos.egl.EGLContext;
|
||||||
|
import javax.microedition.khronos.egl.EGLDisplay;
|
||||||
|
import javax.microedition.khronos.opengles.GL10;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.PixelFormat;
|
||||||
|
import android.opengl.GLSurfaceView;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
/**
|
||||||
|
* A simple GLSurfaceView sub-class that demonstrate how to perform
|
||||||
|
* OpenGL ES 1.0 rendering into a GL Surface. Note the following important
|
||||||
|
* details:
|
||||||
|
*
|
||||||
|
* - The class must use a custom context factory to enable 1.0 rendering.
|
||||||
|
* See ContextFactory class definition below.
|
||||||
|
*
|
||||||
|
* - The class must use a custom EGLConfigChooser to be able to select
|
||||||
|
* an EGLConfig that supports 1.0. This is done by providing a config
|
||||||
|
* specification to eglChooseConfig() that has the attribute
|
||||||
|
* EGL10.ELG_RENDERABLE_TYPE containing the EGL_OPENGL_ES_BIT flag
|
||||||
|
* set. See ConfigChooser class definition below.
|
||||||
|
*
|
||||||
|
* - The class must select the surface's format, then choose an EGLConfig
|
||||||
|
* that matches it exactly (with regards to red/green/blue/alpha channels
|
||||||
|
* bit depths). Failure to do so would result in an EGL_BAD_MATCH error.
|
||||||
|
*/
|
||||||
|
public class EGLview extends GLSurfaceView {
|
||||||
|
private static String TAG = "EGLview";
|
||||||
|
private static final boolean DEBUG = false;
|
||||||
|
|
||||||
|
public EGLview(Context context) {
|
||||||
|
super(context);
|
||||||
|
init(false, 16, 8);
|
||||||
|
}
|
||||||
|
public EGLview(Context context, AttributeSet attrs) {
|
||||||
|
super(context,attrs);
|
||||||
|
init(false, 16, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public EGLview(Context context, boolean translucent, int depth, int stencil) {
|
||||||
|
super(context);
|
||||||
|
init(translucent, depth, stencil);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(boolean translucent, int depth, int stencil) {
|
||||||
|
|
||||||
|
/* By default, GLSurfaceView() creates a RGB_565 opaque surface.
|
||||||
|
* If we want a translucent one, we should change the surface's
|
||||||
|
* format here, using PixelFormat.TRANSLUCENT for GL Surfaces
|
||||||
|
* is interpreted as any 32-bit surface with alpha by SurfaceFlinger.
|
||||||
|
*/
|
||||||
|
if (translucent) {
|
||||||
|
this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup the context factory for 2.0 rendering.
|
||||||
|
* See ContextFactory class definition below
|
||||||
|
*/
|
||||||
|
setEGLContextFactory(new ContextFactory());
|
||||||
|
|
||||||
|
/* We need to choose an EGLConfig that matches the format of
|
||||||
|
* our surface exactly. This is going to be done in our
|
||||||
|
* custom config chooser. See ConfigChooser class definition
|
||||||
|
* below.
|
||||||
|
*/
|
||||||
|
setEGLConfigChooser( translucent ?
|
||||||
|
new ConfigChooser(8, 8, 8, 8, depth, stencil) :
|
||||||
|
new ConfigChooser(5, 6, 5, 0, depth, stencil) );
|
||||||
|
|
||||||
|
/* Set the renderer responsible for frame rendering */
|
||||||
|
setRenderer(new Renderer());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
|
||||||
|
private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
|
||||||
|
@Override
|
||||||
|
public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
|
||||||
|
Log.w(TAG, "creating OpenGL ES 2.0 context");
|
||||||
|
checkEglError("Before eglCreateContext", egl);
|
||||||
|
int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
|
||||||
|
EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
|
||||||
|
checkEglError("After eglCreateContext", egl);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
|
||||||
|
egl.eglDestroyContext(display, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkEglError(String prompt, EGL10 egl) {
|
||||||
|
int error;
|
||||||
|
while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
|
||||||
|
Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {
|
||||||
|
|
||||||
|
public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) {
|
||||||
|
mRedSize = r;
|
||||||
|
mGreenSize = g;
|
||||||
|
mBlueSize = b;
|
||||||
|
mAlphaSize = a;
|
||||||
|
mDepthSize = depth;
|
||||||
|
mStencilSize = stencil;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This EGL config specification is used to specify 1.x rendering.
|
||||||
|
* We use a minimum size of 4 bits for red/green/blue, but will
|
||||||
|
* perform actual matching in chooseConfig() below.
|
||||||
|
*/
|
||||||
|
private static int EGL_OPENGL_ES_BIT = 4;
|
||||||
|
private static int[] s_configAttribs2 =
|
||||||
|
{
|
||||||
|
EGL10.EGL_RED_SIZE, 4,
|
||||||
|
EGL10.EGL_GREEN_SIZE, 4,
|
||||||
|
EGL10.EGL_BLUE_SIZE, 4,
|
||||||
|
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
|
||||||
|
EGL10.EGL_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
|
||||||
|
|
||||||
|
/* Get the number of minimally matching EGL configurations
|
||||||
|
*/
|
||||||
|
int[] num_config = new int[1];
|
||||||
|
egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config);
|
||||||
|
|
||||||
|
int numConfigs = num_config[0];
|
||||||
|
|
||||||
|
if (numConfigs <= 0) {
|
||||||
|
throw new IllegalArgumentException("No configs match configSpec");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate then read the array of minimally matching EGL configs
|
||||||
|
*/
|
||||||
|
EGLConfig[] configs = new EGLConfig[numConfigs];
|
||||||
|
egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config);
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
printConfigs(egl, display, configs);
|
||||||
|
}
|
||||||
|
/* Now return the "best" one
|
||||||
|
*/
|
||||||
|
return chooseConfig(egl, display, configs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
|
||||||
|
EGLConfig[] configs) {
|
||||||
|
for(EGLConfig config : configs) {
|
||||||
|
int d = findConfigAttrib(egl, display, config,
|
||||||
|
EGL10.EGL_DEPTH_SIZE, 0);
|
||||||
|
int s = findConfigAttrib(egl, display, config,
|
||||||
|
EGL10.EGL_STENCIL_SIZE, 0);
|
||||||
|
|
||||||
|
// We need at least mDepthSize and mStencilSize bits
|
||||||
|
if (d < mDepthSize || s < mStencilSize)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// We want an *exact* match for red/green/blue/alpha
|
||||||
|
int r = findConfigAttrib(egl, display, config,
|
||||||
|
EGL10.EGL_RED_SIZE, 0);
|
||||||
|
int g = findConfigAttrib(egl, display, config,
|
||||||
|
EGL10.EGL_GREEN_SIZE, 0);
|
||||||
|
int b = findConfigAttrib(egl, display, config,
|
||||||
|
EGL10.EGL_BLUE_SIZE, 0);
|
||||||
|
int a = findConfigAttrib(egl, display, config,
|
||||||
|
EGL10.EGL_ALPHA_SIZE, 0);
|
||||||
|
|
||||||
|
if (r == mRedSize && g == mGreenSize && b == mBlueSize && a == mAlphaSize)
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int findConfigAttrib(EGL10 egl, EGLDisplay display,
|
||||||
|
EGLConfig config, int attribute, int defaultValue) {
|
||||||
|
|
||||||
|
if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
|
||||||
|
return mValue[0];
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printConfigs(EGL10 egl, EGLDisplay display,
|
||||||
|
EGLConfig[] configs) {
|
||||||
|
int numConfigs = configs.length;
|
||||||
|
Log.w(TAG, String.format("%d configurations", numConfigs));
|
||||||
|
for (int i = 0; i < numConfigs; i++) {
|
||||||
|
Log.w(TAG, String.format("Configuration %d:\n", i));
|
||||||
|
printConfig(egl, display, configs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printConfig(EGL10 egl, EGLDisplay display,
|
||||||
|
EGLConfig config) {
|
||||||
|
int[] attributes = {
|
||||||
|
EGL10.EGL_BUFFER_SIZE,
|
||||||
|
EGL10.EGL_ALPHA_SIZE,
|
||||||
|
EGL10.EGL_BLUE_SIZE,
|
||||||
|
EGL10.EGL_GREEN_SIZE,
|
||||||
|
EGL10.EGL_RED_SIZE,
|
||||||
|
EGL10.EGL_DEPTH_SIZE,
|
||||||
|
EGL10.EGL_STENCIL_SIZE,
|
||||||
|
EGL10.EGL_CONFIG_CAVEAT,
|
||||||
|
EGL10.EGL_CONFIG_ID,
|
||||||
|
EGL10.EGL_LEVEL,
|
||||||
|
EGL10.EGL_MAX_PBUFFER_HEIGHT,
|
||||||
|
EGL10.EGL_MAX_PBUFFER_PIXELS,
|
||||||
|
EGL10.EGL_MAX_PBUFFER_WIDTH,
|
||||||
|
EGL10.EGL_NATIVE_RENDERABLE,
|
||||||
|
EGL10.EGL_NATIVE_VISUAL_ID,
|
||||||
|
EGL10.EGL_NATIVE_VISUAL_TYPE,
|
||||||
|
0x3030, // EGL10.EGL_PRESERVED_RESOURCES,
|
||||||
|
EGL10.EGL_SAMPLES,
|
||||||
|
EGL10.EGL_SAMPLE_BUFFERS,
|
||||||
|
EGL10.EGL_SURFACE_TYPE,
|
||||||
|
EGL10.EGL_TRANSPARENT_TYPE,
|
||||||
|
EGL10.EGL_TRANSPARENT_RED_VALUE,
|
||||||
|
EGL10.EGL_TRANSPARENT_GREEN_VALUE,
|
||||||
|
EGL10.EGL_TRANSPARENT_BLUE_VALUE,
|
||||||
|
0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB,
|
||||||
|
0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA,
|
||||||
|
0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL,
|
||||||
|
0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL,
|
||||||
|
EGL10.EGL_LUMINANCE_SIZE,
|
||||||
|
EGL10.EGL_ALPHA_MASK_SIZE,
|
||||||
|
EGL10.EGL_COLOR_BUFFER_TYPE,
|
||||||
|
EGL10.EGL_RENDERABLE_TYPE,
|
||||||
|
0x3042 // EGL10.EGL_CONFORMANT
|
||||||
|
};
|
||||||
|
String[] names = {
|
||||||
|
"EGL_BUFFER_SIZE",
|
||||||
|
"EGL_ALPHA_SIZE",
|
||||||
|
"EGL_BLUE_SIZE",
|
||||||
|
"EGL_GREEN_SIZE",
|
||||||
|
"EGL_RED_SIZE",
|
||||||
|
"EGL_DEPTH_SIZE",
|
||||||
|
"EGL_STENCIL_SIZE",
|
||||||
|
"EGL_CONFIG_CAVEAT",
|
||||||
|
"EGL_CONFIG_ID",
|
||||||
|
"EGL_LEVEL",
|
||||||
|
"EGL_MAX_PBUFFER_HEIGHT",
|
||||||
|
"EGL_MAX_PBUFFER_PIXELS",
|
||||||
|
"EGL_MAX_PBUFFER_WIDTH",
|
||||||
|
"EGL_NATIVE_RENDERABLE",
|
||||||
|
"EGL_NATIVE_VISUAL_ID",
|
||||||
|
"EGL_NATIVE_VISUAL_TYPE",
|
||||||
|
"EGL_PRESERVED_RESOURCES",
|
||||||
|
"EGL_SAMPLES",
|
||||||
|
"EGL_SAMPLE_BUFFERS",
|
||||||
|
"EGL_SURFACE_TYPE",
|
||||||
|
"EGL_TRANSPARENT_TYPE",
|
||||||
|
"EGL_TRANSPARENT_RED_VALUE",
|
||||||
|
"EGL_TRANSPARENT_GREEN_VALUE",
|
||||||
|
"EGL_TRANSPARENT_BLUE_VALUE",
|
||||||
|
"EGL_BIND_TO_TEXTURE_RGB",
|
||||||
|
"EGL_BIND_TO_TEXTURE_RGBA",
|
||||||
|
"EGL_MIN_SWAP_INTERVAL",
|
||||||
|
"EGL_MAX_SWAP_INTERVAL",
|
||||||
|
"EGL_LUMINANCE_SIZE",
|
||||||
|
"EGL_ALPHA_MASK_SIZE",
|
||||||
|
"EGL_COLOR_BUFFER_TYPE",
|
||||||
|
"EGL_RENDERABLE_TYPE",
|
||||||
|
"EGL_CONFORMANT"
|
||||||
|
};
|
||||||
|
int[] value = new int[1];
|
||||||
|
for (int i = 0; i < attributes.length; i++) {
|
||||||
|
int attribute = attributes[i];
|
||||||
|
String name = names[i];
|
||||||
|
if ( egl.eglGetConfigAttrib(display, config, attribute, value)) {
|
||||||
|
Log.w(TAG, String.format(" %s: %d\n", name, value[0]));
|
||||||
|
} else {
|
||||||
|
// Log.w(TAG, String.format(" %s: failed\n", name));
|
||||||
|
while (egl.eglGetError() != EGL10.EGL_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subclasses can adjust these values:
|
||||||
|
protected int mRedSize;
|
||||||
|
protected int mGreenSize;
|
||||||
|
protected int mBlueSize;
|
||||||
|
protected int mAlphaSize;
|
||||||
|
protected int mDepthSize;
|
||||||
|
protected int mStencilSize;
|
||||||
|
private final int[] mValue = new int[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Renderer implements GLSurfaceView.Renderer {
|
||||||
|
@Override
|
||||||
|
public void onDrawFrame(GL10 gl) {
|
||||||
|
osgNativeLib.step();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSurfaceChanged(GL10 gl, int width, int height) {
|
||||||
|
osgNativeLib.init(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
||||||
|
// Do nothing
|
||||||
|
gl.glEnable(GL10.GL_DEPTH_TEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
29
androidgcs/src/org/openpilot/osg/osgNativeLib.java
Normal file
29
androidgcs/src/org/openpilot/osg/osgNativeLib.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package org.openpilot.osg;
|
||||||
|
|
||||||
|
public class osgNativeLib {
|
||||||
|
|
||||||
|
static {
|
||||||
|
System.loadLibrary("osgNativeLib");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param width the current view width
|
||||||
|
* @param height the current view height
|
||||||
|
*/
|
||||||
|
public static native void init(int width, int height);
|
||||||
|
public static native void step();
|
||||||
|
public static native void clearContents();
|
||||||
|
public static native void mouseButtonPressEvent(float x,float y, int button);
|
||||||
|
public static native void mouseButtonReleaseEvent(float x,float y, int button);
|
||||||
|
public static native void mouseMoveEvent(float x,float y);
|
||||||
|
public static native void keyboardDown(int key);
|
||||||
|
public static native void keyboardUp(int key);
|
||||||
|
public static native void setClearColor(int red,int green, int blue);
|
||||||
|
public static native int[] getClearColor();
|
||||||
|
public static native void loadObject(String address);
|
||||||
|
public static native void loadObject(String address,String name);
|
||||||
|
public static native void unLoadObject(int number);
|
||||||
|
public static native String[] getObjectNames();
|
||||||
|
public static native void setQuat(float q1, float q2, float q3, float q4);
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user