- Now they are in ndkHelper:: name space - Changed module name to ndk_helper - Changed some static members to class var or stand alone function - Added syncronization for JNIHelper.cpp - For a documentation, I will work with doc writer for future improvement Change-Id: I0055061a4f53b1904cde2e0339550ee277b35fc5 Addressed most of feedbacks, - Switched coding standard to Chrome style - Update JNI helper, and documented - Fixed other issues that is pointed out Change-Id: Icc729a55ed8dd613759f34a3fc35cb4949d2d205
321 lines
7.6 KiB
C++
321 lines
7.6 KiB
C++
/*
|
|
* Copyright 2013 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.
|
|
*/
|
|
|
|
//----------------------------------------------------------
|
|
// tapCamera.cpp
|
|
// Camera control with tap
|
|
//
|
|
//----------------------------------------------------------
|
|
#include <fstream>
|
|
#include "tapCamera.h"
|
|
|
|
namespace ndk_helper
|
|
{
|
|
|
|
const float TRANSFORM_FACTOR = 15.f;
|
|
const float TRANSFORM_FACTORZ = 10.f;
|
|
|
|
const float MOMENTUM_FACTOR_DECREASE = 0.85f;
|
|
const float MOMENTUM_FACTOR_DECREASE_SHIFT = 0.9f;
|
|
const float MOMENTUM_FACTOR = 0.8f;
|
|
const float MOMENTUM_FACTOR_THRESHOLD = 0.001f;
|
|
|
|
//----------------------------------------------------------
|
|
// Ctor
|
|
//----------------------------------------------------------
|
|
TapCamera::TapCamera() :
|
|
dragging_( false ),
|
|
pinching_( false ),
|
|
momentum_( false ),
|
|
ball_radius_( 0.75f ),
|
|
pinch_start_distance_SQ_( 0.f ),
|
|
camera_rotation_( 0.f ),
|
|
camera_rotation_start_( 0.f ),
|
|
camera_rotation_now_( 0.f ),
|
|
momemtum_steps_( 0.f ),
|
|
flip_z_( 0.f )
|
|
{
|
|
//Init offset
|
|
InitParameters();
|
|
|
|
vec_flip_ = Vec2( 1.f, -1.f );
|
|
flip_z_ = -1.f;
|
|
vec_pinch_transform_factor_ = Vec3( 1.f, 1.f, 1.f );
|
|
|
|
vec_ball_center_ = Vec2( 0, 0 );
|
|
vec_ball_now_ = Vec2( 0, 0 );
|
|
vec_ball_down_ = Vec2( 0, 0 );
|
|
|
|
vec_pinch_start_ = Vec2( 0, 0 );
|
|
vec_pinch_start_center_ = Vec2( 0, 0 );
|
|
|
|
vec_flip_ = Vec2( 0, 0 );
|
|
|
|
}
|
|
|
|
void TapCamera::InitParameters()
|
|
{
|
|
//Init parameters
|
|
vec_offset_ = Vec3();
|
|
vec_offset_now_ = Vec3();
|
|
|
|
quat_ball_rot_ = Quaternion();
|
|
quat_ball_now_ = Quaternion();
|
|
quat_ball_now_.ToMatrix( mat_rotation_ );
|
|
camera_rotation_ = 0.f;
|
|
|
|
vec_drag_delta_ = Vec2();
|
|
vec_offset_delta_ = Vec3();
|
|
|
|
momentum_ = false;
|
|
}
|
|
|
|
//----------------------------------------------------------
|
|
// Dtor
|
|
//----------------------------------------------------------
|
|
TapCamera::~TapCamera()
|
|
{
|
|
|
|
}
|
|
|
|
void TapCamera::Update()
|
|
{
|
|
if( momentum_ )
|
|
{
|
|
float momenttum_steps = momemtum_steps_;
|
|
|
|
//Momentum rotation
|
|
Vec2 v = vec_drag_delta_;
|
|
BeginDrag( Vec2() ); //NOTE:This call reset _VDragDelta
|
|
Drag( v * vec_flip_ );
|
|
|
|
//Momentum shift
|
|
vec_offset_ += vec_offset_delta_;
|
|
|
|
BallUpdate();
|
|
EndDrag();
|
|
|
|
//Decrease deltas
|
|
vec_drag_delta_ = v * MOMENTUM_FACTOR_DECREASE;
|
|
vec_offset_delta_ = vec_offset_delta_ * MOMENTUM_FACTOR_DECREASE_SHIFT;
|
|
|
|
//Count steps
|
|
momemtum_steps_ = momenttum_steps * MOMENTUM_FACTOR_DECREASE;
|
|
if( momemtum_steps_ < MOMENTUM_FACTOR_THRESHOLD )
|
|
{
|
|
momentum_ = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
vec_drag_delta_ *= MOMENTUM_FACTOR;
|
|
vec_offset_delta_ = vec_offset_delta_ * MOMENTUM_FACTOR;
|
|
BallUpdate();
|
|
}
|
|
|
|
Vec3 vec = vec_offset_ + vec_offset_now_;
|
|
Vec3 vec_tmp( TRANSFORM_FACTOR, -TRANSFORM_FACTOR, TRANSFORM_FACTORZ );
|
|
|
|
vec *= vec_tmp * vec_pinch_transform_factor_;
|
|
|
|
mat_transform_ = Mat4::Translation( vec );
|
|
}
|
|
|
|
Mat4& TapCamera::GetRotationMatrix()
|
|
{
|
|
return mat_rotation_;
|
|
}
|
|
|
|
Mat4& TapCamera::GetTransformMatrix()
|
|
{
|
|
return mat_transform_;
|
|
}
|
|
|
|
void TapCamera::Reset( const bool bAnimate )
|
|
{
|
|
InitParameters();
|
|
Update();
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------
|
|
//Drag control
|
|
//----------------------------------------------------------
|
|
void TapCamera::BeginDrag( const Vec2& v )
|
|
{
|
|
if( dragging_ )
|
|
EndDrag();
|
|
|
|
if( pinching_ )
|
|
EndPinch();
|
|
|
|
Vec2 vec = v * vec_flip_;
|
|
vec_ball_now_ = vec;
|
|
vec_ball_down_ = vec_ball_now_;
|
|
|
|
dragging_ = true;
|
|
momentum_ = false;
|
|
vec_last_input_ = vec;
|
|
vec_drag_delta_ = Vec2();
|
|
}
|
|
|
|
void TapCamera::EndDrag()
|
|
{
|
|
quat_ball_down_ = quat_ball_now_;
|
|
quat_ball_rot_ = Quaternion();
|
|
|
|
dragging_ = false;
|
|
momentum_ = true;
|
|
momemtum_steps_ = 1.0f;
|
|
}
|
|
|
|
void TapCamera::Drag( const Vec2& v )
|
|
{
|
|
if( !dragging_ )
|
|
return;
|
|
|
|
Vec2 vec = v * vec_flip_;
|
|
vec_ball_now_ = vec;
|
|
|
|
vec_drag_delta_ = vec_drag_delta_ * MOMENTUM_FACTOR + (vec - vec_last_input_);
|
|
vec_last_input_ = vec;
|
|
}
|
|
|
|
//----------------------------------------------------------
|
|
//Pinch controll
|
|
//----------------------------------------------------------
|
|
void TapCamera::BeginPinch( const Vec2& v1, const Vec2& v2 )
|
|
{
|
|
if( dragging_ )
|
|
EndDrag();
|
|
|
|
if( pinching_ )
|
|
EndPinch();
|
|
|
|
BeginDrag( Vec2() );
|
|
|
|
vec_pinch_start_center_ = (v1 + v2) / 2.f;
|
|
|
|
Vec2 vec = v1 - v2;
|
|
float x_diff;
|
|
float y_diff;
|
|
vec.Value( x_diff, y_diff );
|
|
|
|
pinch_start_distance_SQ_ = x_diff * x_diff + y_diff * y_diff;
|
|
camera_rotation_start_ = atan2f( y_diff, x_diff );
|
|
camera_rotation_now_ = 0;
|
|
|
|
pinching_ = true;
|
|
momentum_ = false;
|
|
|
|
//Init momentum factors
|
|
vec_offset_delta_ = Vec3();
|
|
}
|
|
|
|
void TapCamera::EndPinch()
|
|
{
|
|
pinching_ = false;
|
|
momentum_ = true;
|
|
momemtum_steps_ = 1.f;
|
|
vec_offset_ += vec_offset_now_;
|
|
camera_rotation_ += camera_rotation_now_;
|
|
vec_offset_now_ = Vec3();
|
|
|
|
camera_rotation_now_ = 0;
|
|
|
|
EndDrag();
|
|
}
|
|
|
|
void TapCamera::Pinch( const Vec2& v1, const Vec2& v2 )
|
|
{
|
|
if( !pinching_ )
|
|
return;
|
|
|
|
//Update momentum factor
|
|
vec_offset_last_ = vec_offset_now_;
|
|
|
|
float x_diff, y_diff;
|
|
Vec2 vec = v1 - v2;
|
|
vec.Value( x_diff, y_diff );
|
|
|
|
float fDistanceSQ = x_diff * x_diff + y_diff * y_diff;
|
|
|
|
float f = pinch_start_distance_SQ_ / fDistanceSQ;
|
|
if( f < 1.f )
|
|
f = -1.f / f + 1.0f;
|
|
else
|
|
f = f - 1.f;
|
|
if( isnan( f ) )
|
|
f = 0.f;
|
|
|
|
vec = (v1 + v2) / 2.f - vec_pinch_start_center_;
|
|
vec_offset_now_ = Vec3( vec, flip_z_ * f );
|
|
|
|
//Update momentum factor
|
|
vec_offset_delta_ = vec_offset_delta_ * MOMENTUM_FACTOR
|
|
+ (vec_offset_now_ - vec_offset_last_);
|
|
|
|
//
|
|
//Update ration quaternion
|
|
float fRotation = atan2f( y_diff, x_diff );
|
|
camera_rotation_now_ = fRotation - camera_rotation_start_;
|
|
|
|
//Trackball rotation
|
|
quat_ball_rot_ = Quaternion( 0.f, 0.f, sinf( -camera_rotation_now_ * 0.5f ),
|
|
cosf( -camera_rotation_now_ * 0.5f ) );
|
|
}
|
|
|
|
//----------------------------------------------------------
|
|
//Trackball controll
|
|
//----------------------------------------------------------
|
|
void TapCamera::BallUpdate()
|
|
{
|
|
if( dragging_ )
|
|
{
|
|
Vec3 vec_from = PointOnSphere( vec_ball_down_ );
|
|
Vec3 vec_to = PointOnSphere( vec_ball_now_ );
|
|
|
|
Vec3 vec = vec_from.Cross( vec_to );
|
|
float w = vec_from.Dot( vec_to );
|
|
|
|
Quaternion qDrag = Quaternion( vec, w );
|
|
qDrag = qDrag * quat_ball_down_;
|
|
quat_ball_now_ = quat_ball_rot_ * qDrag;
|
|
}
|
|
quat_ball_now_.ToMatrix( mat_rotation_ );
|
|
}
|
|
|
|
Vec3 TapCamera::PointOnSphere( Vec2& point )
|
|
{
|
|
Vec3 ball_mouse;
|
|
float mag;
|
|
Vec2 vec = (point - vec_ball_center_) / ball_radius_;
|
|
mag = vec.Dot( vec );
|
|
if( mag > 1.f )
|
|
{
|
|
float scale = 1.f / sqrtf( mag );
|
|
vec *= scale;
|
|
ball_mouse = Vec3( vec, 0.f );
|
|
}
|
|
else
|
|
{
|
|
ball_mouse = Vec3( vec, sqrtf( 1.f - mag ) );
|
|
}
|
|
return ball_mouse;
|
|
}
|
|
|
|
} //namespace ndkHelper
|