SketchyPhysics last version:
3.7.4 November 26, 2017
"... for SketchUp 32-bit only!"

Downloads
SketchyPhysics 3.7.4 (12MB)
.rbz
SketchUp Extension
.zip
ZIP Archive
.exe
Windows Installer

All SketchUp version -->
SketchUp Product Downloads


Original SketchyPhysics by Chris Phillips
SketchUp 8 + SP 3.2
(.zip, Windows, 38MB)

Show versions before 3.6.0 by Anton Synytsia -->
Sketchucation Topic
Change Log:

> Script area is enabled by default.
> Script editor theme is dark by default.
> Fixed more bugs.
> This is last update!

3.7.3 July 6, 2016

> Fixed Mac OS X crash (Thanks the feedback from Anton Synytsia).

3.7.2 > June 25, 2016

> Integrated new Export animation by Anton Synytsia.
> New Windows installer.
> Fixed some bugs.

3.7.1 > December 23, 2015

> Fixed the theme selector in script editor panel. From now just 2 theme is available.(Light, Dark)
> Added raytest(point, vector). This create a ray.
point: Geom::Point3d or numeric array
vector: Geom::Vector3d or numeric array
Return: Sketchup.active_model.raytest(point, vector) OR false if nil
> Added findBodyByRaytest(ray). This find a body on collision of raytest.
ray: raytest
Return: body [SP3xBodyContext]
> Added findPointByRaytest(ray). This find a point on collision of raytest.
ray: raytest
Return: Geom::Point3d
> Added addImpulse(body, point, vector, strength = 1). Add impulse to body on collision of the raytest. Point and vector must be the same as the raytest values.
body: [SP3xBodyContext]
point: raytest point
vector: raytest vector
strength: numeric

onStart {
  @box = findBody("box")
}

onUpdate {
  point = @box.getOrigin
  # ERASE THE BOX FACE ON GREEN AXIS !
  vector = @box.getAxes.y

  ray = raytest(point, vector)

  if key('v') == 1
    target_body = findBodyByRaytest(ray)
    addImpulse(target_body, point, vector)
  end
}
> Changed the 'visibleAll' command to 'visibility'

3.7.0 > December 12, 2015

> Added Entity Info table into Inspector. This get the all entity ID and index.


> Fixed the javascript fault in SUp 13. (If opened the Settings UI and double-click onto group).
> Added findLayer(value) alias to getLayer(value) v. 3.6.0
value: name- or index of layer
Return: layer
> Added findEntityByIndex(index) alias to getEntity(index) v. 3.6.0
Return: entity
> Added findEntityById(id)
id: ID of entity OR ID of internal entity in the group/component
Return: entity
> Added findGroupByName(name) Find just group/component by name.
name: name of group/component OR name of internal group/component in the group/component
Return: entity
> Added visibility(value, state)
value: entity, layer or body
state: true/false boolean. Default is false.
Return:
  state ? (value.visible = true unless value.visible?) : (value.visible = false if value.visible?)
onStart {
  @entity_1 = findEntityByIndex(0)
  @entity_2 = findEntityById(103)
  @entity_3 = findGroupByName("sphere")

  @layer_1 = findLayer(1)
  @layer_2 = findLayer("Physics joints")

  @body_1 = findBody("sphere")
  @body_2 = findBody(group_entity)
}

onUpdate {
  state = true if key('v') == 1

  visibility(@entity_1, state)
  visibility(@layer_1, state)
  visibility(@body_1, state)

OR

  @state = true if key('v') == 1
  @state = false if key('n') == 1

  visibility(@entity_1, @state)
  visibility(@layer_1, @state)
  visibility(@body_1, @state)
}

3.6.9 > December 7, 2015

> Fixed the Settings dialog html and javascript file.
> Added security alert to getMouseAxes, setSphereAxes, getEntity, getLayer, visibleEntity, visibleLayer commands.
> Improved the script editor panel.
Copy-paste function is working.
New themes: SP Light and SP Dark. The SketchyPhysics keywords is yellow.

3.6.8 > November 26, 2015

> Compatible with SketchUp 2016 32-bit.
New hand icon in simulation because old does not working.
Fixed the Prims and Joints toolbar check function.
New style and icons.
> Fixed model version checking.
Now if the model SketchyPhysics version is subsequent like the installed SP, then appears a window from which be downloaded the latest version.
> Fixed Ace editor theme changer.
From now remember onto selected theme.
> Fixed Menu in Settings dialog.
From now remember onto selected menu.
> Settings dialog is closed during the simulation.
> The last selected group will be memorized before start the simulation. Re-selected if stopped the simulation.
> Added Joints hide checkbox to Inspector.
This hide all Joints during the simulation.
> Added Controller Panel hide checkbox to Inspector.
This hide the Joints Controller Panel during the simulation.
> Added 'Purge Unused' button to Inspector.
This cleans the model.(materials, styles, definitions, layers)
> Added 'Delete Guides' button to Inspector.
This delete all guide points and guidelines.
When you're done with the model, you can delete all guides point from joints.
If there are many joints in the model, this improves the performance!
> Added 'Clear Ruby Console' button to script editor panel. (SketchUp 2014+)
> Added visibleLayer(value, state) command.
value = index- or name of layer
state = true/false boolean
Source:
  layer = Sketchup.active_model.layers[value]
  state ? (layer.visible = true unless layer.visible?) : (layer.visible = false if layer.visible?)
