STEAM GROUP
Open Source Filmmaker osfm
STEAM GROUP
Open Source Filmmaker osfm
504
IN-GAME
3,355
ONLINE
Founded
15 August, 2012
Showing 1-10 of 12 entries
8
[HELP] Heavy rain particle
{LINK REMOVED} a heavy rain particle system I have created from the unusual rain effect (e.g. I have increased a lot the number of particles rendered). Just download it into a 'particles' folder (e.g. the one in 'tf_movies'), add that particle in sfm and lock it to the camera position.

Preview[drive.google.com]
6
how to make this????
2
Script that auto-adjusts focus-distance to a bone;s distance.
10
WANTED : A WAY TO FAKE PORTALS FOR SFM
1
BASIC PYTHON SCRIPTING EXAMPLES/TUTORIAL
I'll be the first one giving some very basic tips :
  • Getting started
    The scripts are located in
    SourceFilmmaker\game\XXX\scripts\sfm\***
    Where XXX is platform for the default scripts, but can be any game folder listed in usermod\gameinfo.txt like usermod, tf, workshop ...
    and where *** can be
    1. the current folder (only used for sfm_init.py I think, i.e., the script executed automatically when launching SFM),
    2. mainmenu, to create scripts launched from the Scripts dropdown menu in SFM (you should have there the Examples scripts. A good place to create scripts un related with a specific shot, just with your current session). You need to restart SFM for the new scripts to appear.
    3. dag, to create scripts accessed through RMB>Dag Utilities menu. There are two subfolders, exact\countX (when you have exactly X Dags selected (e.g. only X=1 dag selected)), and multi (when you have multiple Dags selected e.g. to create point/aim/orient/parent constraints quickly). New scripts appear automatically (no restart needed).
    4. animset, to create scripts accessed through RMB>Rig. That's the one I'm using for my scripts, as you can then get very easily some basic information like your current shot or the "thing" (Animation Set) you have selected. New scripts appear automatically (no restart needed).
    The scripts are written in Python (duh), if you don't know this language, here is a summary of some syntax rules (Python files end with .py, I recommend using Notepad++[notepad-plus-plus.org] to edit them) :
    • As most languages, it is case-sensitive (pro-tip : variableName, FunctionName)
    • No special char to end an instruction, the end of line suffice.
    • PYTHON IS ALL ABOUT TABULATION : hierachy is told through tabulations, there are no braces ('{'), only an opening with a colon (':'), and then the tabbed content.
      Example : this C/java code
      if (condition) { actionsIfTrue(); } else { actionsIfFalse(); } actionsAnyway();
      becomes in Python
      if condition: actionsIfTrue() else: actionsIfFalse() actionsAnyway()
      /!\If you copy-paste my code, you need to replace every 3 spaces by a tabulation /!\
      I did the opposite in order for my code to be good looking, because Steam-code tabulation is too large.
      In Notepad++, \t == 'a tabulation'
    • The for-loop in Python works with arrays. Here is an example from the Example scripts of SFM
      shots = sfmApp.GetShots() nCounter = 0 for shot in shots: flDuration = shot.timeFrame.duration.GetValue().GetSeconds() if flDuration == 0.0: nCounter += 1 track = sfmApp.GetParentTrack( shot ) track.RemoveClip( shot ) message = "Removed %d shots because of duration 0" % nCounter
    • #This is a comment.
    • To create a new function, use the def key word. Example :
      def HelloWorld(dumbName): print "Hello "+dumbName+" !" #Your function may or may not return something : return 0

  • Some basic functions
    Of course, you must have a decent understanding of how the Element Viewer works, because Python scripts work messing with it (Dragons, blabla).

    If you are testing some code, of course,
    /!\ DO IT ON A BLANK SESSION WITH NOTHING TO LOSE /!\
    • Getting the shot you are working on (most important one, as almost all you add/edit will be related to its specific shot) :
      shot = sfm.GetCurrentShot() #This way you can get the Shot ID : shot.GetFileId()
    • Getting the model/camera/light/etc. (Animation Set actually) you are working on (the one you have right-clicked on) (very useful one, to edit one element easily) :
      animSet = sfm.GetCurrentAnimationSet()
    • Adding a New Model (the equivalent of Create Animation Set for New Model) :
      baseName = "secret_spy" #whatever we want. If this name is already taken, it will add "2" at the end of the name. modelPath = "models\\player\\hwm\\spy.mdl" #The short path to the model. If you use an antislash '\', be sure to double it, as it is a special char. newAnimSet = sfmUtils.CreateModelAnimationSet( baseName, modelPath )
      The function sfmUtils.CreateModelAnimationSet is very interesting per se, as it shows a more general method for adding stuff :
      def CreateModelAnimationSet( baseName, modelPath ): #We need the Shot ID when adding elements (vs.CreateElement) shot = sfm.GetCurrentShot() #We instance a pointer to the model, but it is not rendered yet and it has no Animation Set linked to it model = sfm.CreateModel( modelPath ) if ( model != None ): #If the model is created successfully ... #... we create an Animation Set for that model. animSet = sfm.CreateAnimationSet( baseName, target=model ) if ( animSet != None ): #The following code adds the model to the scene dag = vs.CreateElement( "DmeDag", baseName, shot.GetFileId() ) dag.AddChild( model ) shot.scene.AddChild( dag ) return animSet
    • Adding a New Light (the equivalent of Create Animation Set for New Light) :
      def CreateNewLight(lightName = "light"): shot = sfm.GetCurrentShot() #Create an abstract Light newLight = vs.CreateElement("DmeProjectedLight", lightName, shot.GetFileId()) #Add the light to the scene shot.scene.FindOrAddChild("Lights").children.AddToTail(newLight) #Create an Animation Set for the new Light newLightAnimSet = sfm.CreateAnimationSet(lightName, target=newLight) return newLightAnimSet CreateNewLight("fiatLuxEtLuxFuit")
    • Adding a New Camera (the equivalent of Create Animation Set for New Camera) :
      def CreateNewCamera(cameraName = "camera"): shot = sfm.GetCurrentShot() #Create an abstract Camera newCamera = vs.CreateElement("DmeCamera", cameraName, shot.GetFileId()) #Add the camera to the scene shot.scene.FindOrAddChild("Cameras").children.AddToTail(newCamera) #Create an Animation Set for the new Camera newCameraAnimSet = sfm.CreateAnimationSet(cameraName, target=newCamera) return newCameraAnimSet CreateNewCamera("bigBrotherIsWatchingYou")
    • Pasting As Reference (for you guys used to mess with the Element Viewer but new to scripting) : the function is AddToTail(dagElement)
    • Making the Selected Camera the RT Camera (e.g. for Portals or mirrors) :
      shot = sfm.GetCurrentShot() #We get the AnimationSet selected, and hope it is a Camera animSet = sfm.GetCurrentAnimationSet() if animSet.HasAttribute("camera"): #If the selected Animation Set was actually one of a camera #We get the Camera Dag (DmeCamera) : camera = animSet.camera shot.monitorCameras.AddToTail(camera) #Here is the "Paste as Reference equivalent of the Element Viewer ! shot.activeMonitor = shot.activeMonitor + 1 camera.name = "RTCamera" animSet.name = "RTCamera"
    • Getting all the Animation Sets (taken from revzin.net) :
      import vsUtils # Required for iterAttrs to work shot = sfm.GetCurrentShot() # Empty array allAnimSets = [] for shotAttribute in shot.iterAttrs(): if shotAttribute.GetName() == "animationSets": for animSet in shotAttribute: allAnimSets.append(animSet) break #Now all the Animation Sets are in the allAnimSets array : for animSet in allAnimSets : print animSet.GetName()

/!\If you copy-paste my code, you need to replace every 3 spaces by a tabulation /!\
I did the opposite in order for my code to be good looking, because Steam-code tabulation is too large.
In Notepad++, \t == 'a tabulation'
Showing 1-10 of 12 entries