Jump to content
Sign in to follow this  
Kalina

Camera IO Translator

Recommended Posts

I want to create a plugin that allows me to import a camera path.

 

Specifically, the format of my external file is:

 

translationX_frame1, translationY_frame1, translationZ_frame1, rotationX_frame1, rotationY_frame1, rotationZ_frame1

translationX_frame2, translationY_frame2, translationZ_frame2, rotationX_frame2, rotationY_frame2, rotationZ_frame2

translationX_frame3, translationY_frame3, translationZ_frame3, rotationX_frame3, rotationY_frame3, rotationZ_frame3

...

 

I don't really know where to begin. It would make sense to me to be able to create a camera, just set the translation and rotation at each frame. Can I do this in the HDK?

Do I want to write a GEO_IOTranslator for this? If so, would I have to create a camera path somehow, or could I just create a camera? Would that be an OBJ_Camera?

 

I would really appreciate being pointed in the right direction, or some help to get a simple example working; e.g. creating a camera looking at (0,0,0) and moving it from (0,0,1) at frame 1 to (0,0,2) at frame 2.

 

Share this post


Link to post
Share on other sites
Guest mantragora

0. It sound like you are totally new to Houdini, so why going stright into HDK?

1. I would do this in Python.

2. If you insist, then you can implement custom GEO_IO_Translator, use it to read data into CHOPs and then export it to camera.

I think this is better and more universal than implementing your custom camera just to read data from you custom format.

Edited by mantragora

Share this post


Link to post
Share on other sites

it sounds like a job for CHOPS. try loading the file in CHOPS, and exporting the data to the translation and rotation channels of an existing camera. try searching this forum for .chan files...

Share this post


Link to post
Share on other sites

translationX_frame1, translationY_frame1, translationZ_frame1, rotationX_frame1, rotationY_frame1, rotationZ_frame1

translationX_frame2, translationY_frame2, translationZ_frame2, rotationX_frame2, rotationY_frame2, rotationZ_frame2

translationX_frame3, translationY_frame3, translationZ_frame3, rotationX_frame3, rotationY_frame3, rotationZ_frame3

I think it's classic chan file format. If it is, everything you need is FileCHOP + RenameCHOP + ReorderCHOP.

Good luck.

Share this post


Link to post
Share on other sites

It doesn't appear that I can use CHOPS. The file type is .wf, and trying to load it into a File CHOP in Houdini gives me "Unable to read file". http://www.sidefx.com/docs/houdini13.0/nodes/chop/file seems to confirm that this is not a valid file type.

 

Also, this .wf file format that I described is the simpler of two camera path file formats that I will need to be able to import, so I thought I would start working on just that one... But the other file type is .vd, and I would like to be able to read in both in a somewhat similar manner if possible (e.g. programmatically, via a plugin).

 

If you must know, the other format looks ilke this:

fps 30.00000000
keys 3
        0 :     1.02890467643737793     0.0280741788446903229   0.161896556615829468    -8.01320744 -3.913378 -78.6056137 0.00999999978 60
        15 :    1.02306999999999992     0.0306226999999998917   0.264749000000000012    -8.99072453 -14.2586266 -69.5562738 0.01        60
        32 :    1.01645994186401367     0.0335110984742641449   0.381316006183624268    -8.13035774 -26.0038414 -59.277462 0.00999999978        60

It's not frame-by-frame; here interpolation must be done between keys 0, 15, and 32.

Edited by Kalina

Share this post


Link to post
Share on other sites

It's probably easier to just write a python script that converts the data into an (ascii) .clip file which also looks similar (save out a test .clip file to see the format). Then you can just load it using a File CHOP and export it to whatever parameters you want. Or if you want it to be more integrated you can edit $HFS/houdini/CHOPio to use your python script.

 

GEO_IOTranslator won't work because its for geometry and what you have is channel data. For channel data, the equivalent is to write a CL_ClipReader subclass and register it with CL_ClipIO.

  • Like 1

Share this post


Link to post
Share on other sites

It's probably easier to just write a python script that converts the data into an (ascii) .clip file which also looks similar (save out a test .clip file to see the format). Then you can just load it using a File CHOP and export it to whatever parameters you want. Or if you want it to be more integrated you can edit $HFS/houdini/CHOPio to use your python script.

 