onUpdate {
  vis_layer_bool = true if key('v') == 1
  visibleLayer("Physics joints", vis_layer_bool)

  OR

  @vis_layer_bool = true if key('v') == 1
  @vis_layer_bool = false if key('n') == 1
  visibleLayer("Physics joints", @vis_layer_bool)
}
> Added visibleEntity(index, state)
> Added visibleBody(body, state)
body = physics group/component
state = true/false boolean
onStart {
  @body = findBody("sphere")
}

onUpdate {
  vis_body_bool = true if key('v') == 1
  visibleBody(@body, vis_body_bool)

  OR

  @vis_body_bool = true if key('v') == 1
  @vis_body_bool = false if key('n') == 1
  visibleBody(@body, @vis_body_bool)
}
> Added resetSimulation alias to physicsReset; and startSimulation to physicsStart v 3.6.4.
> Fixed the newPoint and newVector command.

3.6.7 > November 2, 2015

> Added new Ace Code Editor.
The copy and paste function is not working!
Hold the Ctrl/Command and drag the selected text to place.
Copy and paste from external editor in the Inspector script box.

3.6.6 > November 2, 2015

> Added new sound player command with stereo and multi functions:
SP3xCommonContext.playSoundPro(
channel,
"sound",
position,
volume,
play,
stop,
ch_reset,
repeat,
time
Required!
Required!
Required!
Optional
Optional
Optional
Optional
Optional
Optional



Default = 5
Default = false
Default = false
Default = false
Default = 0
Default = -1
@channel_1 = playSoundPro(@channel_1, .....)
Sound name.
3D point or array.
Sound volume.
Play sound: true/false boolean.
Stop sound and reset channel: true/false boolean.
Reset channel: true/false boolean.
Repeat sound.
Playback length in milliseconds.
)

Note: The channel is automatic resets, if non playing the sound.

#============================================================
# Version 1:  Background music
#============================================================
onUpdate {

  @channel_1 = playSoundPro(
    @channel_1,
    "background_music",
    camera.eye,  # Sound sources is camera centre point.
    5,
    frame == 1,  # Play music if simulation frame is 1.
    false,       # No stop.
    false,       # No channel reset.
    999          # Repeat.
  )
}

#============================================================
# Version 2:  Car horn.
#============================================================
onStart {
  @car = findBody("car")
}

onUpdate {
  if key('v') == 1
    play = true if @channel_horn == nil
  else
    stop = true
  end

  @channel_horn = playSoundPro(
    @channel_horn,
    "car_horn",
    @car.getCenter,
    4,
    play,
    stop
  )
}

#============================================================
# Version 3:  Play sound one by one.
#============================================================
onStart {
  @body = findBody("sphere")
}

onUpdate {
  play = true if key('v') == 1 and @channel_3 == nil

  @channel_3 = playSoundPro(
    @channel_3,
    "sound",
    @body.getCenter,
    4,
    play
  )
}

#============================================================
# Version 4:  Play sound with each key press.
#============================================================
onStart {
  @body = findBody("sphere")
}

onUpdate {
  if key('v') == 1
    play = true if @asdda == nil
    @asdda = true
  else
    @asdda = nil
  end

  @channel_4 = playSoundPro(
    @channel_4,
    "sound",
    @body.getCenter,
    5,
    play
  )
}

#============================================================
# Version 5:  Gun shot.
#============================================================
onStart {
  @gun = findBody("sphere")
}

onUpdate {
  play = true if key('v') == 1 and every(7)

  @channel_5 = playSoundPro(
    @channel_5,
    "gunShot_4",
    @gun.getCenter,
    5,
    play,
    false,       # No stop
    true         # Channel is nil, if 'play' no true.
  )
}

