diff --git a/include/IECoreRI/private/SXRendererImplementation.h b/include/IECoreRI/private/SXRendererImplementation.h index 67efdab6a3..5c8e88ea54 100644 --- a/include/IECoreRI/private/SXRendererImplementation.h +++ b/include/IECoreRI/private/SXRendererImplementation.h @@ -139,6 +139,8 @@ class SXRendererImplementation : public IECore::Renderer SxShader imagerShader; SXExecutor::ShaderVector coshaders; SXExecutor::ShaderVector lights; + + Imath::M44f transform; }; typedef std::stack StateStack; diff --git a/src/IECoreRI/SXRendererImplementation.cpp b/src/IECoreRI/SXRendererImplementation.cpp index 6cdeaffec2..9582110434 100644 --- a/src/IECoreRI/SXRendererImplementation.cpp +++ b/src/IECoreRI/SXRendererImplementation.cpp @@ -34,6 +34,7 @@ #include "IECoreRI/private/SXRendererImplementation.h" #include "IECoreRI/SXExecutor.h" +#include "IECoreRI/Convert.h" #include "IECore/MessageHandler.h" #include "IECore/Shader.h" @@ -41,7 +42,6 @@ #include "IECore/SplineData.h" #include "IECore/MatrixAlgo.h" #include "IECore/Transform.h" -#include "IECore/MatrixTransform.h" #include "IECore/Group.h" #include "boost/algorithm/string/case_conv.hpp" @@ -227,17 +227,25 @@ void IECoreRI::SXRendererImplementation::worldEnd() void IECoreRI::SXRendererImplementation::transformBegin() { - msg( Msg::Warning, "IECoreRI::SXRendererImplementation::transformBegin", "Not implemented" ); + // New push state onto the stack: deep copy flag is false, so we don't create a new SxContext, which will swallow up any + // coordinate systems declared before transformEnd(): + m_stateStack.push( State( m_stateStack.top(), false ) ); } void IECoreRI::SXRendererImplementation::transformEnd() { - msg( Msg::Warning, "IECoreRI::SXRendererImplementation::transformEnd", "Not implemented" ); + unsigned minimumStack = m_inWorld ? 2 : 1; + if( m_stateStack.size() <= minimumStack ) + { + IECore::msg( IECore::Msg::Error, "IECoreRI::SXRenderer::transformEnd", "No matching transformBegin." ); + return; + } + m_stateStack.pop(); } void IECoreRI::SXRendererImplementation::setTransform( const Imath::M44f &m ) { - msg( Msg::Warning, "IECoreRI::SXRendererImplementation::setTransform", "Not implemented" ); + m_stateStack.top().transform = m; } void IECoreRI::SXRendererImplementation::setTransform( const std::string &coordinateSystem ) @@ -247,7 +255,7 @@ void IECoreRI::SXRendererImplementation::setTransform( const std::string &coordi Imath::M44f IECoreRI::SXRendererImplementation::getTransform() const { - return getTransform( "object" ); + return m_stateStack.top().transform; } Imath::M44f IECoreRI::SXRendererImplementation::getTransform( const std::string &coordinateSystem ) const @@ -258,12 +266,15 @@ Imath::M44f IECoreRI::SXRendererImplementation::getTransform( const std::string void IECoreRI::SXRendererImplementation::concatTransform( const Imath::M44f &m ) { - msg( Msg::Warning, "IECoreRI::SXRendererImplementation::concatTransform", "Not implemented" ); + m_stateStack.top().transform = m * m_stateStack.top().transform; } void IECoreRI::SXRendererImplementation::coordinateSystem( const std::string &name ) { - msg( Msg::Warning, "IECoreRI::SXRendererImplementation::coordinateSystem", "Not implemented" ); + M44f m = m_stateStack.top().transform.transposed(); + RtMatrix mm; + convert( m, mm ); + SxDefineSpace ( m_stateStack.top().context.get(), name.c_str(), (RtFloat*)&mm[0][0] ); } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/test/IECoreRI/SXRendererTest.py b/test/IECoreRI/SXRendererTest.py index 60f160e984..eb7a59da9e 100644 --- a/test/IECoreRI/SXRendererTest.py +++ b/test/IECoreRI/SXRendererTest.py @@ -127,7 +127,7 @@ def __assertVectorDataAlmostEqual( self, data1, data2 ) : else : for i in range( 0, len( data1 ) ) : self.assertAlmostEqual( data1[i], data2[i], 6 ) - + def test( self ) : r = IECoreRI.SXRenderer() @@ -901,7 +901,42 @@ def testUserOptions( self ): s = r.shade( points ) self.assertEqual( s["Ci"][0], IECore.Color3f( 1,1,1 ) ) - + + def testCoordinateSystems( self ): + + self.assertEqual( os.system( "shaderdl -Irsl -o test/IECoreRI/shaders/sxCoordSystemTest.sdl test/IECoreRI/shaders/sxCoordSystemTest.sl" ), 0 ) + + points = self.__rectanglePoints( IECore.Box2i( IECore.V2i( 0 ), IECore.V2i( 1 ) ) ) + + r = IECoreRI.SXRenderer() + + r.shader( "surface", "test/IECoreRI/shaders/sxCoordSystemTest.sdl", { "coordSysName" : IECore.StringData( "test1" ) } ) + + r.transformBegin() + r.setTransform( IECore.M44f.createTranslated( IECore.V3f(0,0,2) ) ) + r.coordinateSystem( "test1" ) + r.transformEnd() + + r.transformBegin() + r.setTransform( IECore.M44f.createRotated( IECore.V3f(1,0,0) ) ) + r.concatTransform( IECore.M44f.createTranslated( IECore.V3f(0,0,2) ) ) + r.coordinateSystem( "test2" ) + r.transformEnd() + + s1 = r.shade( points ) + for i in range( len( s1["Ci"] ) ): + self.assertEqual( points["P"][i] + IECore.V3f(0,0,2), IECore.V3f( s1["Ci"][i][0], s1["Ci"][i][1], s1["Ci"][i][2] ) ) + + r.shader( "surface", "test/IECoreRI/shaders/sxCoordSystemTest.sdl", { "coordSysName" : IECore.StringData( "test2" ) } ) + s2 = r.shade( points ) + for i in range( len( s2["Ci"] ) ): + shaderP = IECore.V3f( s2["Ci"][i][0], s2["Ci"][i][1], s2["Ci"][i][2] ) + transP = points["P"][i] * IECore.M44f.createTranslated( IECore.V3f(0,0,2) ) * IECore.M44f.createRotated( IECore.V3f(1,0,0) ) + + self.failUnless( ( shaderP - transP ).length() < 1.e-5 ) + + + def tearDown( self ) : files = [ @@ -923,6 +958,8 @@ def tearDown( self ) : "test/IECoreRI/shaders/sxTextureTest.sdl", "test/IECoreRI/shaders/sxUniformPrimitiveVariableShaderParameterTest.sdl", "test/IECoreRI/shaders/sxUniformPrimitiveVariableTest.sdl", + "test/IECoreRI/shaders/sxUserOptionTest.sdl", + "test/IECoreRI/shaders/sxCoordSystemTest.sdl", ] for f in files : diff --git a/test/IECoreRI/shaders/sxCoordSystemTest.sl b/test/IECoreRI/shaders/sxCoordSystemTest.sl new file mode 100644 index 0000000000..db8a424d27 --- /dev/null +++ b/test/IECoreRI/shaders/sxCoordSystemTest.sl @@ -0,0 +1,4 @@ +surface sxCoordSystemTest( string coordSysName = "current" ) +{ + Ci = color( transform( coordSysName, "current", P ) ); +}