utc-Dali-StyleManager.cpp
utc-Dali-SuperBlurView.cpp
utc-Dali-Toolkit.cpp
+ utc-Dali-Model3dView.cpp
)
# Append list of test harness files (Won't get parsed for test cases)
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/public-api/controls/model3d-view/model3d-view.h>
+
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+
+
+void model_view_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void model_view_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+namespace
+{
+const char * TEST_OBJ_FILE_NAME = "Dino.obj";
+const char * TEST_MTL_FILE_NAME = "Dino.mtl";
+//const char * TEST_IMG_PATH = "";
+}
+
+// Negative test case for a method
+int UtcDaliModelViewUninitialized(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliModel3dViewUninitialized");
+
+ Toolkit::Model3dView view;
+
+ try
+ {
+ // New() must be called to create a Model3dView or it wont be valid.
+ Actor a = Actor::New();
+ view.Add( a );
+ DALI_TEST_CHECK( false );
+ }
+ catch (Dali::DaliException& e)
+ {
+ // Tests that a negative test of an assertion succeeds
+ DALI_TEST_PRINT_ASSERT( e );
+ DALI_TEST_CHECK(!view);
+ }
+ END_TEST;
+}
+
+// Positive test case for a method
+int UtcDaliModelViewNew(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliModel3dViewNew");
+
+ Toolkit::Model3dView view = Toolkit::Model3dView::New();
+ DALI_TEST_CHECK( view );
+
+ Toolkit::Model3dView view2 = Toolkit::Model3dView::New("","","");
+ DALI_TEST_CHECK( view2 );
+ END_TEST;
+}
+
+// Positive test case for a method
+int UtcDaliModelViewDownCast(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliModelViewDownCast");
+
+ Toolkit::Model3dView view = Toolkit::Model3dView::New();
+ BaseHandle handle(view);
+
+ Toolkit::Model3dView modelView = Toolkit::Model3dView::DownCast( handle );
+ DALI_TEST_CHECK( view );
+ DALI_TEST_CHECK( modelView );
+ DALI_TEST_CHECK( modelView == view );
+ END_TEST;
+}
+
+
+// Positive test case for a method
+int UtcDaliModelViewPropertyNames(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliModel3dViewPropertyNames");
+
+ Toolkit::Model3dView view = Toolkit::Model3dView::New();
+ DALI_TEST_CHECK( view );
+
+ view.SetProperty( Model3dView::Property::GEOMETRY_URL, Dali::Property::Value( TEST_OBJ_FILE_NAME ) );
+ Property::Value val = view.GetProperty( Model3dView::Property::GEOMETRY_URL );
+ std::string obj_file_name;
+ DALI_TEST_CHECK( val.Get( obj_file_name ) );
+ DALI_TEST_EQUALS( obj_file_name, TEST_OBJ_FILE_NAME, TEST_LOCATION );
+
+ view.SetProperty( Model3dView::Property::MATERIAL_URL, Dali::Property::Value( TEST_MTL_FILE_NAME ) );
+ val = view.GetProperty( Model3dView::Property::MATERIAL_URL );
+ DALI_TEST_CHECK( val.Get( obj_file_name ) );
+ DALI_TEST_EQUALS( obj_file_name, TEST_MTL_FILE_NAME, TEST_LOCATION );
+
+ //modelView.SetProperty( Model3dView::Property::MTL_URL, Dali::Property::Value( mtlUrl ) );
+ //modelView.SetProperty( Model3dView::Property::IMAGES_URL, Dali::Property::Value( imagesUrl ) );
+
+ END_TEST;
+}
+
+// Positive test case for a method
+int UtcDaliModelViewAddRemove(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliModel3dViewAddRemove");
+
+ Toolkit::Model3dView view = Toolkit::Model3dView::New();
+ DALI_TEST_CHECK( view );
+
+ Actor actor = Actor::New();
+ DALI_TEST_CHECK( !actor.OnStage() );
+
+
+ view.SetParentOrigin(ParentOrigin::CENTER);
+ view.SetSize(Stage::GetCurrent().GetSize());
+ view.Add(actor);
+ Stage::GetCurrent().Add(view);
+
+ DALI_TEST_CHECK( actor.OnStage() );
+
+ view.Remove(actor);
+
+ DALI_TEST_CHECK( !actor.OnStage() );
+ END_TEST;
+}
+
+
+int UtcDaliModelCopyAndAssignment(void)
+{
+ ToolkitTestApplication application;
+
+ Model3dView view = Toolkit::Model3dView::New();
+ DALI_TEST_CHECK( view );
+
+ Model3dView copy( view );
+ DALI_TEST_CHECK( view == copy );
+
+ Model3dView assign;
+ DALI_TEST_CHECK( ! assign );
+
+ assign = copy;
+ DALI_TEST_CHECK( assign == view );
+
+ END_TEST;
+}
+
+int UtcDaliModelTypeRegistry(void)
+{
+ ToolkitTestApplication application;
+
+ TypeRegistry typeRegistry = TypeRegistry::Get();
+ DALI_TEST_CHECK( typeRegistry );
+
+ TypeInfo typeInfo = typeRegistry.GetTypeInfo( "Model3dView" );
+ DALI_TEST_CHECK( typeInfo );
+
+ BaseHandle handle = typeInfo.CreateInstance();
+ DALI_TEST_CHECK( handle );
+
+ Model3dView view = Model3dView::DownCast( handle );
+ DALI_TEST_CHECK( view );
+
+ END_TEST;
+}
+
+int UtcDaliModelOnSizeSet(void)
+{
+ ToolkitTestApplication application;
+
+ Model3dView view = Toolkit::Model3dView::New();
+
+ Stage::GetCurrent().Add( view );
+
+ application.SendNotification();
+ application.Render();
+
+ Vector3 size( 200.0f, 300.0f, 0.0f );
+ view.SetSize( size );
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( view.GetCurrentSize(), size, TEST_LOCATION );
+
+ END_TEST;
+}
publicapidefaultcontrolsdir = $(publicapicontrolsdir)/default-controls
publicapigaussianblurviewdir = $(publicapicontrolsdir)/gaussian-blur-view
publicapiimageviewdir = $(publicapicontrolsdir)/image-view
+publicapimodel3dviewdir = $(publicapicontrolsdir)/model3d-view
publicapiscrollbardir = $(publicapicontrolsdir)/scroll-bar
publicapiscrollabledir = $(publicapicontrolsdir)/scrollable
publicapiscrollviewdir = $(publicapicontrolsdir)/scrollable/scroll-view
publicapigaussianblurview_HEADERS = $(public_api_gaussian_blur_view_header_files)
publicapiimageview_HEADERS = $(public_api_image_view_header_files)
publicapiitemview_HEADERS = $(public_api_item_view_header_files)
+publicapimodel3dview_HEADERS = $(public_api_model3d_view_header_files)
publicapiscrollbar_HEADERS = $(public_api_scroll_bar_header_files)
publicapiscrollable_HEADERS = $(public_api_scrollable_header_files)
publicapiscrollview_HEADERS = $(public_api_scroll_view_header_files)
#include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
#include <dali-toolkit/public-api/controls/gaussian-blur-view/gaussian-blur-view.h>
#include <dali-toolkit/public-api/controls/image-view/image-view.h>
+#include <dali-toolkit/public-api/controls/model3d-view/model3d-view.h>
#include <dali-toolkit/public-api/controls/scroll-bar/scroll-bar.h>
#include <dali-toolkit/public-api/controls/scrollable/item-view/default-item-layout.h>
#include <dali-toolkit/public-api/controls/scrollable/item-view/item-factory.h>
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include "model3d-view-impl.h"
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/type-registry.h>
+#include <dali/public-api/animation/constraint.h>
+#include <dali/public-api/animation/constraint-source.h>
+#include <dali/public-api/animation/constraints.h>
+#include <dali/devel-api/object/type-registry-helper.h>
+#include <dali-toolkit/public-api/controls/model3d-view/model3d-view.h>
+#include <dali/public-api/images/resource-image.h>
+#include <dali/devel-api/adaptor-framework/file-loader.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/model3d-view/obj-loader.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace
+{
+
+// Type registration
+BaseHandle Create()
+{
+ return Toolkit::Model3dView::New();
+}
+
+// Setup properties, signals and actions using the type-registry.
+DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Model3dView, Toolkit::Control, Create );
+
+DALI_PROPERTY_REGISTRATION( Toolkit, Model3dView, "geometry-url", STRING, GEOMETRY_URL)
+DALI_PROPERTY_REGISTRATION( Toolkit, Model3dView, "material-url", STRING, MATERIAL_URL)
+DALI_PROPERTY_REGISTRATION( Toolkit, Model3dView, "images-url", STRING, IMAGES_URL)
+DALI_PROPERTY_REGISTRATION( Toolkit, Model3dView, "illumination-type", INTEGER, ILLUMINATION_TYPE)
+DALI_PROPERTY_REGISTRATION( Toolkit, Model3dView, "texture0-url", STRING, TEXTURE0_URL)
+DALI_PROPERTY_REGISTRATION( Toolkit, Model3dView, "texture1-url", STRING, TEXTURE1_URL)
+DALI_PROPERTY_REGISTRATION( Toolkit, Model3dView, "texture2-url", STRING, TEXTURE2_URL)
+
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, Model3dView, "light-position", VECTOR3, LIGHT_POSITION)
+
+DALI_TYPE_REGISTRATION_END()
+
+
+#define MAKE_SHADER(A)#A
+
+// Diffuse illumination shader
+
+const char* SIMPLE_VERTEX_SHADER = MAKE_SHADER(
+ attribute highp vec3 aPosition;\n
+ attribute highp vec2 aTexCoord;\n
+ attribute highp vec3 aNormal;\n
+ varying mediump vec3 vIllumination;\n
+ uniform mediump vec3 uSize;\n
+ uniform mediump mat4 uMvpMatrix;\n
+ uniform mediump mat4 uModelView;\n
+ uniform mediump mat3 uNormalMatrix;
+ uniform mediump mat4 uObjectMatrix;\n
+ uniform mediump vec3 uLightPosition;\n
+ \n
+ void main()\n
+ {\n
+ vec4 vertexPosition = vec4(aPosition*min(uSize.x, uSize.y), 1.0);\n
+ vertexPosition = uObjectMatrix * vertexPosition;\n
+ vertexPosition = uMvpMatrix * vertexPosition;\n
+ \n
+ //Illumination in Model-View space - Transform attributes and uniforms\n
+ vec4 vertPos4 = uModelView * vec4(aPosition.xyz, 1.0);\n
+ vec3 vertPos = vec3(vertPos4) / vertPos4.w;\n
+ \n
+ vec3 normalInterp = uNormalMatrix * aNormal;\n
+ \n
+ vec4 lightPos4 = uModelView * vec4(uLightPosition, 1.0);\n
+ vec3 lightPos = vec3(lightPos4) / lightPos4.w;\n
+ \n
+ vec3 vecToLight = normalize( lightPos.xyz - vertPos.xyz );\n
+ \n
+ float lightDiffuse = dot( vecToLight, normalInterp );\n
+ lightDiffuse = max(0.0,lightDiffuse);\n
+ vIllumination = vec3(lightDiffuse * 0.5 + 0.5);\n
+ \n
+ gl_Position = vertexPosition;\n
+ }\n
+);
+
+const char* SIMPLE_FRAGMENT_SHADER = MAKE_SHADER(
+ precision mediump float;\n
+ varying mediump vec3 vIllumination;\n
+ uniform lowp vec4 uColor;\n
+ \n
+ void main()\n
+ {\n
+ gl_FragColor.rgb = vIllumination.rgb * uColor.rgb;\n
+ gl_FragColor.a = uColor.a;\n
+ }\n
+);
+
+// Diffuse and specular illumination shader with albedo texture
+
+const char* VERTEX_SHADER = MAKE_SHADER(
+ attribute highp vec3 aPosition;\n
+ attribute highp vec2 aTexCoord;\n
+ attribute highp vec3 aNormal;\n
+ varying mediump vec2 vTexCoord;\n
+ varying mediump vec3 vIllumination;\n
+ varying mediump float vSpecular;\n
+ uniform mediump vec3 uSize;\n
+ uniform mediump mat4 uMvpMatrix;\n
+ uniform mediump mat4 uModelView;
+ uniform mediump mat3 uNormalMatrix;
+ uniform mediump mat4 uObjectMatrix;\n
+ uniform mediump vec3 uLightPosition;\n
+ \n
+ void main()
+ {\n
+ vec4 vertexPosition = vec4(aPosition*min(uSize.x, uSize.y), 1.0);\n
+ vertexPosition = uObjectMatrix * vertexPosition;\n
+ vertexPosition = uMvpMatrix * vertexPosition;\n
+ \n
+ //Illumination in Model-View space - Transform attributes and uniforms\n
+ vec4 vertPos4 = uModelView * vec4(aPosition.xyz, 1.0);\n
+ vec3 vertPos = vec3(vertPos4) / vertPos4.w;\n
+ \n
+ vec4 lightPos4 = uModelView * vec4(uLightPosition, 1.0);\n
+ vec3 lightPos = vec3(lightPos4) / lightPos4.w;\n
+ \n
+ vec3 normalInterp = normalize(uNormalMatrix * aNormal);\n
+ \n
+ vec3 vecToLight = normalize( lightPos.xyz - vertPos.xyz );\n
+ vec3 viewDir = normalize(-vertPos);
+ \n
+ vec3 halfVector = normalize(viewDir + vecToLight);
+ \n
+ float lightDiffuse = dot( vecToLight, normalInterp );\n
+ lightDiffuse = max(0.0,lightDiffuse);\n
+ vIllumination = vec3(lightDiffuse * 0.5 + 0.5);\n
+ \n
+ // this is blinn phong
+ //float specAngle = max(dot(halfVector, normalInterp), 0.0);\n
+ //vSpecular = pow(specAngle, 16.0);\n
+ \n
+ // this is phong (for comparison)
+ vec3 reflectDir = reflect(-vecToLight, normalInterp);
+ float specAngle = max(dot(reflectDir, viewDir), 0.0);
+ // note that the exponent is different here
+ vSpecular = pow(specAngle, 16.0/4.0);
+ \n
+ vTexCoord = aTexCoord;\n
+ gl_Position = vertexPosition;\n
+ }\n
+);
+
+const char* FRAGMENT_SHADER = MAKE_SHADER(
+ precision mediump float;\n
+ varying mediump vec2 vTexCoord;\n
+ varying mediump vec3 vIllumination;\n
+ varying mediump float vSpecular;\n
+ uniform sampler2D sDiffuse;\n
+ uniform lowp vec4 uColor;\n
+ \n
+ void main()\n
+ {\n
+ vec4 texture = texture2D( sDiffuse, vTexCoord );\n
+ gl_FragColor.rgb = vIllumination.rgb * texture.rgb * uColor.rgb + vSpecular * 0.3;\n
+ gl_FragColor.a = texture.a * uColor.a;\n
+ }\n
+);
+
+// Diffuse and specular illumination shader with albedo texture, normal map and gloss map shader
+
+const char* NRMMAP_VERTEX_SHADER = MAKE_SHADER(
+ attribute highp vec3 aPosition;\n
+ attribute highp vec2 aTexCoord;\n
+ attribute highp vec3 aNormal;\n
+ attribute highp vec3 aTangent;\n
+ attribute highp vec3 aBiNormal;\n
+ varying mediump vec2 vTexCoord;\n
+ varying mediump vec3 vLightDirection;\n
+ varying mediump vec3 vHalfVector;\n
+ uniform mediump vec3 uSize;\n
+ uniform mediump mat4 uMvpMatrix;\n
+ uniform mediump mat4 uModelView;
+ uniform mediump mat3 uNormalMatrix;
+ uniform mediump mat4 uObjectMatrix;\n
+ uniform mediump vec3 uLightPosition;\n
+ \n
+ void main()
+ {\n
+ vec4 vertexPosition = vec4(aPosition*min(uSize.x, uSize.y), 1.0);\n
+ vertexPosition = uObjectMatrix * vertexPosition;\n
+ vertexPosition = uMvpMatrix * vertexPosition;\n
+ \n
+ vTexCoord = aTexCoord;\n
+ \n
+ vec3 vNormal = normalize(uNormalMatrix * aNormal);\n
+ vec3 vTangent = normalize(uNormalMatrix * aTangent);\n
+ vec3 vBiNormal = normalize(uNormalMatrix * aBiNormal);\n
+ \n
+ vec4 vertPos4 = uModelView * vec4(aPosition.xyz, 1.0);\n
+ vec3 vertPos = vec3(vertPos4) / vertPos4.w;\n
+ \n
+ vec4 lightPos4 = uModelView * vec4(uLightPosition, 1.0);\n
+ vec3 lightPos = vec3(lightPos4) / lightPos4.w;\n
+ \n
+ vec3 vecToLight = lightPos - vertPos;
+ vLightDirection.x = dot(vecToLight, vTangent);
+ vLightDirection.y = dot(vecToLight, vBiNormal);
+ vLightDirection.z = dot(vecToLight, vNormal);
+ vLightDirection = normalize(vLightDirection);
+ \n
+ vec3 viewDir = normalize(vertPos);
+ \n
+ vec3 halfVector = normalize(viewDir + vecToLight);
+ vHalfVector.x = dot (halfVector, vTangent);
+ vHalfVector.y = dot (halfVector, vBiNormal);
+ vHalfVector.z = dot (halfVector, vNormal);
+ \n
+ gl_Position = vertexPosition;\n
+
+ //vHalfVector = aTangent;
+ }\n
+);
+
+const char* NRMMAP_FRAGMENT_SHADER = MAKE_SHADER(
+ precision mediump float;\n
+ varying mediump vec2 vTexCoord;\n
+ varying mediump vec3 vLightDirection;\n
+ varying mediump vec3 vHalfVector;\n
+ uniform sampler2D sDiffuse;\n
+ uniform sampler2D sNormal;\n
+ uniform sampler2D sGloss;\n
+ uniform lowp vec4 uColor;\n
+ \n
+ void main()\n
+ {\n
+ vec4 texture = texture2D( sDiffuse, vTexCoord );\n
+ vec4 nrmMap = texture2D( sNormal, vTexCoord ) * 2.0 - 1.0;\n
+ vec4 glossMap = texture2D( sGloss, vTexCoord );\n
+ \n
+ vec3 normalizedLightDirection = normalize(vLightDirection);\n
+ float lightDiffuse = max( 0.0, dot( nrmMap.xyz, normalizedLightDirection ) );\n
+ lightDiffuse = lightDiffuse * 0.5 + 0.5;\n
+ \n
+ float shininess = pow (max (dot (vHalfVector, nrmMap.xyz), 0.0), 16.0) ;
+ \n
+ gl_FragColor.rgb = texture.rgb * uColor.rgb * lightDiffuse + shininess * glossMap.rgb;\n
+ gl_FragColor.a = texture.a * uColor.a;\n
+
+ //gl_FragColor.rgb = vHalfVector.rgb;
+ }\n
+);
+
+
+} // anonymous namespace
+
+using namespace Dali;
+
+void LookAt(Matrix& result, const Vector3& eye, const Vector3& target, const Vector3& up)
+{
+ Vector3 vZ = target - eye;
+ vZ.Normalize();
+
+ Vector3 vX = up.Cross(vZ);
+ vX.Normalize();
+
+ Vector3 vY = vZ.Cross(vX);
+ vY.Normalize();
+
+ result.SetInverseTransformComponents(vX, vY, vZ, eye);
+}
+
+
+Model3dView::Model3dView()
+ : Control( ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) )
+{
+ mTexture0Url = "";
+ mTexture1Url = "";
+ mTexture2Url = "";
+
+ mIlluminationType = Toolkit::Model3dView::DIFFUSE_WITH_NORMAL_MAP;
+
+ mCameraFOV = Math::PI_OVER_180 * 45.f;
+
+ mControlSize = Vector2(100.,100.);
+}
+
+Model3dView::~Model3dView()
+{
+}
+
+Toolkit::Model3dView Model3dView::New()
+{
+ Model3dView* impl = new Model3dView();
+
+ Dali::Toolkit::Model3dView handle = Dali::Toolkit::Model3dView( *impl );
+
+ // Second-phase init of the implementation
+ // This can only be done after the CustomActor connection has been made...
+ impl->Initialize();
+
+ return handle;
+}
+
+void Model3dView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
+{
+ Toolkit::Model3dView model3dView = Toolkit::Model3dView::DownCast( Dali::BaseHandle( object ) );
+
+ if( model3dView )
+ {
+ Model3dView& impl( GetImpl( model3dView ) );
+ switch( index )
+ {
+ case Toolkit::Model3dView::Property::GEOMETRY_URL:
+ {
+ if( value.Get(impl.mObjUrl) )
+ {
+ impl.LoadGeometry();
+ impl.CreateGeometry();
+ }
+ break;
+ }
+ case Toolkit::Model3dView::Property::MATERIAL_URL:
+ {
+ if( value.Get(impl.mMaterialUrl) )
+ {
+ impl.LoadMaterial();
+ impl.CreateMaterial();
+ }
+ break;
+ }
+ case Toolkit::Model3dView::Property::IMAGES_URL:
+ {
+ if( value.Get(impl.mImagesUrl) )
+ {
+ impl.LoadTextures();
+ }
+ break;
+ }
+ case Toolkit::Model3dView::Property::ILLUMINATION_TYPE:
+ {
+ int illuminationType;
+ if( value.Get(illuminationType) )
+ {
+ impl.mIlluminationType = Toolkit::Model3dView::IlluminationType(illuminationType);
+ impl.CreateGeometry();
+ impl.CreateMaterial();
+ impl.LoadTextures();
+ }
+ break;
+ }
+ case Toolkit::Model3dView::Property::TEXTURE0_URL:
+ {
+ value.Get(impl.mTexture0Url);
+ break;
+ }
+ case Toolkit::Model3dView::Property::TEXTURE1_URL:
+ {
+ value.Get(impl.mTexture1Url);
+ break;
+ }
+ case Toolkit::Model3dView::Property::TEXTURE2_URL:
+ {
+ value.Get(impl.mTexture2Url);
+ break;
+ }
+ }
+ }
+}
+
+Property::Value Model3dView::GetProperty( BaseObject* object, Property::Index index )
+{
+ Property::Value value;
+
+ Toolkit::Model3dView model3dView = Toolkit::Model3dView::DownCast( Dali::BaseHandle( object ) );
+
+ if( model3dView )
+ {
+ Model3dView& impl( GetImpl( model3dView ) );
+ switch( index )
+ {
+ case Toolkit::Model3dView::Property::GEOMETRY_URL:
+ {
+ value = impl.mObjUrl;
+ break;
+ }
+ case Toolkit::Model3dView::Property::MATERIAL_URL:
+ {
+ value = impl.mMaterialUrl;
+ break;
+ }
+ case Toolkit::Model3dView::Property::IMAGES_URL:
+ {
+ value = impl.mImagesUrl;
+ break;
+ }
+ case Toolkit::Model3dView::Property::ILLUMINATION_TYPE:
+ {
+ value = int(impl.mIlluminationType);
+ break;
+ }
+ case Toolkit::Model3dView::Property::TEXTURE0_URL:
+ {
+ value = impl.mTexture0Url;
+ break;
+ }
+ case Toolkit::Model3dView::Property::TEXTURE1_URL:
+ {
+ value = impl.mTexture1Url;
+ break;
+ }
+ case Toolkit::Model3dView::Property::TEXTURE2_URL:
+ {
+ value = impl.mTexture2Url;
+ break;
+ }
+ }
+ }
+
+ return value;
+}
+
+/////////////////////////////////////////////////////////////
+
+
+void Model3dView::OnStageConnection( int depth )
+{
+ CustomActor self = Self();
+ self.AddRenderer( mRenderer );
+
+ if( mObjLoader.IsSceneLoaded() )
+ {
+ mMesh = mObjLoader.CreateGeometry(mIlluminationType);
+
+ CreateMaterial();
+ LoadTextures();
+
+ mRenderer.SetGeometry( mMesh );
+
+ //create constraint for lightPosition Property with uLightPosition in the shader
+ Vector3 lightPosition( 0, 0, 0 );
+ Dali::Property::Index lightProperty = mShader.RegisterProperty( "uLightPosition", lightPosition );
+ Constraint constraint = Constraint::New<Vector3>( mShader, lightProperty, EqualToConstraint() );
+ constraint.AddSource( Source( self, Toolkit::Model3dView::Property::LIGHT_POSITION ) );
+ constraint.Apply();
+ }
+}
+
+///////////////////////////////////////////////////////////
+//
+// Private methods
+//
+
+void Model3dView::OnInitialize()
+{
+ //Create empty versions of the geometry and material so we always have a Renderer
+ Geometry mesh = Geometry::New();
+ Shader shader = Shader::New( SIMPLE_VERTEX_SHADER, SIMPLE_FRAGMENT_SHADER, (Shader::ShaderHints)(Shader::HINT_REQUIRES_SELF_DEPTH_TEST | Shader::HINT_MODIFIES_GEOMETRY) );
+ Material material = Material::New( shader );
+ mRenderer = Renderer::New( mesh, material );
+}
+
+void Model3dView::LoadGeometry()
+{
+ //Load file in adaptor
+ std::streampos fileSize;
+ Dali::Vector<char> fileContent;
+
+ if (FileLoader::ReadFile(mObjUrl,fileSize,fileContent,FileLoader::TEXT))
+ {
+ mObjLoader.ClearArrays();
+
+ std::string materialUrl;
+ mObjLoader.Load(fileContent.Begin(), fileSize, materialUrl);
+
+ //Get size information from the obj loaded
+ mSceneCenter = mObjLoader.GetCenter();
+ mSceneSize = mObjLoader.GetSize();
+ }
+ else
+ {
+ //Error
+ }
+}
+
+void Model3dView::LoadMaterial()
+{
+ //Load file in adaptor
+ std::streampos fileSize;
+ Dali::Vector<char> fileContent;
+
+ if( FileLoader::ReadFile(mMaterialUrl, fileSize, fileContent, FileLoader::TEXT) )
+ {
+ mObjLoader.LoadMaterial(fileContent.Begin(), fileSize, mTexture0Url, mTexture1Url, mTexture2Url);
+ }
+ else
+ {
+ //Error
+ }
+}
+
+void Model3dView::Load()
+{
+ LoadGeometry();
+ LoadMaterial();
+}
+
+void Model3dView::OnRelayout( const Vector2& size, RelayoutContainer& container )
+{
+ UpdateView();
+}
+
+void Model3dView::UpdateView()
+{
+ if( mObjLoader.IsSceneLoaded() )
+ {
+ //The object will always be centred
+
+ Matrix scaleMatrix;
+ scaleMatrix.SetIdentityAndScale(Vector3(1.0, -1.0, 1.0));
+
+ mShader.RegisterProperty( "uObjectMatrix", scaleMatrix );
+ }
+}
+
+void Model3dView::CreateGeometry()
+{
+ if( mObjLoader.IsSceneLoaded() )
+ {
+ mMesh = mObjLoader.CreateGeometry(mIlluminationType);
+
+ if( mRenderer )
+ {
+ mRenderer.SetGeometry( mMesh );
+ }
+ }
+}
+
+void Model3dView::UpdateShaderUniforms()
+{
+ if( mShader )
+ {
+ //Update shader related info, uniforms, etc. for the new shader
+ UpdateView();
+
+ Vector3 lightPosition( 0, 0, 0 );
+ Dali::Property::Index lightProperty = mShader.RegisterProperty( "lightPosition", lightPosition );
+
+ CustomActor self = Self();
+
+ //create constraint for lightPosition Property with uLightPosition in the shader
+ if( lightProperty )
+ {
+ Constraint constraint = Constraint::New<Vector3>( mShader, lightProperty, EqualToConstraint() );
+ constraint.AddSource( Source( self, Toolkit::Model3dView::Property::LIGHT_POSITION ) );
+ constraint.Apply();
+ }
+ }
+}
+
+void Model3dView::CreateMaterial()
+{
+ if( mObjLoader.IsMaterialLoaded() && (mTexture0Url != ""))
+ {
+ if( (mTexture2Url != "") && (mTexture1Url != "") && (mIlluminationType == Toolkit::Model3dView::DIFFUSE_WITH_NORMAL_MAP))
+ {
+ mShader = Shader::New( NRMMAP_VERTEX_SHADER, NRMMAP_FRAGMENT_SHADER, (Shader::ShaderHints)(Shader::HINT_REQUIRES_SELF_DEPTH_TEST | Shader::HINT_MODIFIES_GEOMETRY) );
+ }
+ else if(mIlluminationType == Toolkit::Model3dView::DIFFUSE_WITH_TEXTURE)
+ {
+ mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER, (Shader::ShaderHints)(Shader::HINT_REQUIRES_SELF_DEPTH_TEST | Shader::HINT_MODIFIES_GEOMETRY) );
+ }
+ else
+ {
+ mShader = Shader::New( SIMPLE_VERTEX_SHADER, SIMPLE_FRAGMENT_SHADER, (Shader::ShaderHints)(Shader::HINT_REQUIRES_SELF_DEPTH_TEST | Shader::HINT_MODIFIES_GEOMETRY) );
+ }
+ }
+ else
+ {
+ mShader = Shader::New( SIMPLE_VERTEX_SHADER, SIMPLE_FRAGMENT_SHADER, (Shader::ShaderHints)(Shader::HINT_REQUIRES_SELF_DEPTH_TEST | Shader::HINT_MODIFIES_GEOMETRY) );
+ }
+
+ mMaterial = Material::New( mShader );
+
+ mMaterial.SetFaceCullingMode(Material::NONE);
+
+ if( mRenderer )
+ {
+ mRenderer.SetMaterial( mMaterial );
+ }
+
+ UpdateShaderUniforms();
+}
+
+void Model3dView::LoadTextures()
+{
+ if( !mMaterial )
+ return ;
+
+ if( mTexture0Url != "" )
+ {
+ std::string imgUrl = mImagesUrl + mTexture0Url;
+
+ //Load textures
+ Image tex0 = ResourceImage::New( imgUrl );
+ if( tex0 )
+ {
+ Sampler sampler = Sampler::New( tex0, "sDiffuse" );
+ sampler.SetWrapMode(Sampler::REPEAT,Sampler::REPEAT);
+ sampler.SetAffectsTransparency(false);
+
+ mMaterial.AddSampler( sampler );
+ }
+ }
+
+ if( (mTexture1Url != "") && (mIlluminationType == Toolkit::Model3dView::DIFFUSE_WITH_NORMAL_MAP) )
+ {
+ std::string imgUrl = mImagesUrl + mTexture1Url;
+
+ //Load textures
+ Image tex1 = ResourceImage::New( imgUrl );
+ if (tex1)
+ {
+ Sampler sampler = Sampler::New( tex1, "sNormal" );
+ sampler.SetWrapMode(Sampler::REPEAT,Sampler::REPEAT);
+ sampler.SetAffectsTransparency(false);
+ sampler.SetFilterMode(Sampler::LINEAR,Sampler::LINEAR);
+
+ mMaterial.AddSampler( sampler );
+ }
+ }
+
+ if( (mTexture2Url != "") && (mIlluminationType == Toolkit::Model3dView::DIFFUSE_WITH_NORMAL_MAP) )
+ {
+ std::string imgUrl = mImagesUrl + mTexture2Url;
+
+ //Load textures
+ Image tex2 = ResourceImage::New( imgUrl );
+ if( tex2 )
+ {
+ Sampler sampler = Sampler::New( tex2, "sGloss" );
+ sampler.SetWrapMode(Sampler::REPEAT,Sampler::REPEAT);
+ sampler.SetAffectsTransparency(false);
+ sampler.SetFilterMode(Sampler::LINEAR,Sampler::LINEAR);
+
+ mMaterial.AddSampler( sampler );
+ }
+ }
+}
+
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_INTERNAL_MODEL3D_VIEW_H__
+#define __DALI_TOOLKIT_INTERNAL_MODEL3D_VIEW_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/rendering/renderer.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/control-impl.h>
+#include <dali-toolkit/public-api/controls/model3d-view/model3d-view.h>
+#include <dali-toolkit/internal/controls/model3d-view/obj-loader.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+class Model3dView;
+
+namespace Internal
+{
+/**
+ * @brief Impl class for Model3dView.
+ *
+ * All the geometry loaded with the control is automatically centered and scaled to fit
+ * the size of all the other controls. So the max is (0.5,0.5) and the min is (-0.5,-0.5)
+*/
+class Model3dView : public Control
+{
+public:
+
+ /**
+ * @brief Create a new Model3dView.
+ *
+ * @return A public handle to the newly allocated Model3dView.
+ */
+ static Toolkit::Model3dView New();
+
+ // Properties
+
+ /**
+ * @brief Called when a property of an object of this type is set.
+ *
+ * @param[in] object The object whose property is set.
+ * @param[in] index The property index.
+ * @param[in] value The new property value.
+ */
+ static void SetProperty( BaseObject* object, Property::Index index, const Property::Value& value );
+
+ /**
+ * @brief Called to retrieve a property of an object of this type.
+ *
+ * @param[in] object The object whose property is to be retrieved.
+ * @param[in] index The property index.
+ * @return The current value of the property.
+ */
+ static Property::Value GetProperty( BaseObject* object, Property::Index index );
+
+ /**
+ * @copydoc Control::OnRelayout
+ */
+ virtual void OnRelayout( const Vector2& size, RelayoutContainer& container );
+
+ /**
+ * @brief Called to load both geometry (.obj) and material (.mtl) files
+ *
+ */
+ void Load();
+
+protected:
+
+ /**
+ * @brief Construct a new Model3dView.
+ */
+ Model3dView();
+
+ /**
+ * A reference counted object may only be deleted by calling Unreference()
+ */
+ virtual ~Model3dView();
+
+private:
+
+ /**
+ * @copydoc Toolkit::Control::OnInitialize()
+ */
+ virtual void OnInitialize();
+
+ /**
+ * @copydoc CustomActorImpl::OnStageConnection()
+ */
+ virtual void OnStageConnection( int depth );
+
+private:
+
+ /**
+ * @brief Load geometry (.obj) from file
+ */
+ void LoadGeometry();
+
+ /**
+ * @brief Load material (.mtl) from file
+ */
+ void LoadMaterial();
+
+ /**
+ * @brief Create Geometry class from the loaded geometry
+ */
+ void CreateGeometry();
+
+ /**
+ * @brief Create Material and Shader classes from the loaded material
+ */
+ void CreateMaterial();
+
+ /**
+ * @brief Load samplers and add them to Material
+ */
+ void LoadTextures();
+
+ /**
+ * @brief Set matrix to shader to orientate geometry
+ */
+ void UpdateView();
+
+ /**
+ * @brief Update shader uniforms
+ */
+ void UpdateShaderUniforms();
+
+
+ ObjLoader mObjLoader;
+
+ //Properties
+ std::string mObjUrl;
+ std::string mMaterialUrl;
+ std::string mImagesUrl;
+ std::string mTexture0Url;
+ std::string mTexture1Url;
+ std::string mTexture2Url;
+ Vector3 mLightPosition;
+ float mCameraFOV;
+ Toolkit::Model3dView::IlluminationType mIlluminationType;
+
+ //Size
+ Vector2 mControlSize;
+ Vector3 mSceneCenter;
+ Vector3 mSceneSize;
+
+ //Render members
+ Shader mShader;
+ Material mMaterial;
+ Geometry mMesh;
+ Renderer mRenderer;
+};
+
+} // namespace Internal
+
+// Helpers for public-api forwarding methods
+inline Toolkit::Internal::Model3dView& GetImpl( Toolkit::Model3dView& obj )
+{
+ DALI_ASSERT_ALWAYS(obj);
+ Dali::RefObject& handle = obj.GetImplementation();
+ return static_cast<Toolkit::Internal::Model3dView&>(handle);
+}
+
+inline const Toolkit::Internal::Model3dView& GetImpl( const Toolkit::Model3dView& obj )
+{
+ DALI_ASSERT_ALWAYS(obj);
+ const Dali::RefObject& handle = obj.GetImplementation();
+ return static_cast<const Toolkit::Internal::Model3dView&>(handle);
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_INTERNAL_MODEL_VIEW_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include "obj-loader.h"
+
+// EXTERNAL INCLUDES
+#include <string>
+#include <sstream>
+#include <string.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+using namespace Dali;
+
+ObjLoader::ObjLoader()
+{
+ mSceneLoaded = false;
+ mMaterialLoaded = false;
+ mSceneAABB.Init();
+}
+
+ObjLoader::~ObjLoader()
+{
+ ClearArrays();
+}
+
+bool ObjLoader::IsSceneLoaded()
+{
+ return mSceneLoaded;
+}
+
+bool ObjLoader::IsMaterialLoaded()
+{
+ return mMaterialLoaded;
+}
+
+//TODO: Use a function that can generate more than one normal/tangent per vertex (using angle)
+void ObjLoader::CalculateTangentArray(const Dali::Vector<Vector3>& vertex,
+ const Dali::Vector<Vector2>& texcoord,
+ Dali::Vector<TriIndex>& triangle,
+ Dali::Vector<Vector3>& normal,
+ Dali::Vector<Vector3>& tangent)
+{
+ normal.Clear();
+ normal.Resize(vertex.Size());
+
+ Vector3 *tan1 = new Vector3[vertex.Size() * 2];
+
+ memset(tan1, 0, normal.Size() * sizeof(Vector3) * 2);
+ memset(&normal[0], 0, normal.Size() * sizeof(Vector3) * 2);
+
+ for (unsigned long a = 0; a < triangle.Size(); a++)
+ {
+ Vector3 Tangent, Bitangent, Normal;
+
+ const Vector3& v0 = vertex[triangle[a].pntIndex[0]];
+ const Vector3& v1 = vertex[triangle[a].pntIndex[1]];
+ const Vector3& v2 = vertex[triangle[a].pntIndex[2]];
+
+ Vector3 Edge1 = v1 - v0;
+ Vector3 Edge2 = v2 - v0;
+
+ Normal = Edge1.Cross(Edge2);
+
+ const Vector2& w0 = texcoord[triangle[a].texIndex[0]];
+ const Vector2& w1 = texcoord[triangle[a].texIndex[1]];
+ const Vector2& w2 = texcoord[triangle[a].texIndex[2]];
+
+ float DeltaU1 = w1.x - w0.x;
+ float DeltaV1 = w1.y - w0.y;
+ float DeltaU2 = w2.x - w0.x;
+ float DeltaV2 = w2.y - w0.y;
+
+ float f = 1.0f / (DeltaU1 * DeltaV2 - DeltaU2 * DeltaV1);
+
+ Tangent.x = f * (DeltaV2 * Edge1.x - DeltaV1 * Edge2.x);
+ Tangent.y = f * (DeltaV2 * Edge1.y - DeltaV1 * Edge2.y);
+ Tangent.z = f * (DeltaV2 * Edge1.z - DeltaV1 * Edge2.z);
+
+ tan1[triangle[a].pntIndex[0]] += Tangent;
+ tan1[triangle[a].pntIndex[1]] += Tangent;
+ tan1[triangle[a].pntIndex[2]] += Tangent;
+
+ normal[triangle[a].pntIndex[0]] += Normal;
+ normal[triangle[a].pntIndex[1]] += Normal;
+ normal[triangle[a].pntIndex[2]] += Normal;
+ }
+
+ for (unsigned long a = 0; a < triangle.Size(); a++)
+ {
+ for (unsigned long j = 0; j < 3; j++)
+ {
+ triangle[a].nrmIndex[j] = triangle[a].pntIndex[j];
+ }
+ }
+
+ for (unsigned long a = 0; a < normal.Size(); a++)
+ {
+ normal[a].Normalize();
+
+ const Vector3& n = normal[a];
+ const Vector3& t = tan1[a];
+
+ // Gram-Schmidt orthogonalize
+ Vector3 calc = t - n * n.Dot(t);
+ calc.Normalize();
+ tangent[a] = Vector3(calc.x,calc.y,calc.z);
+ }
+
+ delete[] tan1;
+}
+
+
+void ObjLoader::CenterAndScale(bool center, Dali::Vector<Vector3>& points)
+{
+ BoundingVolume newAABB;
+
+ Vector3 sceneSize = GetSize();
+
+ float biggestDimension = sceneSize.x;
+ if( sceneSize.y > biggestDimension )
+ {
+ biggestDimension = sceneSize.y;
+ }
+ if( sceneSize.z > biggestDimension )
+ {
+ biggestDimension = sceneSize.z;
+ }
+
+
+ newAABB.Init();
+ for( unsigned int ui = 0; ui < points.Size(); ++ui)
+ {
+ points[ui] = points[ui] - GetCenter();
+ points[ui] = points[ui] / biggestDimension;
+ newAABB.ConsiderNewPointInVolume(points[ui]);
+ }
+
+ mSceneAABB = newAABB;
+}
+
+void ObjLoader::CreateGeometryArray(Dali::Vector<Vertex> & vertices,
+ Dali::Vector<Vector2> & textures,
+ Dali::Vector<VertexExt> & verticesExt,
+ Dali::Vector<int> & indices)
+{
+ //If we don't have tangents, calculate them
+ //we need to recalculate the normals too, because we need just one normal,tangent, bitangent per vertex
+ //TODO: Use a better function to calculate tangents
+ if( mTangents.Size() == 0 )
+ {
+ mTangents.Resize(mNormals.Size());
+ mBiTangents.Resize(mNormals.Size());
+ CalculateTangentArray(mPoints, mTextures, mTriangles, mNormals, mTangents);
+ for (unsigned int ui = 0 ; ui < mNormals.Size() ; ++ui )
+ {
+ mBiTangents[ui] = mNormals[ui].Cross(mTangents[ui]);
+ }
+ }
+
+ //Check the number of points textures and normals
+ if ((mPoints.Size() == mTextures.Size()) && (mTextures.Size() == mNormals.Size()))
+ {
+ //We create the vertices array. For now we just copy points info
+ for (unsigned int ui = 0 ; ui < mPoints.Size() ; ++ui )
+ {
+ Vertex vertex;
+ vertex.position = mPoints[ui];
+ vertices.PushBack(vertex);
+
+ textures.PushBack(Vector2());
+ verticesExt.PushBack(VertexExt());
+ }
+
+ //We copy the indices
+ for (unsigned int ui = 0 ; ui < mTriangles.Size() ; ++ui )
+ {
+ for (int j = 0 ; j < 3 ; ++j)
+ {
+ indices.PushBack(mTriangles[ui].pntIndex[j]);
+
+ vertices[mTriangles[ui].pntIndex[j]].normal = mNormals[mTriangles[ui].nrmIndex[j]];
+
+ textures[mTriangles[ui].pntIndex[j]] = mTextures[mTriangles[ui].texIndex[j]];
+
+ verticesExt[mTriangles[ui].pntIndex[j]].tangent = mTangents[mTriangles[ui].nrmIndex[j]];
+ verticesExt[mTriangles[ui].pntIndex[j]].bitangent = mBiTangents[mTriangles[ui].nrmIndex[j]];
+ }
+ }
+ }
+ else
+ {
+ //We have to normalize the arrays so we can draw we just one index array
+ for (unsigned int ui = 0 ; ui < mTriangles.Size() ; ++ui )
+ {
+ for (int j = 0 ; j < 3 ; ++j)
+ {
+ Vertex vertex;
+ vertex.position = mPoints[mTriangles[ui].pntIndex[j]];
+ vertex.normal = mNormals[mTriangles[ui].nrmIndex[j]];
+ vertices.PushBack(vertex);
+
+ textures.PushBack(mTextures[mTriangles[ui].texIndex[j]]);
+
+ VertexExt vertexExt;
+ vertexExt.tangent = mTangents[mTriangles[ui].nrmIndex[j]];
+ vertexExt.bitangent = mBiTangents[mTriangles[ui].nrmIndex[j]];
+ verticesExt.PushBack(vertexExt);
+ }
+ }
+ }
+}
+
+bool ObjLoader::Load(char* objBuffer, std::streampos fileSize, std::string& materialFile)
+{
+ Vector3 point;
+ Vector2 texture;
+ std::string vet[4], name;
+ int ptIdx[4];
+ int nrmIdx[4];
+ int texIdx[4];
+ TriIndex triangle,triangle2;
+ int pntAcum = 0, texAcum = 0, nrmAcum = 0;
+ bool iniObj = false;
+ int face = 0;
+
+ //Init AABB for the file
+ mSceneAABB.Init();
+
+ std::string strMatActual;
+
+ std::string input = objBuffer;
+ std::istringstream ss(input);
+ ss.imbue(std::locale("C"));
+
+
+ std::string line;
+ std::getline(ss, line);
+
+ while (std::getline(ss, line))
+ {
+ std::istringstream isline(line, std::istringstream::in);
+ std::string tag;
+
+ isline >> tag;
+
+ if (tag == "v")
+ {
+ //Two different objects in the same file
+ isline >> point.x;
+ isline >> point.y;
+ isline >> point.z;
+ mPoints.PushBack(point);
+
+ mSceneAABB.ConsiderNewPointInVolume(point);
+ }
+ else if (tag == "vn")
+ {
+ isline >> point.x;
+ isline >> point.y;
+ isline >> point.z;
+
+ mNormals.PushBack(point);
+ }
+ else if (tag == "#_#tangent")
+ {
+ isline >> point.x;
+ isline >> point.y;
+ isline >> point.z;
+
+ mTangents.PushBack(point);
+ }
+ else if (tag == "#_#binormal")
+ {
+ isline >> point.x;
+ isline >> point.y;
+ isline >> point.z;
+
+ mBiTangents.PushBack(point);
+ }
+ else if (tag == "vt")
+ {
+ isline >> texture.x;
+ isline >> texture.y;
+
+ texture.y = 1.0-texture.y;
+ mTextures.PushBack(texture);
+ }
+ else if (tag == "#_#vt1")
+ {
+ isline >> texture.x;
+ isline >> texture.y;
+
+ texture.y = 1.0-texture.y;
+ mTextures2.PushBack(texture);
+ }
+ else if (tag == "s")
+ {
+ }
+ else if (tag == "f")
+ {
+ if (!iniObj)
+ {
+ //name assign
+
+ iniObj = true;
+ }
+
+ int numIndices = 0;
+ while( isline >> vet[numIndices] )
+ {
+ numIndices++;
+ }
+
+ char separator;
+ char separator2;
+ //File could not have texture Coordinates
+ if (strstr(vet[0].c_str(),"//"))
+ {
+ for( int i = 0 ; i < numIndices; i++)
+ {
+ std::istringstream isindex(vet[i]);
+ isindex >> ptIdx[i] >> separator >> nrmIdx[i];
+ texIdx[i] = 0;
+ }
+ }
+ else if (strstr(vet[0].c_str(),"/"))
+ {
+ for( int i = 0 ; i < numIndices; i++)
+ {
+ std::istringstream isindex(vet[i]);
+ isindex >> ptIdx[i] >> separator >> texIdx[i] >> separator2 >> nrmIdx[i];
+ }
+ }
+ else
+ {
+ for( int i = 0 ; i < numIndices; i++)
+ {
+ std::istringstream isindex(vet[i]);
+ isindex >> ptIdx[i];
+ texIdx[i] = 0;
+ nrmIdx[i] = 0;
+ }
+ }
+
+ //If it is a triangle
+ if( numIndices == 3 )
+ {
+ for( int i = 0 ; i < 3; i++)
+ {
+ triangle.pntIndex[i] = ptIdx[i] - 1 - pntAcum;
+ triangle.nrmIndex[i] = nrmIdx[i] - 1 - nrmAcum;
+ triangle.texIndex[i] = texIdx[i] - 1 - texAcum;
+ }
+ mTriangles.PushBack(triangle);
+ face++;
+ }
+ //If on the other hand it is a quad, we will create two triangles
+ else if( numIndices == 4 )
+ {
+ for( int i = 0 ; i < 3; i++)
+ {
+ triangle.pntIndex[i] = ptIdx[i] - 1 - pntAcum;
+ triangle.nrmIndex[i] = nrmIdx[i] - 1 - nrmAcum;
+ triangle.texIndex[i] = texIdx[i] - 1 - texAcum;
+ }
+ mTriangles.PushBack(triangle);
+ face++;
+
+ for( int i = 0 ; i < 3; i++)
+ {
+ int idx = (i+2) % numIndices;
+ triangle2.pntIndex[i] = ptIdx[idx] - 1 - pntAcum;
+ triangle2.nrmIndex[i] = nrmIdx[idx] - 1 - nrmAcum;
+ triangle2.texIndex[i] = texIdx[idx] - 1 - texAcum;
+ }
+ mTriangles.PushBack(triangle2);
+ face++;
+ }
+ }
+ else if (tag == "usemtl")
+ {
+ isline >> strMatActual;
+ }
+ else if (tag == "mtllib")
+ {
+ isline >> strMatActual;
+ }
+ else if (tag == "g")
+ {
+ isline >> name;
+ }
+ else
+ {
+ }
+ }
+
+ if (iniObj)
+ {
+ pntAcum += (int)mPoints.Size();
+ texAcum += (int)mTextures.Size();
+ nrmAcum += (int)mNormals.Size();
+
+ CenterAndScale(true, mPoints);
+
+ face = 0;
+
+ mSceneLoaded = true;
+
+ return true;
+ }
+
+ return false;
+
+}
+
+void ObjLoader::LoadMaterial(char* objBuffer, std::streampos fileSize, std::string& texture0Url, std::string& texture1Url, std::string& texture2Url)
+{
+ float fR,fG,fB;
+
+ std::string info;
+
+ std::string input = objBuffer;
+ std::istringstream ss(input);
+ ss.imbue(std::locale("C"));
+
+ std::string line;
+ std::getline(ss, line);
+
+ while (std::getline(ss, line))
+ {
+ std::istringstream isline(line, std::istringstream::in);
+ std::string tag;
+
+ isline >> tag;
+
+ if (tag == "newmtl") //name of the material
+ {
+ isline >> info;
+ }
+ else if (tag == "Kd") //diffuse color
+ {
+ isline >> fR >> fG >> fB;
+ }
+ else if (tag == "Kd") //Ambient color
+ {
+ isline >> fR >> fG >> fB;
+ }
+ else if (tag == "Tf") //color
+ {
+ }
+ else if (tag == "Ni")
+ {
+ }
+ else if (tag == "map_Kd")
+ {
+ isline >> info;
+ texture0Url = info;
+ }
+ else if (tag == "bump")
+ {
+ isline >> info;
+ texture1Url = info;
+ }
+ else if (tag == "map_Ks")
+ {
+ isline >> info;
+ texture2Url = info;
+ }
+ }
+
+ mMaterialLoaded = true;
+}
+
+Geometry ObjLoader::CreateGeometry(Toolkit::Model3dView::IlluminationType illuminationType)
+{
+ Dali::Vector<Vertex> vertices;
+ Dali::Vector<Vector2> textures;
+ Dali::Vector<VertexExt> verticesExt;
+ Dali::Vector<int> indices;
+
+ CreateGeometryArray(vertices, textures, verticesExt, indices);
+
+ //All vertices need at least Position and Normal
+ Property::Map vertexFormat;
+ vertexFormat["aPosition"] = Property::VECTOR3;
+ vertexFormat["aNormal"] = Property::VECTOR3;
+ PropertyBuffer surfaceVertices = PropertyBuffer::New( vertexFormat, vertices.Size() );
+ surfaceVertices.SetData( &vertices[0] );
+
+ Geometry surface = Geometry::New();
+ surface.AddVertexBuffer( surfaceVertices );
+
+ //Some need texture coordinates
+ if( (illuminationType == Toolkit::Model3dView::DIFFUSE_WITH_NORMAL_MAP ) || (illuminationType == Toolkit::Model3dView::DIFFUSE_WITH_TEXTURE ) )
+ {
+ Property::Map textureFormat;
+ textureFormat["aTexCoord"] = Property::VECTOR2;
+ PropertyBuffer extraVertices = PropertyBuffer::New( textureFormat, textures.Size() );
+ extraVertices.SetData( &textures[0] );
+
+ surface.AddVertexBuffer( extraVertices );
+ }
+
+ //Some need tangent and bitangent
+ if( illuminationType == Toolkit::Model3dView::DIFFUSE_WITH_NORMAL_MAP )
+ {
+ Property::Map vertexExtFormat;
+ vertexExtFormat["aTangent"] = Property::VECTOR3;
+ vertexExtFormat["aBiNormal"] = Property::VECTOR3;
+ PropertyBuffer extraVertices = PropertyBuffer::New( vertexExtFormat, verticesExt.Size() );
+ extraVertices.SetData( &verticesExt[0] );
+
+ surface.AddVertexBuffer( extraVertices );
+ }
+
+ if (indices.Size())
+ {
+ //Indices
+ Property::Map indicesVertexFormat;
+ indicesVertexFormat["aIndices"] = Property::INTEGER;
+ PropertyBuffer indicesToVertices = PropertyBuffer::New( indicesVertexFormat, indices.Size() );
+ indicesToVertices.SetData(&indices[0]);
+
+ surface.SetIndexBuffer ( indicesToVertices );
+ }
+
+ surface.SetRequiresDepthTesting(true);
+ //surface.SetProperty(Geometry::Property::GEOMETRY_HALF_EXTENTS, GetSize() * 0.5);
+
+ vertices.Clear();
+ verticesExt.Clear();
+ indices.Clear();
+
+ return surface;
+}
+
+Vector3 ObjLoader::GetCenter()
+{
+ Vector3 center = GetSize() * 0.5 + mSceneAABB.pointMin;
+ return center;
+}
+
+Vector3 ObjLoader::GetSize()
+{
+ Vector3 size = mSceneAABB.pointMax - mSceneAABB.pointMin;
+ return size;
+}
+
+void ObjLoader::ClearArrays()
+{
+ mPoints.Clear();
+ mTextures.Clear();
+ mNormals.Clear();
+ mTangents.Clear();
+ mBiTangents.Clear();
+
+ mTriangles.Clear();
+
+ mSceneLoaded = false;
+}
+
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_INTERNAL_OBJ_LOADER_H__
+#define __DALI_TOOLKIT_INTERNAL_OBJ_LOADER_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/rendering/renderer.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/model3d-view/model3d-view.h>
+
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+class ObjLoader;
+
+namespace Internal
+{
+class ObjLoader
+{
+public:
+
+ struct TriIndex
+ {
+ int pntIndex[3];
+ int nrmIndex[3];
+ int texIndex[3];
+ };
+
+ struct Vertex
+ {
+ Vertex()
+ {}
+
+ Vertex( const Vector3& position, const Vector3& normal, const Vector2& textureCoord )
+ : position( position ), normal( normal )
+ {}
+
+ Vector3 position;
+ Vector3 normal;
+ };
+
+ struct VertexExt
+ {
+ VertexExt()
+ {}
+
+ VertexExt( const Vector3& tangent, const Vector3& binormal )
+ : tangent( tangent), bitangent (binormal)
+ {}
+
+ Vector3 tangent;
+ Vector3 bitangent;
+ };
+
+ struct BoundingVolume
+ {
+ void Init()
+ {
+ pointMin = Vector3(999999.9,999999.9,999999.9);
+ pointMax = Vector3(-999999.9,-999999.9,-999999.9);
+ }
+
+ void ConsiderNewPointInVolume(const Vector3& position)
+ {
+ pointMin.x = std::min(position.x, pointMin.x);
+ pointMin.y = std::min(position.y, pointMin.y);
+ pointMin.z = std::min(position.z, pointMin.z);
+
+ pointMax.x = std::max(position.x, pointMax.x);
+ pointMax.y = std::max(position.y, pointMax.y);
+ pointMax.z = std::max(position.z, pointMax.z);
+ }
+
+ Vector3 pointMin;
+ Vector3 pointMax;
+ };
+
+ ObjLoader();
+ virtual ~ObjLoader();
+
+ bool IsSceneLoaded();
+ bool IsMaterialLoaded();
+
+ bool Load(char* objBuffer, std::streampos fileSize, std::string& materialFile);
+
+ void LoadMaterial(char* objBuffer, std::streampos fileSize, std::string& texture0Url, std::string& texture1Url, std::string& texture2Url);
+
+ Geometry CreateGeometry(Toolkit::Model3dView::IlluminationType illuminationType);
+
+ Vector3 GetCenter();
+ Vector3 GetSize();
+
+ void ClearArrays();
+
+private:
+
+ BoundingVolume mSceneAABB;
+
+ bool mSceneLoaded;
+ bool mMaterialLoaded;
+
+ Dali::Vector<Vector3> mPoints;
+ Dali::Vector<Vector2> mTextures;
+ Dali::Vector<Vector2> mTextures2;
+ Dali::Vector<Vector3> mNormals;
+ Dali::Vector<Vector3> mTangents;
+ Dali::Vector<Vector3> mBiTangents;
+ Dali::Vector<TriIndex> mTriangles;
+
+ void CalculateTangentArray(const Dali::Vector<Vector3>& vertex,
+ const Dali::Vector<Vector2>& texcoord,
+ Dali::Vector<TriIndex>& triangle,
+ Dali::Vector<Vector3>& normal,
+ Dali::Vector<Vector3>& tangent);
+
+ void CenterAndScale(bool center, Dali::Vector<Vector3>& points);
+
+
+ void CreateGeometryArray(Dali::Vector<Vertex> & vertices,
+ Dali::Vector<Vector2> & textures,
+ Dali::Vector<VertexExt> & verticesExt,
+ Dali::Vector<int> & indices);
+
+};
+
+
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+
+
+
+#endif // __DALI_TOOLKIT_INTERNAL_OBJ_LOADER_H__
$(toolkit_src_dir)/controls/image-view/image-view-impl.cpp \
$(toolkit_src_dir)/controls/magnifier/magnifier-impl.cpp \
$(toolkit_src_dir)/controls/popup/confirmation-popup-impl.cpp \
+ $(toolkit_src_dir)/controls/model3d-view/model3d-view-impl.cpp \
+ $(toolkit_src_dir)/controls/model3d-view/obj-loader.cpp \
$(toolkit_src_dir)/controls/popup/popup-impl.cpp \
$(toolkit_src_dir)/controls/page-turn-view/page-turn-portrait-view-impl.cpp \
$(toolkit_src_dir)/controls/page-turn-view/page-turn-effect.cpp \
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+
+#include <dali-toolkit/public-api/controls/model3d-view/model3d-view.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/model3d-view/model3d-view-impl.h>
+
+// EXTERNAL INCLUDES
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+Model3dView::Model3dView()
+{}
+
+Model3dView::Model3dView( const Model3dView& model3dView )
+: Control( model3dView )
+{
+}
+
+Model3dView& Model3dView::operator=( const Model3dView& model3dView )
+{
+ if( &model3dView != this )
+ {
+ Control::operator=( model3dView );
+ }
+ return *this;
+}
+
+Model3dView::~Model3dView()
+{
+}
+
+Model3dView Model3dView::New()
+{
+ return Internal::Model3dView::New();
+}
+
+Model3dView Model3dView::New( const std::string& objUrl, const std::string& mtlUrl, const std::string& imagesUrl )
+{
+ Model3dView model3dView = Internal::Model3dView::New();
+ model3dView.SetProperty( Model3dView::Property::GEOMETRY_URL, Dali::Property::Value( objUrl ) );
+ model3dView.SetProperty( Model3dView::Property::MATERIAL_URL, Dali::Property::Value( mtlUrl ) );
+ model3dView.SetProperty( Model3dView::Property::IMAGES_URL, Dali::Property::Value( imagesUrl ) );
+
+ return model3dView;
+}
+
+Model3dView Model3dView::DownCast( BaseHandle handle )
+{
+ return Control::DownCast<Model3dView, Internal::Model3dView>(handle);
+}
+
+Model3dView::Model3dView( Internal::Model3dView& implementation )
+ : Control( implementation )
+{
+}
+
+Model3dView::Model3dView( Dali::Internal::CustomActor* internal )
+ : Control( internal )
+{
+ VerifyCustomActorPointer<Internal::Model3dView>( internal );
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_MODEL3D_VIEW_H__
+#define __DALI_TOOLKIT_MODEL3D_VIEW_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/control.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal DALI_INTERNAL
+{
+class Model3dView;
+}
+/**
+ * @brief Model3dView is a control for displaying 3d geometry.
+ *
+ * All the geometry loaded with the control is automatically centered and scaled to fit
+ * the size of all the other controls. So the max is (0.5,0.5) and the min is (-0.5,-0.5)
+*/
+class DALI_IMPORT_API Model3dView : public Control
+{
+public:
+
+ /**
+ * @brief The start and end property ranges for this control.
+ */
+ enum PropertyRange
+ {
+ PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1,
+ PROPERTY_END_INDEX = PROPERTY_START_INDEX + 1000, ///< Reserve property indices
+
+ ANIMATABLE_PROPERTY_START_INDEX = ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX,
+ ANIMATABLE_PROPERTY_END_INDEX = ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX + 1000 ///< Reserve animatable property indices
+ };
+
+ /**
+ * @brief An enumeration of properties belonging to the TextLabel class.
+ */
+ struct Property
+ {
+ enum
+ {
+ GEOMETRY_URL = PROPERTY_START_INDEX, ///< name "geometry-url", The path to the geometry file, type STRING
+ MATERIAL_URL, ///< name "material-url", The path to the material file, type STRING
+ IMAGES_URL, ///< name "images-url", The path to the images directory, type STRING
+ ILLUMINATION_TYPE, ///< name "illumination-type", The type of illumination, type INTEGER
+ TEXTURE0_URL, ///< name "texture0-url", The path to first texture, type STRING
+ TEXTURE1_URL, ///< name "texture1-url", The path to second texture, type STRING
+ TEXTURE2_URL, ///< name "texture2-url", The path to third texture, type STRING
+
+ LIGHT_POSITION = ANIMATABLE_PROPERTY_START_INDEX ///< name "light-position", The coordinates of the light, type Vector3
+ };
+ };
+
+ enum IlluminationType
+ {
+ DIFFUSE,
+ DIFFUSE_WITH_TEXTURE,
+ DIFFUSE_WITH_NORMAL_MAP
+ };
+
+
+ /**
+ * @brief Create a new instance of a Model3dView control.
+ *
+ * @return A handle to the new Model3dView control.
+ */
+ static Model3dView New();
+
+ /**
+ * @brief Create a new instance of a Model3dView control.
+ *
+ * @return A handle to the new Model3dView control.
+ */
+ static Model3dView New( const std::string& objUrl, const std::string& mtlUrl, const std::string& imagesUrl );
+
+
+ /**
+ * @brief Create an uninitialized Model3dView
+ *
+ * Only derived versions can be instantiated. Calling member
+ * functions with an uninitialized Dali::Object is not allowed.
+ */
+ Model3dView();
+
+ /**
+ * @brief Destructor
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ */
+ ~Model3dView();
+
+ /**
+ * @brief Copy constructor.
+ */
+ Model3dView( const Model3dView& model3dView );
+
+ /**
+ * @brief Assignment operator.
+ */
+ Model3dView& operator=( const Model3dView& model3dView );
+
+ /**
+ * @brief Downcast an Object handle to Model3dView.
+ *
+ * If handle points to a Model3dView the downcast produces valid
+ * handle. If not the returned handle is left uninitialized.
+ *
+ * @param[in] handle Handle to an object
+ * @return handle to a Model3dView or an uninitialized handle
+ */
+ static Model3dView DownCast( BaseHandle handle );
+
+public: // Not intended for application developers
+
+ /**
+ * @brief Creates a handle using the Toolkit::Internal implementation.
+ *
+ * @param[in] implementation The Control implementation.
+ */
+ DALI_INTERNAL Model3dView( Internal::Model3dView& implementation );
+
+ /**
+ * @brief Allows the creation of this Control from an Internal::CustomActor pointer.
+ *
+ * @param[in] internal A pointer to the internal CustomActor.
+ */
+ DALI_INTERNAL Model3dView( Dali::Internal::CustomActor* internal );
+
+};
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_MODEL3D_VIEW_H__
$(public_api_src_dir)/controls/buttons/radio-button.cpp \
$(public_api_src_dir)/controls/default-controls/solid-color-actor.cpp \
$(public_api_src_dir)/controls/image-view/image-view.cpp \
+ $(public_api_src_dir)/controls/model3d-view/model3d-view.cpp \
$(public_api_src_dir)/controls/scroll-bar/scroll-bar.cpp \
$(public_api_src_dir)/controls/scrollable/item-view/default-item-layout.cpp \
$(public_api_src_dir)/controls/scrollable/item-view/item-layout.cpp \
public_api_default_controls_header_files = \
$(public_api_src_dir)/controls/default-controls/solid-color-actor.h
+public_api_model3d_view_header_files = \
+ $(public_api_src_dir)/controls/model3d-view/model3d-view.h
+
public_api_gaussian_blur_view_header_files = \
$(public_api_src_dir)/controls/gaussian-blur-view/gaussian-blur-view.h