Note: If you use more gun shots, you can use this:
every(7,0) for 1 gun
every(7,1) for 2 gun
every(7,2) for 3 gun
etc ...
The second number should be less than the first!
> Added playback sound detector.
SP3xCommonContext.playing?(channel)
Returns: true/false boolean.
onUpdate {
  @channel_1 = playSound("activation_1") if key('v') == 1 and @channel == nil

  # This resets the sound channel. Required to setSoundPosition/2/ !
  (@channel_1 = nil unless playing?(@channel_1)) if @channel_1

  (@channel_85 = nil unless playing?(@channel_85)) if @channel_85

  # etc....

  # Turn it On/Off the joints with sound.
  if @channel_1
    playing?(@channel_1) ? setVar('variable',1) : setVar('variable',0)
  end
}
> Added set maximum channels in numbers. Default is 8, max is 100.
SP3xCommonContext.maxChannels(numeric)
onStart {
  maxChannels(30)
}
> Added frame counter with allocation. Count default is 0.
SP3xCommonContext.every(allocation, count)
Returns: true/false boolean.
Source:
  frame % allocation == count
onUpdate {
  @channel_1 = playSound("activation_1") if key('v') == 1 and every(30)
  @channel_2 = playSound("activation_2") if key('n') == 1 and every(30,10)
}

3.6.5 > October 24, 2015

> Fixed SketchUp 2013 start simulation crash.
> Fixed setSphereAxes command.
> Improved transition command.

3.6.4 > October 22, 2015

> Added follower camera command to vehicles.
SP3xBodyContext.followerCamera(
distance,
speed,
front height,
rear height,
field of view
Required!
Optional
Optional
Optional
Optional

Default = 20
Default = 10
Default = 50
Default = 40
)


> Added new menu item ("Camera Follow and Track") into right click context menu during simulation.
> Added origin point modifier (setBodyOrigin) to multiple shapes are selected.
> Added physicsReset command to stop and reset physics simulation.
SP3xBodyContext.physicsReset
Returns: MSketchyPhysics3::SketchyPhysicsClient.safePhysicsReset
onUpdate {
  physicsReset if key('v') == 1
}
> Added physicsStart command to start physics simulation.
SP3xBodyContext.physicsStart
Returns: MSketchyPhysics3::SketchyPhysicsClient.physicsStart
onUpdate {
  if key('v') == 1
    timer = UI.start_timer(0.2, false) {
      UI.stop_timer(timer)
      physicsStart
    }
    physicsReset
  end
}
> Added group/component finder by name to body commands.
SP3xBodyContext.findBody(value)
value: name of group/component OR entity
Returns: @simulation.findBody(value)
onStart {
  @entity_1 = getEntity(1)
  @body_1 = findBody(@entity_1)
OR
  @body_1 = findBody("sphere")
}

onUpdate {
  @body_1.setVelocity([0,1,0])
}

3.6.3 > October 20, 2015

> Sounds dialog is integrated into Settings dialog.
> Added for shapes body origin changer command. This changes the origin point to body center point.
   Only in this way will be correct the friction.

> Fixed the Joint-Properties and connection tool.rb.
Connect joint to body: Hold the left Ctrl, click the joint then click the body.
Disconnect: Hold the left Shift, no matter what the order. <->
> Fixed the getFps command.
> Fixed the setSphereAxes command.
> Added update checker in "Extensions -> SketchyPhysics -> Check the new version"
> Added Ruby Console cleaner command into sp_tool.rb.
Returns: SKETCHUP_CONSOLE.clear

3.6.2 > October 14, 2015

> Added hide Joint Controller Panel command:
SP3xCommonContext.hiddenControllerPanel
(The getMouseAxes command automatically hides the controller panel.)
onStart {
  hiddenControllerPanel
}
> Fixed the controller_commands.rb.
> Fixed the physicsStart command in sp_tool.rb. Now open the Joint Controller Panel.
> Added oscillator command:
SP3xCommonContext.oscillator(num)
(num == speed)
onStart {
  @body_1 = findBody("sphere")
  @body_1.static = true
  @body_1.nocollision = true
}

onUpdate {
  up = 50 + oscillator(20)
  @body_1.setTransformation([0, 0, up])

  setVar("servo", oscillator(20))

  #Joints Controller: oscillator(20)
}

3.6.1 > October 6, 2015

> Fixed the webdialogs. Now font sizing is automatic with webdialog width. The dialog windows is freely scalable !
> Integrated 61 wav sound files in sound folder.
> Removed the GamePlay button.
> Added Windows detector:
SP3xCommonContext.os_windows?
Returns (RUBY_PLATFORM =~ /mswin|mingw/i) ? true : false

3.6.0 > July 4, 2015

> New style, renewed the webdialogs, toolbar icons and Joints.
> Added an option to scale joints:
(Menu)Plugins->SketchyPhysics->Edit Joint Scale or Joints toolbar (created by Anton Synytsia)
> Added new GamePlay button. This disable the "Joint Controller Panel" hides the axes of SketchUp and SketchUp window puts into the background. Reset simulation with ESC button.
> Added mouse controller. Only for Windows and can be used only once in Script-box!:
SP3xBodyContext.getMouseAxes
Returns: [x,y] Array

