1 /*
2     Copyright (c) 2008-2009 NetAllied Systems GmbH
3 
4     This file is part of DAE2MA.
5 
6     Licensed under the MIT Open Source License,
7     for details please see LICENSE file or the website
8     http://www.opensource.org/licenses/mit-license.php
9 */
10 
11 #include "DAE2MAStableHeaders.h"
12 #include "DAE2MACameraImporter.h"
13 #include "DAE2MAVisualSceneImporter.h"
14 #include "DAE2MASyntax.h"
15 
16 #include "COLLADAFWCamera.h"
17 
18 #include <MayaDMCommands.h>
19 
20 
21 namespace DAE2MA
22 {
23 
24     const String CameraImporter::CAMERA_NAME = "camera";
25 
26 
27     //------------------------------
CameraImporter(DocumentImporter * documentImporter)28 	CameraImporter::CameraImporter ( DocumentImporter* documentImporter )
29         : BaseImporter ( documentImporter )
30 	{
31 	}
32 
33     //------------------------------
~CameraImporter()34 	CameraImporter::~CameraImporter()
35 	{
36         UniqueIdMayaNodeMap::iterator it = mMayaCameraNodesMap.begin ();
37         while ( it != mMayaCameraNodesMap.end () )
38         {
39             MayaNode* mayaNode = it->second;
40             delete mayaNode;
41             ++it;
42         }
43         mMayaCameraNodesMap.clear ();
44 	}
45 
46     //------------------------------
importCamera(const COLLADAFW::Camera * camera)47     void CameraImporter::importCamera ( const COLLADAFW::Camera* camera )
48     {
49         // Check if the camera is already imported.
50         const COLLADAFW::UniqueId& cameraId = camera->getUniqueId ();
51         if ( findMayaCameraNode ( cameraId ) != 0 ) return;
52 
53         // Get the transform nodes, which work with this camera instance.
54         VisualSceneImporter* visualSceneImporter = getDocumentImporter ()->getVisualSceneImporter ();
55         const UniqueIdVec* transformNodeIds = visualSceneImporter->findCameraTransformIds ( cameraId );
56         if ( transformNodeIds == 0 )
57         {
58             std::cerr << "No camera node which implements this camera!" << std::endl;
59             return;
60         }
61 
62         UniqueIdVec::const_iterator nodesIter = transformNodeIds->begin ();
63         while ( nodesIter != transformNodeIds->end () )
64         {
65             // Get the maya node of the current transform node.
66             const COLLADAFW::UniqueId& transformNodeId = *nodesIter;
67             MayaNodesList* mayaTransformNodes = visualSceneImporter->findMayaTransformNodes ( transformNodeId );
68             if ( mayaTransformNodes->size () == 0 )
69             {
70                 std::cerr << "The referenced transform node doesn't exist!" << std::endl;
71                 return;
72             }
73             MayaNode* mayaTransformNode = (*mayaTransformNodes) [0];
74             String transformNodeName = mayaTransformNode->getName ();
75 
76             // Get the path to the parent transform node.
77             String transformNodePath = mayaTransformNode->getNodePath ();
78 
79             // The first reference is a direct one, the others are instances.
80             if ( nodesIter == transformNodeIds->begin() )
81             {
82                 // Create the current mesh node.
83                 createCamera ( camera, mayaTransformNode );
84             }
85             else
86             {
87                 // Get the path to the mesh.
88                 MayaNode* mayaCameraNode = findMayaCameraNode ( cameraId );
89                 String cameraNodePath = mayaCameraNode->getNodePath ();
90 
91                 // parent -shape -noConnections -relative -addObject "|pCube1|pCubeShape1" "pCube2";
92                 FILE* file = getDocumentImporter ()->getFile ();
93                 MayaDM::parentShape ( file, cameraNodePath, transformNodePath, false, true, true, true );
94             }
95 
96             ++nodesIter;
97         }
98     }
99 
100     //------------------------------
createCamera(const COLLADAFW::Camera * camera,MayaNode * mayaTransformNode)101     void CameraImporter::createCamera (
102         const COLLADAFW::Camera* camera,
103         MayaNode* mayaTransformNode )
104     {
105         // Get the unique id.
106         const COLLADAFW::UniqueId& cameraId = camera->getUniqueId ();
107 
108         // Make the maya name unique and manage it in all necessary lists.
109         String cameraName = camera->getName ();
110         if ( cameraName.empty () ) cameraName = CAMERA_NAME;
111         cameraName = DocumentImporter::frameworkNameToMayaName ( cameraName );
112         const ExtraDataCallbackHandler& callbackHandler = getDocumentImporter ()->getMayaIdCallbackHandler ();
113         String originalMayaId = getOriginalMayaId ( callbackHandler, cameraId, COLLADASaxFWL15::HASH_ELEMENT_CAMERA );
114         if ( !originalMayaId.empty () ) cameraName = originalMayaId;
115         cameraName = generateUniqueDagNodeName ( cameraName, mayaTransformNode );
116 
117         // Create a maya node object of the current node and push it into the map.
118         MayaNode* mayaCameraNode = new MayaNode ( cameraId, cameraName, mayaTransformNode );
119         mMayaCameraNodesMap [ cameraId ] = mayaCameraNode;
120 
121         // Check if we want to write a shared default camera.
122         bool isSharedCamera = false;
123         if (   COLLADABU::Utils::equals ( camera->getName (), CAMERA_PERSP_SHAPE )
124             || COLLADABU::Utils::equals ( camera->getName (), CAMERA_TOP_SHAPE )
125             || COLLADABU::Utils::equals ( camera->getName (), CAMERA_FRONT_SHAPE )
126             || COLLADABU::Utils::equals ( camera->getName (), CAMERA_SIDE_SHAPE ) )
127         {
128             isSharedCamera = true;
129         }
130 
131         // Create the maya camera object and write it into the maya ascii file.
132         FILE* file = getDocumentImporter ()->getFile ();
133         MayaDM::Camera mayaCamera ( file, cameraName, mayaTransformNode->getNodePath (), isSharedCamera );
134 
135         // Add the original id attribute.
136         String colladaId = camera->getOriginalId ();
137         if ( !colladaId.empty () )
138         {
139             MayaDM::addAttr ( file, COLLADA_ID_ATTRIBUTE_NAME, ATTRIBUTE_DATA_TYPE, ATTRIBUTE_TYPE_STRING );
140             MayaDM::setAttr ( file, COLLADA_ID_ATTRIBUTE_NAME, ATTRIBUTE_TYPE, ATTRIBUTE_TYPE_STRING, colladaId );
141         }
142 //         // TODO Add the attributes for all the extra tags.
143 //         setExtraData ( camera->getExtraDataArray () );
144 
145         // Have a look, if there is a center of interest set by the transform's lookat matrix.
146         VisualSceneImporter* visualSceneImporter = getDocumentImporter ()->getVisualSceneImporter ();
147         double centerOfInterestDistance;
148         bool found = visualSceneImporter->findCenterOfInterestDistance ( mayaTransformNode->getUniqueId (), centerOfInterestDistance );
149         if ( found )
150         {
151             mayaCamera.setCenterOfInterest ( centerOfInterestDistance );
152         }
153 
154         // Write the data in depend on the camera type.
155         const COLLADAFW::Camera::CameraType& cameraType = camera->getCameraType ();
156         switch ( cameraType )
157         {
158         case COLLADAFW::Camera::ORTHOGRAPHIC:
159             setOrthographicCameraAttributes ( camera, mayaCameraNode, mayaCamera );
160             break;
161         case COLLADAFW::Camera::PERSPECTIVE:
162             setPerspectiveCameraAttributes ( camera, mayaCameraNode, mayaCamera );
163             break;
164         default:
165             std::cerr << "Unknown camera type!" << std::endl;
166             break;
167         }
168 
169     }
170 
171     //------------------------------
setPerspectiveCameraAttributes(const COLLADAFW::Camera * camera,MayaNode * mayaCameraNode,MayaDM::Camera & mayaCamera)172     void CameraImporter::setPerspectiveCameraAttributes (
173         const COLLADAFW::Camera* camera,
174         MayaNode* mayaCameraNode,
175         MayaDM::Camera& mayaCamera )
176     {
177         mayaCamera.setOrthographic ( false );
178 
179         double nearClipPlane = camera->getNearClippingPlane ();
180         nearClipPlane = toLinearUnit ( nearClipPlane );
181         mayaCamera.setNearClipPlane ( nearClipPlane );
182 
183         double farClipPlane = camera->getFarClippingPlane ();
184         farClipPlane = toLinearUnit ( farClipPlane );
185         mayaCamera.setFarClipPlane ( farClipPlane );
186 
187         FILE* file = getDocumentImporter ()->getFile ();
188 
189         const COLLADAFW::Camera::DescriptionType& description = camera->getDescriptionType ();
190         switch ( description )
191         {
192         case COLLADAFW::Camera::ASPECTRATIO_AND_X:
193             {
194                 double aspectRatio = camera->getAspectRatio ();
195                 MayaDM::editCameraAspectRatio ( file, mayaCameraNode->getNodePath (), aspectRatio );
196 
197                 double horizontalFieldOfView = camera->getXFov ();
198                 MayaDM::editCameraHorizontalFieldOfView ( file, mayaCameraNode->getNodePath (), horizontalFieldOfView );
199             }
200             break;
201         case COLLADAFW::Camera::ASPECTRATIO_AND_Y:
202             {
203                 double aspectRatio = camera->getAspectRatio ();
204                 MayaDM::editCameraAspectRatio ( file, mayaCameraNode->getNodePath (), aspectRatio );
205 
206                 double verticalFieldOfView = camera->getYFov ();
207                 MayaDM::editCameraVerticalFieldOfView ( file, mayaCameraNode->getNodePath (), verticalFieldOfView );
208             }
209             break;
210         case COLLADAFW::Camera::SINGLE_X:
211             {
212                 double aspectRatio = 1.0;
213                 MayaDM::editCameraAspectRatio ( file, mayaCameraNode->getNodePath (), aspectRatio );
214 
215                 double horizontalFieldOfView = camera->getXFov ();
216                 MayaDM::editCameraHorizontalFieldOfView ( file, mayaCameraNode->getNodePath (), horizontalFieldOfView );
217             }
218             break;
219         case COLLADAFW::Camera::SINGLE_Y:
220             {
221                 double aspectRatio = 1.0;
222                 MayaDM::editCameraAspectRatio ( file, mayaCameraNode->getNodePath (), aspectRatio );
223 
224                 double verticalFieldOfView = camera->getYFov ();
225                 MayaDM::editCameraVerticalFieldOfView ( file, mayaCameraNode->getNodePath (), verticalFieldOfView );
226             }
227             break;
228         case COLLADAFW::Camera::X_AND_Y:
229             {
230                 double aspectRatio = camera->getXFov () / camera->getYFov ();
231                 MayaDM::editCameraAspectRatio ( file, mayaCameraNode->getNodePath (), aspectRatio );
232 
233                 double horizontalFieldOfView = camera->getXFov ();
234                 MayaDM::editCameraHorizontalFieldOfView ( file, mayaCameraNode->getNodePath (), horizontalFieldOfView );
235 
236                 double verticalFieldOfView = camera->getYFov ();
237                 MayaDM::editCameraVerticalFieldOfView ( file, mayaCameraNode->getNodePath (), verticalFieldOfView );
238             }
239             break;
240         default:
241             std::cerr << "Unknown description type!" << std::endl;
242             break;
243         }
244 
245     }
246 
247     //------------------------------
setOrthographicCameraAttributes(const COLLADAFW::Camera * camera,MayaNode * mayaCameraNode,MayaDM::Camera & mayaCamera)248     void CameraImporter::setOrthographicCameraAttributes (
249         const COLLADAFW::Camera* camera,
250         MayaNode* mayaCameraNode,
251         MayaDM::Camera& mayaCamera )
252     {
253         mayaCamera.setOrthographic ( true );
254 
255         double nearClipPlane = camera->getNearClippingPlane ();
256         nearClipPlane = toLinearUnit ( nearClipPlane );
257         mayaCamera.setNearClipPlane ( nearClipPlane );
258 
259         double farClipPlane = camera->getFarClippingPlane ();
260         farClipPlane = toLinearUnit ( farClipPlane );
261         mayaCamera.setFarClipPlane ( farClipPlane );
262 
263         FILE* file = getDocumentImporter ()->getFile ();
264 
265         COLLADAFW::Camera::DescriptionType description = camera->getDescriptionType ();
266         switch ( description )
267         {
268         case COLLADAFW::Camera::ASPECTRATIO_AND_X:
269             {
270                 double aspectRatio = camera->getAspectRatio ();
271                 MayaDM::editCameraAspectRatio ( file, mayaCameraNode->getNodePath (), aspectRatio );
272 
273                 double orthographicWidth = camera->getXMag () * 2;
274                 MayaDM::editCameraOrthographicWidth ( file, mayaCameraNode->getNodePath (), orthographicWidth );
275             }
276             break;
277         case COLLADAFW::Camera::ASPECTRATIO_AND_Y:
278             {
279                 double aspectRatio = camera->getAspectRatio ();
280                 MayaDM::editCameraAspectRatio ( file, mayaCameraNode->getNodePath (), aspectRatio );
281 
282                 double orthographicHeight = camera->getYMag () * 2;
283                 MayaDM::editCameraOrthographicWidth ( file, mayaCameraNode->getNodePath (), orthographicHeight );
284             }
285             break;
286         case COLLADAFW::Camera::SINGLE_X:
287             {
288                 double orthographicWidth = camera->getXMag () * 2;
289                 MayaDM::editCameraOrthographicWidth ( file, mayaCameraNode->getNodePath (), orthographicWidth );
290             }
291             break;
292         case COLLADAFW::Camera::SINGLE_Y:
293             {
294                 double orthographicHeight = camera->getYMag () * 2;
295                 MayaDM::editCameraOrthographicWidth ( file, mayaCameraNode->getNodePath (), orthographicHeight );
296             }
297             break;
298         case COLLADAFW::Camera::X_AND_Y:
299             {
300                 double orthographicWidth = camera->getXMag () * 2;
301                 MayaDM::editCameraOrthographicWidth ( file, mayaCameraNode->getNodePath (), orthographicWidth );
302 
303 //                 double aspectRatio = camera->getXMag () / camera->getYMag ();
304 //                 MayaDM::editCameraAspectRatio ( file, mayaCameraNode->getNodePath (), aspectRatio );
305             }
306             break;
307         default:
308             std::cerr << "Unknown description type!" << std::endl;
309             break;
310         }
311 
312     }
313 
314     // --------------------------------------------
findMayaCameraNode(const COLLADAFW::UniqueId & cameraId)315     MayaNode* CameraImporter::findMayaCameraNode ( const COLLADAFW::UniqueId& cameraId )
316     {
317         UniqueIdMayaNodeMap::iterator it = mMayaCameraNodesMap.find ( cameraId );
318         if ( it != mMayaCameraNodesMap.end () )
319             return it->second;
320 
321         return 0;
322     }
323 
324 } // namespace DAE2MA
325