Notifications
Clear all

[Closed] How to make Speedometer Plugin…

Is there an easy way to connect this to a text object so that the speed displays dynamically? Its such a great script…to be able to render this in the viewport would be the cherry on top!

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

there is a sample in the mxs help that shows how to make dynamically changeable Text shape text.
but let me show some other way… we need just simply modify my old speedometer plugin… i’ve added a new parameter – output text object which can be picked from the scene. it sets a text on speed get event… i set it to baseobject, so you can add any modifier to the text shape to make it renderable the way you like.


 
 /*
 	sample code by denisT 2012-2013. free to use but please give me a credit.
 */
 
 plugin Modifier Speedometer
 name:"Speedometer"
 classID:#(0x00196700,0x1011abc1)
 (
 	local target
 	fn getTarget = (refs.dependentnodes this)[1]
 	fn synchTarget = 
 	(
 		if (target = getTarget()) != undefined do
 		(
 			s = this.speed.controller = createinstance Float_Script
 			s.AddObject #v target.position.controller
 			s.AddTarget #v0 target[#transform][#position] offset:-0.01s
 			s.AddTarget #v1 target[#transform][#position] offset:0
 
 			ss = "length(v1-v0)"
 			s.SetExpression ss
 			s
 		)
 	)
 	parameters main rollout:params
 	(
 		speed type:#float animatable:on ui:ui_speed
 		unit type:#integer default:1 animatable:off ui:ui_unit
 		
 		on speed get val do if iskindof speed.controller Float_Script then
 		(
 			val = case unit of
 			(
 					1: val
 					2: val*100.0
 					3: val*100.0/(units.decodevalue "1m")
 					4: val*100.0/(units.decodevalue "1m")/0.27778
 					5: val*100.0/(units.decodevalue "1m")/0.44704
 					6: val*100.0/framerate
 			  default: val
 			)
 			if iskindof this.textNode.baseobject Text do this.textNode.baseobject.text = val as string
 			val 
 		)
 		else val 
 		
 		on unit set val do if iskindof speed.controller Float_Script do speed.controller.Update()
 	)
 	rollout params "Parameters"
 	(
 		label lb_delta "Time Delta(s):" across:2 align:#right offset:[-4,1]
 		spinner ui_delta fieldwidth:64 range:[-1e9,1e9,0.01] type:#float align:#right offset:[6,0] enabled:off
 		
 		local unit_labels = 
 		#(
 			"units per time delta", 
 			"units per second", 
 			"meters per second", 
 			"kilometers per hour", 
 			"miles per hour",
 			"units per frame" 
 		)
 		label lb_unit "Units:" across:2 align:#right offset:[-43,8]
 		radiobuttons ui_unit labels:unit_labels default:1 align:#left offset:[-38,7]
 		label lb_speed "Local Speed:" across:2 align:#right offset:[-4,8]
 		spinner ui_speed fieldwidth:64 range:[-1e9,1e9,0] type:#float align:#right offset:[6,7] enabled:off
 	)
 	parameters textOutput rollout:textOutput
 	(
 		textNode type:#node subanim:on ui:ui_textNode
 	)
 	fn onlyText node = (iskindof node.baseobject Text) 
 	rollout textOutput "Text Output Node" 
 	(
 		pickbutton ui_textNode "Pick Text Node" autoDisplay:on filter:onlyText width:152 align:#right offset:[8,0]
 	)
 	
 	on attachedToNode node do 
 	(
 		--format "attach... %
" target
 		synchTarget()
 	)
 	on update do 
 	(
 		--format "update... %
" target
 		synchTarget()
 	)
 )
 
 
 delete objects
 b = box isselected:on
 t = text()
 addmodifier b (Speedometer textNode:t)
 with animate on at time 100 b.pos = [0,200,0]
 

K…sort of figured it out. I got the text to update in the viewport.

DenisT…thanks again for the script! All of your help makes learning less painfull!

Thats bascially what i did…similar to the online help version…changing the text based on the output of your speed controller.

used this in the text dloat script controller:


$'Text001'.text = ($Dummy001.speedometer.speed) as String;
0

I have a couple more questions…is there a way to truncate the number of decimal places for the speed output? Right now it jumps anywhere from 1 decimal place to 4.

