HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OBJ_Shake.C
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018
3  * Side Effects Software Inc. All rights reserved.
4  *
5  * Redistribution and use of Houdini Development Kit samples in source and
6  * binary forms, with or without modification, are permitted provided that the
7  * following conditions are met:
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * 2. The name of Side Effects Software may not be used to endorse or
11  * promote products derived from this software without specific prior
12  * written permission.
13  *
14  * THIS SOFTWARE IS PROVIDED BY SIDE EFFECTS SOFTWARE `AS IS' AND ANY EXPRESS
15  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
17  * NO EVENT SHALL SIDE EFFECTS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  *----------------------------------------------------------------------------
26  * This custom object defines a geometry object that has parameters which
27  * define a frame-dependent jitter in its translation. This can be used to make
28  * earth-quake type effects. No doubt next year will be the year of the
29  * Earthquake movie.
30  */
31 
32 #include <SYS/SYS_Math.h>
33 #include <UT/UT_DSOVersion.h>
34 #include <PRM/PRM_Include.h>
35 #include <OP/OP_Director.h>
36 #include <OP/OP_OperatorTable.h>
37 #include "OBJ_Shake.h"
38 
39 
40 using namespace HDK_Sample;
41 
42 // shakeIndirect is an array of indices that are used to access parameters
43 // quickly. The indices are initialized by the EVAL_FLOAT methods in the
44 // header file.
45 int *OBJ_Shake::shakeIndirect = 0;
46 
47 
48 
49 // Constructor for new object class
51  :OBJ_Geometry(net, name, op)
52 {
53  // initialize local member data here.
54 
55  // shakeIndirect is initialized to an array of 1 index (each initialized
56  // to -1 -- ie not accessed yet).
57  //
58  // The base class, OBJ_Geometry, uses its own class static indirect array.
59  // We don't have to worry about this as long as we don't change the order
60  // of these base parameters in our template list. If we were to change
61  // the order of these base parameters, then we would need to override the
62  // getIndirect() method to ensure our class static indirect array is used.
63  // In that case, we'd need to ensure it was large enough to handle all of
64  // the base parameters as well (i.e. allocIndirect(I_N_GEO_INDICES + 1).
65  if (!shakeIndirect) shakeIndirect = allocIndirect(1);
66 }
67 
68 
69 
70 // virtual destructor for new object class
72 {
73 }
74 
75 
76 // Un-comment the next line to see an example of creating custom tabs
77 //#define SWITCHER_EXAMPLE
78 #ifdef SWITCHER_EXAMPLE
79 static PRM_Name switcherName("shakeswitcher");
80 static PRM_Default switcher[] = {
81  PRM_Default( 1, "Shake"), // 1 is number of parameters in tab
82  PRM_Default( 0, "Other"), // actually have no parameters here
83 };
84 #endif
85 
86 // here is the name of the parameter that is used by the shake object
87 static PRM_Name OBJjitter("jitter", "Jitter Scale");
88 
89 
90 
91 // this is the template list that defines the new parameters that are
92 // used by the shake object.
93 static PRM_Template templatelist[] =
94 {
95  // Here we define the new parameter
96 #ifdef SWITCHER_EXAMPLE
97  PRM_Template(PRM_SWITCHER, sizeof(switcher)/sizeof(PRM_Default),
98  &switcherName, switcher),
99 #endif
100  PRM_Template(PRM_XYZ_J, 3, &OBJjitter, PRMoneDefaults),
101 
102  // followed by this blank terminating Template.
103  PRM_Template()
104 };
105 
106 
107 
108 // this function returns the OP_TemplatePair that combines the parameters
109 // of this object with those of its ancestors in the (object type hierarchy)
112 {
113  OP_TemplatePair *shake, *geo;
114 
115  // Here, we have to "inherit" template pairs from geometry and beyond. To
116  // do this, we first need to instantiate our template list, then add the
117  // base class templates.
118  shake = new OP_TemplatePair(templatelist, prevstuff);
120  shake);
121  return geo;
122 }
123 
124 
125 
126 // the myConstructor method is used to create new objects of the correct
127 // type from the OperatorTable.
128 OP_Node *
130 {
131  return new OBJ_Shake(net, name, op);
132 }
133 
134 
135 
136 // this method pre-multiplies the given matrix with an appropriate transform
137 // to shake the object. our shake transform gets inserted into the object
138 // transform pipeline essentially before the transform parameters.
139 int
141 {
142  const fpreal t = context.getTime(); // extract time from OP_Context
143  fpreal jx, jy, jz;
144  unsigned seed;
145  int modified;
146 
147  // call OBJ_Geometry::applyInputIndependentTransform() so that we don't
148  // lose any information
149  modified = OBJ_Geometry::applyInputIndependentTransform(context, mat);
150  if (error() >= UT_ERROR_ABORT)
151  {
152  // don't do anything since an error has occurred.
153  return modified;
154  }
155 
156  // first we compute our jitter values as a random value within
157  // the given jitter scale using a frame dependent seed value
158  // (different for x, y, and z)
159  jx = JX(t); jy = JY(t); jz = JZ(t);
160 
161  seed = (int)OPgetDirector()->getChannelManager()->getSample(t);
162  jx *= 2*SYSfastRandom(seed) - 1.0;
163 
164  seed ^= 0xdeadbeef;
165  jy *= 2*SYSfastRandom(seed) - 1.0;
166 
167  seed ^= 0xfadedcab;
168  jz *= 2*SYSfastRandom(seed) - 1.0;
169 
170  // we add our jitter to the object transform
171  mat.pretranslate(jx, jy, jz);
172 
173  // since the jitter value is frame dependent and this object won't
174  // be flagged as time dependent through any other method, we need to
175  // explicitly flag it here.
176  // NB: this flag gets reset at the beginning of every cook, unless
177  // tranform caching is enabled by the object parameter.
178  // When transforms are cached, this flag is cleared before the cook on
179  // which there was a miss that invalidated all cached transforms for
180  // that object.
181  flags().setTimeDep(true);
182 
183  // return 1 to indicate that we have modified the input matrix.
184  // if we didn't modify mat, then we should return 0 instead.
185  return 1;
186 }
187 
188 
189 
190 // this function installs the new object in houdini's object table.
191 void
193 {
194  table->addOperator(new OP_Operator("hdk_shake", "Shake",
198  0, 1,
199  0));
200 }
virtual OP_ERROR error()
static const char * theChildTableName
Definition: OBJ_Node.h:237
virtual ~OBJ_Shake()
Definition: OBJ_Shake.C:71
OBJ_Shake(OP_Network *net, const char *name, OP_Operator *op)
Definition: OBJ_Shake.C:50
const OP_NodeFlags & flags() const
Definition: OP_Node.h:1339
fpreal getTime() const
Definition: OP_Context.h:60
PRM_API PRM_Default PRMoneDefaults[]
bool addOperator(OP_Operator *op, std::ostream *err=nullptr)
static OP_Node * myConstructor(OP_Network *net, const char *name, OP_Operator *entry)
Definition: OBJ_Shake.C:129
PRM_API const PRM_Type PRM_XYZ_J
static PRM_Template * getTemplateList(OBJ_ParmsStyle style)
CH_Manager * getChannelManager()
Definition: OP_Director.h:97
void newObjectOperator(OP_OperatorTable *table)
Definition: OBJ_Shake.C:192
fpreal getSample(fpreal t) const
Definition: CH_Manager.h:1011
virtual int applyInputIndependentTransform(OP_Context &context, UT_DMatrix4 &mat)
void pretranslate(T dx, T dy, T dz=0.0f)
Definition: UT_Matrix4.h:719
fpreal JY(fpreal t)
Definition: OBJ_Shake.h:54
fpreal JX(fpreal t)
Definition: OBJ_Shake.h:53
GLuint const GLchar * name
Definition: glcorearb.h:785
PRM_API const PRM_Type PRM_SWITCHER
double fpreal
Definition: SYS_Types.h:270
typedef int
Definition: png.h:1175
int * allocIndirect(int size=64)
OP_API OP_Director * OPgetDirector()
fpreal JZ(fpreal t)
Definition: OBJ_Shake.h:55
static OP_TemplatePair * buildTemplatePair(OP_TemplatePair *prevstuff)
Definition: OBJ_Shake.C:111
virtual int applyInputIndependentTransform(OP_Context &context, UT_DMatrix4 &mat)
Definition: OBJ_Shake.C:140
void setTimeDep(int onOff)
Definition: OP_NodeFlags.h:112