onUpdate {
  mouse = getMouseAxes

  setVar("motor", mouse.x)

  head_axes = setSphereAxes(mouse.x, mouse.y)
}
> Added head move function for fps type games. (Used only once!):
SP3xCommonContext.setSphereAxes(left-right, up-down)
Returns: [x,y] Array
onStart {
  @body_1 = findBody("sphere")
  @body_1.static = true
  @body_1.nocollision = true
  @body_2 = findBody("box")
  @body_2.static = true
  @body_2.nocollision = true
}

onUpdate {
  head_axes = setSphereAxes(key('left')-key('right'), key('up')-key('down'))
  @body_1.setTransformation([0,0,50], head_axes.x, head_axes.y, head_axes.z)
  @body_2.setTransformation([40,0,50], head_axes.x, head_axes.y, head_axes.z)
}
> Added body multi transformation:
SP3xBodyContext.setTransformation(
point, Xvector, Yvector, Zvector,
rotation degrees, vector, point,
X scale, Y scale, Z scale
Required!, Opt., Opt., Opt.,
Optional, Optional, Optional,
Optional, Optional, Optional
Default = nil, [1,0,0], [0,1,0], [0,0,1],
Default = 0, [0,0,1], [0,0,0],
Default = 1, 1, 1
)


onStart {
  @body_1 = findBody("sphere")
  @body_1.static = true
  @body_1.nocollision = true
}

onUpdate {
  @body_1.setTransformation(
    newPoint(0,0,50), newVector(1,0,0), newVector(0,1,0), newVector(0,0,1),
    90, newVector(0,0,1), newPoint(0,0,0),
    1, 1, 1
  )
}
> Added transition. Array logarithm only; Number logarithm or linear:
SP3xCommonContext.transition(
new,
current,
speed,
linear
Required!
Required!
Optional
Optional


Default = 50
Default = false
)

onStart {
  @new = @current = [0,0,0]
  @newNum = @currentNum = 0
}

onUpdate {
  @new = [45, -21, 523] if key('v') == 1
  @new = [0, 57, -311] if key('n') == 1

  @current = transition(@new, @current, 10)
  # Now the @current is x,y,z array.

  @newNum = 185 if key('v') == 1
  @newNum = -21 if key('n') == 1

  @currentNum = transition(@newNum, @currentNum, 10, true)
  # Now the @currentNum is number.
}
> Added Frames Per Second getter:
SP3xCommonContext.getFps
Returns: Numeric
onUpdate {
  getEntity(1).text = getFps.to_s
}
> Added body absolute center point getter:
SP3xBodyContext.getCenter
Returns: 3D point
onStart {
  @body_1 = findBody("sphere")
}

onUpdate {
  point = @body_1.getCenter
}
> Added body origin point getter:
SP3xBodyContext.getOrigin
Returns: 3D point
onStart {
  @body_1 = findBody("sphere")
}

onUpdate {
  point = @body_1.getOrigin
}
> Added body axes getter:
SP3xBodyContext.getAxes
Returns: [x,y,z] Array
onStart {
  @body_1 = findBody("sphere")
}

onUpdate {
  axes = @body_1.getAxes
}
> Added entities getter:
SP3xCommonContext.getEntity(index)
Returns: Sketchup.active_model.entities[index]
onStart {
  @entity_1 = getEntity(1)
}

onUpdate {
  @entity_1.material = "red"
}
> Added layer getter:
SP3xCommonContext.getLayer(value)
value: name- or index of layer
Returns: Sketchup.active_model.layers[value]
onStart {
  @layer_1 = getLayer(1)
}

onUpdate {
  @layer_1.visible = false
}
> Added body hide or visible command:
SP3xBodyContext.visible=(state)
Returns: body.group.visible=true/false
onStart {
  @body_1 = findBody("sphere")
}

onUpdate {
  axes = @body_1.visible = false
}
> Added SP3xBodyContext.conversion=(transformations * transformations)
Returns: self.group.transformation=()
onStart {
  @body_1 = findBody("sphere")
  @body_1.static = true
  @body_1.nocollision = true
}

onUpdate {
  tra_1 = transformation_R(30, newVector(0,0,1))
  tra_2 = transformation_R(60, newVector(1,0,0))
  @body_1.conversion=(tra_1 * tra_2)
}
> Added SP3xBodyContext.transformation_N(position, x, y, z)
Returns: Geom::Transformation.new
> Added SP3xBodyContext.transformation_R(degrees, vector, point)
Returns: Geom::Transformation.rotation
> Added SP3xBodyContext.transformation_S(x, y, z)
Returns: Geom::Transformation.scaling
> Added SP3xCommonContext.newPoint(x, y, z)
Returns: Geom::Point3d.new
> Added SP3xCommonContext.newVector(x, y, z)
Returns: Geom::Vector3d.new