And is it possible to show the units for the speed as well? That would be really helpful.

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

look at mxs help formattedPrint. there has to be a format that does do what you want.
it’s easy to add units. just simply add after (val as string) the <units string>

Am i using this code correctly in my float script…it seems that there is something wrong because the number of decimal places still jumps.


 $'Text001'.text = (formattedprint $Dummy001.speedometer.speed format:"#4.3g") as String;
 0
 

Thanks for pointing me to the formattedprint by the way…good to know.

playing with my own sample:



/*
	sample code by denisT 2012. free to use but please give me a credit.
*/

plugin Modifier Speedometer
name:"Speedometer"
classID:#(0x00196700,0x1011abc1)
(
	local target
	fn getTarget = (refs.dependentnodes this)[1]
	fn synchTarget = 
	(
		if (target = getTarget()) != undefined do
		(
			s = this.speed.controller = createinstance Float_Script
			s.AddObject #v target.position.controller
			s.AddTarget #v0 target[#transform][#position] offset:-0.01s
			s.AddTarget #v1 target[#transform][#position] offset:0

			ss = "length(v1-v0)"
			s.SetExpression ss
			s
		)
	)
	parameters main rollout:params
	(
		speed type:#float animatable:on ui:ui_speed
		unit type:#integer default:1 animatable:off ui:ui_unit
		
		on speed get val do if iskindof speed.controller Float_Script then
		(
			val = case unit of
			(
					1: val
					2: val*100.0
					3: val*100.0/(units.decodevalue "1m")
					4: val*100.0/(units.decodevalue "1m")/0.27778
					5: val*100.0/(units.decodevalue "1m")/0.44704
					6: val*100.0/framerate
			  default: val
			)
			if val != undefined and iskindof this.textNode.baseobject Text do 
			(
				v = (dotnetclass "System.String").Format "{0,7:0.00}" val 
				this.textNode.baseobject.text = v
			)
			val 
		)
		else val 
		
		on unit set val do if iskindof speed.controller Float_Script do speed.controller.Update()
	)
	rollout params "Parameters"
	(
		label lb_delta "Time Delta(s):" across:2 align:#right offset:[-4,1]
		spinner ui_delta fieldwidth:64 range:[-1e9,1e9,0.01] type:#float align:#right offset:[6,0] enabled:off
		
		local unit_labels = 
		#(
			"units per time delta", 
			"units per second", 
			"meters per second", 
			"kilometers per hour", 
			"miles per hour",
			"units per frame" 
		)
		label lb_unit "Units:" across:2 align:#right offset:[-43,8]
		radiobuttons ui_unit labels:unit_labels default:1 align:#left offset:[-38,7]
		label lb_speed "Local Speed:" across:2 align:#right offset:[-4,8]
		spinner ui_speed fieldwidth:64 range:[-1e9,1e9,0] type:#float align:#right offset:[6,7] enabled:off
	)
	parameters textOutput rollout:textOutput
	(
		textNode type:#node subanim:on ui:ui_textNode
	)
	fn onlyText node = (iskindof node.baseobject Text) 
	rollout textOutput "Text Output Node" 
	(
		pickbutton ui_textNode "Pick Text Node" autoDisplay:on filter:onlyText width:152 align:#right offset:[8,0]
	)
	
	on attachedToNode node do 
	(
		synchTarget()
	)
	on update do 
	(
		synchTarget()
	)
)


delete objects
b = box isselected:on
t = text font:"Courier New"
addmodifier b (Speedometer unit:2 textNode:t)
with animate on at time 100 b.pos = [0,200,0]

i met an interesting problem… as you see i use fixed-size font with the Text shape, i make formatted string on 7 symbols, but it doesn’t help me to have the text at the same place all the time. that was really fun to find a solution. do you see any?

Not exactly sure but i would guess that it is a kerning issue. It looks like the space is changing dynamically based on the width of the number and thats why its moving around.
So even if you are using a string with seven symbols… all 1’s would be less wide then all 9’s.

btw… you can take a look how i format the string using .net. in our case it works better than mxs formattedprint

That does work better. I don’t really understand why the formattedprint didn’t work in the float_script though. So is it the kerning in the text object that makes the decimal place wobble around?

Page 2 / 2