GEO_IOTranslator won't work because its for geometry and what you have is channel data. For channel data, the equivalent is to write a CL_ClipReader subclass and register it with CL_ClipIO.

 

Thank you thank you thank you THANK YOU!

A CL_ClipReader is what I want in the end, but I couldn't find any examples or information about this, so this will be complicated for a beginner like myself (any advice?). For now, I wrote a simple python wf-to-clip converter script and edited CHOPio, and it works beautifully.

  • Like 1

Share this post


Link to post
Share on other sites

It's probably not too complicated if you just look at the relevant header files. However, I would only try it if you're already experienced in C++ and running into performance issues. A simple python script like this is helluva easier to maintain.

Share this post


Link to post
Share on other sites
Guest mantragora

It's probably not too complicated if you just look at the relevant header files. However, I would only try it if you're already experienced in C++ and running into performance issues. A simple python script like this is helluva easier to maintain.

That's a good occasion to prepare some template if someone would like to follow this road in the future. For GEO_IO I have such a template, so all I have to do is CTRL+C/CTRL+V template *.h/*.cpp files, give them new names and I'm ready to fill in fileRead/fileSave methods + set new extesnion. Don't have to look into example files to try figure out how I should start with it.

I see that there are two virtual methods that we can override, but I can't figure out how to set custom extension and register it. There is some mention that they register themself by using registerClipReader()/registerClipWriter() but I still can't see how to set custom extension to test is it working.

I will start:

 

FileFormats_Common.h

/*
	This is a place where you should specify common for all file formats include files, 
	names that may be shared between more than one place or operator/selector.

	IMPORTANT! ------------------------------------------
	-----------------------------------------------------

	Author: Mantragora (2014)

*/
#pragma once

/* -----------------------------------------------------------------
INCLUDES
----------------------------------------------------------------- */
#include <CL/CL_ClipIO.h>

#include <ostream>
#include <iostream.h>

// -------------------------- using //
using std::cout;
using std::endl;

/* -----------------------------------------------------------------
CL_Template
----------------------------------------------------------------- */


CL_Template.h

/*
	Use this as a starting template for CL file format.

	IMPORTANT! ------------------------------------------
	-----------------------------------------------------

	Author: Mantragora (2014)

*/

#pragma once
#include "../FileFormat_Common.h"

namespace Mantragora
{
	namespace FileFormat
	{
		class CL_Template : public CL_ClipIO
		{
		public:
			CL_Template() {}
			
			virtual
			~CL_Template() {}

			virtual auto
			writeClip(const char* file_name, const CL_Clip& clip)
			-> bool;

			virtual auto
			readClip(const char* file_name, CL_Clip& clip)
			-> bool;
		};
	}
}
CL_Template.cpp

/*
	Use this as a starting template for CL file format.

	IMPORTANT! ------------------------------------------
	-----------------------------------------------------

	Author: Mantragora (2014)

*/

#include "CL_Template.h"
using namespace Mantragora::FileFormat;

auto
CL_Template::readClip(const char* file_name, CL_Clip& clip)
-> bool
{
    return true;
}

auto
CL_Template::writeClip(const char* file_name, const CL_Clip& clip)
-> bool
{
    return true;
}
Now what? :D

Is there some registerNewClip() function where I should call registerClipReader()/registerClipWriter() and pass to each new extension?

registerClipReader(const char* extension, CL_ClipReader& clip_reader)
registerClipWriter(const char* extension, CL_ClipWriter& clip_writer)
What should be passed as second argument to each of those methods? The same CL_Template class? Edited by mantragora

Share this post


Link to post
Share on other sites

From CL_ClipIO.h:

133 // These functions are called from shared objects/dll's to register readers
134 // and writers.
135 extern "C" {
136  SYS_VISIBILITY_EXPORT extern void CLregisterClipReader(void *);
137  SYS_VISIBILITY_EXPORT extern void CLregisterClipWriter(void *);
138 }
139

So, putting this together from reading CL_ClipIO.h, you have something like (untested):

void CLregisterClipReader(void *)
{
    static CL_Template clip_reader;
    CL_ClipIO::inst().registerClipReader(".wf", clip_reader);
}

Share this post


Link to post
Share on other sites
Guest mantragora

From CL_ClipIO.h:

133 // These functions are called from shared objects/dll's to register readers
134 // and writers.
135 extern "C" {
136  SYS_VISIBILITY_EXPORT extern void CLregisterClipReader(void *);
137  SYS_VISIBILITY_EXPORT extern void CLregisterClipWriter(void *);
138 }
139
So, putting this together from reading CL_ClipIO.h, you have something like (untested):

 

void CLregisterClipReader(void *)
{
    static CL_Template clip_reader;
    CL_ClipIO::inst().registerClipReader(".wf", clip_reader);
}

Thanks!

CL_ClipIO have private constructor, so we cannot inherit from it :D. So instead I inherit from CL_ClipReader/CL_ClipWriter. It seems to work.

Here is modified code:

FileFormat_Common.h

/*
	This is a place where you should specify common for all file formats include files, 
	names that may be shared between more than one place or operator/selector.

	IMPORTANT! ------------------------------------------
	-----------------------------------------------------

	Author: Mantragora (2014)

*/
#pragma once

/* -----------------------------------------------------------------
INCLUDES
----------------------------------------------------------------- */
#include <CL/CL_ClipIO.h>
#include <CL/CL_Clip.h>
#include <CL/CL_ClipReader.h>
#include <CL/CL_ClipWriter.h>

#include <ostream>
#include <iostream.h>

// -------------------------- using //
using std::cout;
using std::endl;

/* -----------------------------------------------------------------
CL_Template
----------------------------------------------------------------- */
#define CL_TEMPLATE_EXTENSION_NAME ".mantragoraclip"
CL_Template.h

/*
	Use this as a starting template for CL file format.

	IMPORTANT! ------------------------------------------
	-----------------------------------------------------

	Author: Mantragora (2014)

*/

#pragma once
#include "../FileFormat_Common.h"

namespace Mantragora
{
	namespace FileFormat
	{
		class CL_Template : public CL_ClipReader, public CL_ClipWriter
		{
		public:
			CL_Template();

			virtual
			~CL_Template();

			virtual auto
			writeClip(const char* file_name, const CL_Clip& clip)
			-> bool override;

			virtual auto
			readClip(const char* file_name, CL_Clip& clip)
			-> bool override;
		};
	}
}
CL_Template.cpp

/*
	Use this as a starting template for CL file format.

	IMPORTANT! ------------------------------------------
	-----------------------------------------------------

	Author: Mantragora (2014)

*/

#include "CL_Template.h"
using namespace Mantragora::FileFormat;

CL_Template::CL_Template() 
: CL_ClipReader(), CL_ClipWriter()
{

}

CL_Template::~CL_Template()
{

}

auto
CL_Template::readClip(const char* file_name, CL_Clip& clip)
-> bool
{
	cout << file_name << endl;

	return true;
}

auto
CL_Template::writeClip(const char* file_name, const CL_Clip& clip)
-> bool
{	
	cout << file_name << endl;

	return true;
}
FileFormat_Registration.cpp

/*
	This is a place where you should create and register all additional file formats.

	IMPORTANT! ------------------------------------------
	-----------------------------------------------------

	Author: Mantragora (2014)

*/

#define FINAL

#include <UT/UT_DSOVersion.h>
#include "CL/CL_Template.h"

#ifdef FINAL
#include "CL/CL_Template.cpp"
#endif

using namespace Mantragora::FileFormat;

/* ---------------------------------------------------------------------
CL REGISTRATION
--------------------------------------------------------------------- */
// create
namespace CL_Instances
{
	static CL_Template clTemplate;
}

// register readers
auto
CLregisterClipReader(void*)
-> void
{		
	CL_ClipIO::inst().registerClipReader(CL_TEMPLATE_EXTENSION_NAME, (CL_ClipReader&)CL_Instances::clTemplate);
}

// register writers
auto
CLregisterClipWriter(void*)
-> void
{	
	CL_ClipIO::inst().registerClipWriter(CL_TEMPLATE_EXTENSION_NAME, (CL_ClipWriter&)CL_Instances::clTemplate);
}
Edited by mantragora

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×