| accessing |
| addViewingParticipant: aParticipant
|
^self addViewingParticipants: { aParticipant }.
|
| addViewingParticipants: someParticipants
|
teaParty join: someParticipants.
self frameChildrenDo: [ :fc | fc addViewingParticipants: someParticipants ].
|
| boundSphere
|
" This will return a render bounds object if one exists. This is a TBoundSphere (location + radius), which is used to determine if a particular object is inside the clipping planes or for collision detection tests. Otherwise, the object will be assumed to have a local coordinate location of 0,0,0 and a radius of 1.0."
^ nil.
|
| boundingBox
|
"Answer the bounding box for the receiver and its children"
^ self boundingBox: B3DMatrix4x4 identity.
|
| boundingBox: trans
|
"Answer the bounding box for the receiver and its children"
| box childBox |
box := self frameBox.
self frameChildrenDo:[:child|
childBox := child boundingBox transformedBy: (trans composeWith: child localTransform).
box := box merge: childBox.
].
^box
|
| boundsChanged
|
" Does nothing"
|
| boundsDepth: depth
|
frameChildren ifNotNil:[
frameChildren do:[:fc | fc boundsDepth: depth].].
|
| changed: frame
|
" Does nothing, just forward on to parent."
self parent ifNotNil:[self parent changed: frame.]
|
| childChanged
|
self childChanged: self.
|
| childChanged: frame
|
" Does nothing, just forward on to parent."
self parent ifNotNil:[self parent changed: frame.]
|
| colorize: color
|
"used by buttons and things - this just keeps us out of trouble for now, though I may need it later..."
|
| compositeBoundSphere
|
"Answer either my own or a composition of my children's bound spheres"
| children bSphere |
children := OrderedCollection new.
self boundSpheresDo:[:bs|
bSphere := bs union: bSphere.
children add: bs.
].
children size = 0 ifTrue:[^nil].
children size = 1 ifTrue:[^children first].
bSphere children: children.
bSphere frame: self.
bSphere transform: self globalTransform.
^bSphere
|
| disableCaching.
|
|
| disableCachingTree
|
.
self do:[ :f | f disableCaching ].
|
| distanceTo: aFrame
|
^(self globalPosition - aFrame globalPosition) length
|
| do: block
|
block value: self.
frameChildren ifNotNil:[
frameChildren do:[ :fc | fc do: block].].
|
| extent
|
"Answer the bounding box for the receiver and its children"
^ self boundingBox extent.
|
| extent: ext
|
"Does nothing"
|
| find: blockTest
|
| list |
blockTest ifNil:[^ nil].
list _ OrderedCollection new.
self find: blockTest into: list.
^ list.
|
| find: blockTest into: list
|
frameChildren ifNotNil:[
frameChildren do:[ :fc | fc find: blockTest into: list].].
(blockTest value: self) ifTrue:[ list add: self].
|
| frameBox
|
"Answer the local bounding box of this frame"
^TBox origin: 0@0@0 corner: 0@0@0
|
| frameChanged
|
" This guarantees that if we make a change in a parent frame, all of the children are aware and can deal with it properly."
frameChanged _ true.
frameChildren ifNotNil:[
frameChildren do:[ :child | child frameChanged ].].
myEventMap ifNotNil:[self signal: #frameChanged]. "to inform interested parties"
myPlayer ifNotNil:[myPlayer signal: #frameChanged].
|
| frameChildren
|
^ frameChildren.
|
| frameChildrenDo: aBlock
|
frameChildren ifNil:[^self].
^frameChildren do: aBlock
|
| fullBright: bool
|
frameChildren ifNotNil:[frameChildren do:[:fc | fc fullBright: bool]].
|
| getFrameChanged
|
^ frameChanged.
|
| globalToLocal: anObject
|
^self globalTransform inverseTransformation localPointToGlobal: anObject
|
| hasAlpha
|
" Does this object have an alpha channel to render? Return true if it does."
^ false.
|
| inertiaTensor
|
^ nil.
|
| localToGlobal: anObject
|
^self globalTransform localPointToGlobal: anObject
|
| locator
|
"Return a locator telling us where to find this guy on the net"
^nil
|
| lookAt
|
^ self globalTransform column3.
|
| lookSide
|
^ self globalTransform column1.
|
| lookUp
|
^ self globalTransform column2.
|
| material
|
frameChildren isEmptyOrNil ifTrue:[^nil].
^frameChildren anyOne material
|
| material: mat
|
frameChildren ifNil:[^self].
frameChildren do:[:each| each material: mat].
|
| materialAlpha: ignored
|
"backstop"
|
| objectName
|
^objectName
|
| objectName: oName
|
objectName _ oName.
|
| objectOwner
|
objectOwner ifNil:[
frameParent ifNotNil:[^ frameParent objectOwner.].].
^ objectOwner.
|
| objectOwner: oOwner
|
objectOwner _ oOwner.
self isComponent ifFalse:[
frameChildren ifNotNil:[
frameChildren do:[ :child | child objectOwner: oOwner. ].].].
|
| octreeBox
|
| box childBox bs |
box _ TBox new.
frameChildren ifNotNil:[
frameChildren do:[ :fc |
childBox _ fc octreeBox.
childBox ifNotNil:[
box _ box unionBox: childBox.].
].
].
bs _ self boundSphere.
bs ifNotNil:[
bs transform: self globalTransform.
box growVertex: bs globalPosition.
].
box min x > box max x ifTrue:[^ nil ].
^ box.
|
| octreeRadius
|
| rad childRad |
" Find the max bound sphere radius of the tree. This is used for quadtree/octree construction "
self boundSphere ifNotNil:[ rad _ self boundSphere radius.] ifNil:[ rad _ 0 ].
frameChildren ifNotNil:[
frameChildren do:[ :fc |
childRad _ fc octreeRadius.
rad _ rad max: childRad.
].
].
^ rad.
|
| octreeSieve: octree
|
| bs |
bs _ self boundSphere.
bs ifNotNil:[
bs transform: self globalTransform.
octree add: bs.
].
frameChildren ifNotNil:[
frameChildren do:[ :fc | fc octreeSieve: octree. ].
].
|
| parentChanged
|
self parentChanged: self.
|
| parentChanged: frame
|
" Does nothing, just forward on to children."
frameChildren ifNotNil:[frameChildren do:[:fc | fc parentChanged: frame].].
|
| scriptIcon
|
^self class scriptIcon
|
| selected: fc
|
"Inform the parent frame that this frame has been selected"
frameParent selected: fc.
|
| showFrame
|
" TFrame >> showFrame recursively climbs the frame's tree and outputs it the Transcript."
self showFrame: 0.
|
| showFrame: depth
|
1 to: depth do:[ :i | Transcript show:'---|'].
Transcript show: self objectName; cr.
self frameChildren ifNotNil:[
frameChildren do:[ : fc |
fc showFrame: depth+1.].].
|
| solid
|
^ solid.
|
| solid: bool
|
solid _ bool.
|
| solidTree: bool
|
self do:[ :f | f solid: bool].
|
| solidVisibleTree: bool
|
self solidTree: bool.
self visibleTree: bool.
|
| sphereTree
|
| bs |
bs _ self boundSphere.
bs ifNotNil:[
frameChildren ifNotNil:[ frameChildren do:[ :fc | bs _ bs union: (fc sphereTree).].].
^ bs.
].
frameChildren ifNotNil:[
frameChildren do:[ :fc |
bs ifNil:[ bs _ fc sphereTree. ]
ifNotNil: [bs _ bs union: (fc sphereTree). ].
].
^ bs.
].
^ nil.
|
| test
|
^ test.
|
| test: tst
|
test _ tst.
|
| transparency: trans
|
frameChildren ifNotNil:[
frameChildren do:[ :fc | fc transparency: trans].].
|
| viewingParticipants
|
^#(). "for frame roots that aren't spaces"
|
| visible
|
^ visible.
|
| visible: bool
|
visible _ bool.
|
| visibleTree
|
self visible ifTrue:[^ true].
frameChildren ifNotNil:[
frameChildren do:[ :fc | fc visibleTree ifTrue:[^ true].].].
^ false.
|
| visibleTree: bool
|
self do:[ :f | f visible: bool].
|
| frameManagement |
| addLightFrame: litefrm
|
frameParent ifNotNil:[frameParent addLightFrame: litefrm.]
|
| addLightFrames
|
" When a frame is added as a child, any lights included in the heirarchy are reported to the base TRoom."
self isLight ifTrue:[ self addLightFrame: self].
frameChildren ifNotNil: [frameChildren do:[ :fc | fc addLightFrames ].].
|
| addPortalFrame: prtlFrm
|
frameParent ifNotNil:[frameParent addPortalFrame: prtlFrm.]
|
| addPortalFrames
|
" When a frame is added as a child, any portals included in the heirarchy are reported to the base TRoom."
self isPortal ifTrue:[ self addPortalFrame: self].
frameChildren ifNotNil: [frameChildren do:[ :fc | fc addPortalFrames ].].
|
| addRayFrame: rayfrm
|
frameParent ifNotNil:[frameParent addRayFrame: rayfrm.]
|
| addRayFrames
|
" When a frame is added as a child, any rays included in the heirarchy are reported to the base TSpace."
self isRay ifTrue:[ self addRayFrame: self].
frameChildren ifNotNil: [frameChildren do:[ :fc | fc addRayFrames ].].
|
| forceGlobalToLocal
|
"This is used by TMesh when the imported vertices are pre-transformed, and all of the nodes are in global coordinates and we want to put them back into their untransformed state. This occurs with the 3DS Max ASE files."
frameChildren ifNotNil:[ frameChildren do:[ :fc | fc forceGlobalToLocal.]].
frameParent ifNotNil:[
self localTransform: (
frameParent localTransform orthoNormInverse composeWith: self localTransform).
].
|
| removeLightFrame: litefrm
|
frameParent ifNotNil:[frameParent removeLightFrame: litefrm.]
|
| removeLightFrames
|
" When a frame is disconnected from its parent, we need to remove the references to the lights in the TRoom."
self isLight ifTrue:[self removeLightFrame: self.].
frameChildren ifNotNil:[frameChildren do:[ :fc | fc removeLightFrames ].].
|
| removePortalFrame: prtlFrm
|
frameParent ifNotNil:[frameParent removePortalFrame: prtlFrm.]
|
| removePortalFrames
|
" When a frame is disconnected from its parent, we need to remove the references to the lights in the TRoom."
self isPortal ifTrue:[self removePortalFrame: self.].
frameChildren ifNotNil:[frameChildren do:[ :fc | fc removePortalFrames ].].
|
| removeRayFrame: rayfrm
|
frameParent ifNotNil:[frameParent removeRayFrame: rayfrm.]
|
| removeRayFrames
|
" When a frame is disconnected from its parent, we need to remove the references to the rays in the TSpace."
self isRay ifTrue:[self removeRayFrame: self.].
frameChildren ifNotNil:[frameChildren do:[ :fc | fc removeRayFrames ].].
|
| replaceChild: oldChild with: newChild
|
| |
oldChild removeLightFrames.
oldChild removePortalFrames.
oldChild removeRayFrames.
frameChildren replace: oldChild with: newChild.
oldChild isComponent ifTrue:[ oldChild stopStepping.].
oldChild parent: nil.
newChild isComponent ifTrue: [ newChild startStepping. ].
newChild parent: self.
newChild addLightFrames.
newChild addPortalFrames.
newChild addRayFrames.
|
| hierarchy |
| addChild: child
|
frameChildren ifNil:[frameChildren _ OrderedCollection new.].
"If child singleParent is true, then we can not add this frame until we have removed it from a previous parent."
child singleParent ifTrue:[
child parent ifNotNil:[child parent removeChild: child].
self singleParent: true.].
"make sure child and all its subframes are informed of all viewers so they can be added to their tea parties"
child addViewingParticipants: self root viewingParticipants.
frameChildren add: child.
child isComponent ifTrue: [ child startStepping].
child parent: self.
child addLightFrames.
child addPortalFrames.
child addRayFrames.
myPlayer ifNotNil:[myPlayer signal: #structureChanged].
|
| boundSpheresDo: aBlock
|
| bSphere |
bSphere := self boundSphere.
bSphere ifNotNil:[^aBlock value: bSphere].
frameChildren ifNil:[^self].
self frameChildren do:[:each| each boundSpheresDo: aBlock].
|
| child: index
|
^frameChildren at: index.
|
| collapse
|
"Forces all frames to identity transform while retaining translation, and pushes the previous transform to the frame children. This is used primarily for meshes and their supporting groups."
| orient trans |
trans _ self translation.
orient _ self orientation.
frameChildren ifNotNil:[
frameChildren do:[ :fc |
fc localTransform: (orient composeWith: fc localTransform).
fc collapse.
].
].
self localTransform: B3DMatrix4x4 identity.
self translation: trans.
|
| currentParent: fParent
|
frameParent _ fParent.
|
| destroy
|
frameParent ifNotNil:[frameParent removeChild: self].
|
| doesNotUnderstand: aMessage
|
"Check for new user messages"
Transcript cr; show: 'Error: '; show: self; show:' '; show: aMessage.
(self compileYellowScript: aMessage) ifTrue:[^aMessage sentTo: self].
^super doesNotUnderstand: aMessage
|
| hasChild: child
|
frameChildren ifNotNil:[
frameChildren do:[:fc |
fc = child ifTrue:[^ true ].].].
^ false.
|
| insertFrame: frm
|
| parent |
self parent ifNotNil:[
parent _ self parent.
parent removeChild: self.
parent addChild: frm.
].
frm addChild: self.
|
| isChild: parent
|
^ parent hasChild: self.
|
| parent
|
^frameParent.
|
| parent: fParent
|
self frameChanged.
frameParent _ fParent.
|
| prune
|
"
frameChildren ifNotNil:[
frameChildren do:[ :fc | fc prune ifTrue:[
self removeChild: fc.].].
frameChildren size = 0 ifTrue:[frameChildren _ nil].
].
(self class = TFrame and:[ frameChildren = nil ])ifTrue:[^true].
^ false."
|
| removeAll
|
| child |
frameChildren ifNil:[^nil.].
[frameChildren size = 0] whileFalse:[
child _ frameChildren at: 1.
frameChildren removeAt: 1.
child removeLightFrames.
child removePortalFrames.
].
frameChildren _ nil.
|
| removeChild: child
|
| |
child removeLightFrames.
child removePortalFrames.
child removeRayFrames.
frameChildren ifNotNil:[frameChildren remove: child ifAbsent:[].].
child isComponent ifTrue:[ child stopStepping. ].
child parent: nil.
myPlayer ifNotNil:[myPlayer signal: #structureChanged].
|
| removeSelf
|
self parent ifNotNil:[
self parent removeChild: self.].
|
| root
|
frameParent ifNil:[^ self] ifNotNil:[^ frameParent root.].
|
| singleParent
|
" singleParent forces a frame to only have one parent. Most frames enable multiple parents to easily enable instancing of the objects. However, certain object types such as lights and cameras can NOT be instanced. If singleParent is set to true, if a frame is added as a child to a new parent, it will be removed from the previous parent frame first."
^singleParent.
|
| singleParent: bool
|
singleParent _ bool.
|
| transferTo: frame
|
self parent ifNotNil:[ self parent removeChild: self].
frame addChild: self.
|
| render |
| makeThumb: ogl
|
| rect thumb vis|
vis _ self visible.
self visible: false."avoid recursion."
rect _(0@0 corner: 128@96).
ogl renderWait:[thumb _ self root snapShot: ogl rectangle: rect atLoc: self globalTransform view: 45.0.].
self visible: vis.
^ thumb.
|
| pick: pointer
|
^ false
|
| pickFloor: pointer
|
^ self pick: pointer.
|
| render: ogl
|
ogl glDisable: GLLighting;
" This is used to render solid objects (if any). "
glColor3fv: #(1.0 0 0)asFloatArray;
glBegin: GLLineStrip;
glVertex3fv:#(0.0 0.0 0.0)asFloatArray;
glVertex3fv:#(1.0 0.0 0.0)asFloatArray;
glVertex3fv:#(0.75 0.25 0.0)asFloatArray;
glVertex3fv:#(0.75 -0.25 0.0)asFloatArray;
glVertex3fv:#(1.0 0.0 0.0)asFloatArray;
glVertex3fv:#(0.75 0.0 0.25)asFloatArray;
glVertex3fv:#(0.75 0.0 -0.25)asFloatArray;
glVertex3fv:#(1.0 0.0 0.0)asFloatArray;
glEnd;
glColor3fv: #(0.0 1.0 0)asFloatArray;
glBegin: GLLineStrip;
glVertex3fv:#(0.0 0.0 0.0)asFloatArray;
glVertex3fv:#(0.0 1.0 0.0)asFloatArray;
glVertex3fv:#(0.0 0.75 0.25)asFloatArray;
glVertex3fv:#(0.0 0.75 -0.25)asFloatArray;
glVertex3fv:#(0.0 1.0 0.0)asFloatArray;
glVertex3fv:#(0.25 0.75 0.0)asFloatArray;
glVertex3fv:#(-0.25 0.75 0.0)asFloatArray;
glVertex3fv:#(0.0 1.0 0.0)asFloatArray;
glEnd;
glColor3fv: #(0.0 0.0 1.0)asFloatArray;
glBegin: GLLineStrip;
glVertex3fv:#(0.0 0.0 0.0)asFloatArray;
glVertex3fv:#(0.0 0.0 1.0)asFloatArray;
glVertex3fv:#(0.25 0.0 0.75)asFloatArray;
glVertex3fv:#(-0.25 0.0 0.75)asFloatArray;
glVertex3fv:#(0.0 0.0 1.0)asFloatArray;
glVertex3fv:#(0.0 0.25 0.75)asFloatArray;
glVertex3fv:#(0.0 -0.25 0.75)asFloatArray;
glVertex3fv:#(0.0 0.0 1.0)asFloatArray;
glEnd;
glEnable: GLLighting.
|
| render: ogl box: box
|
| |
self render: ogl cube: box location: box center scale: 1.0.
|
| render: ogl cube: cube location: loc scale: scale
|
| dx dy dz x y z |
" This message is used only to make sure a frame is actually drawing something. In this case, I draw a cube. "
dx _ scale/2.0.
dy _ scale/2.0.
dz _ scale/2.0.
x _ loc x.
y _ loc y.
z _ loc z.
ogl glBegin: GLQuads;
glNormal3f: 0.0 with: 0.0 with: 1.0;
glTexCoord2f:0.0 with:1.0; glVertex3f: x+(dx negated) with: y+(dy negated) with: z+dz;
glTexCoord2f:1.0 with:1.0; glVertex3f: x+dx with: y+(dy negated) with: z+dz;
glTexCoord2f:1.0 with:0.0; glVertex3f: x+dx with: y+dy with: z+dz;
glTexCoord2f:0.0 with: 0.0; glVertex3f: x+(dx negated) with: y+dy with: z+dz.
dz _ dz negated.
ogl glNormal3f: 0.0 with: 0.0 with: -1.0;
glTexCoord2f:1.0 with: 0.0; glVertex3f: x+(dx negated) with: y+dy with: z+dz;
glTexCoord2f:0.0 with:0.0; glVertex3f: x+dx with: y+dy with: z+dz;
glTexCoord2f:0.0 with:1.0; glVertex3f: x+dx with: y+(dy negated) with: z+dz;
glTexCoord2f:1.0 with:1.0; glVertex3f: x+(dx negated) with: y+(dy negated) with: z+dz.
dz _ dz negated.
ogl glNormal3f: 1.0 with: 0.0 with: 0.0;
glTexCoord2f:0.0 with:1.0; glVertex3f: x+dx with: y+(dy negated) with: z+dz;
glTexCoord2f:1.0 with:1.0; glVertex3f: x+dx with: y+(dy negated) with: z+(dz negated);
glTexCoord2f:1.0 with: 0.0; glVertex3f: x+dx with: y+dy with: z+(dz negated);
glTexCoord2f:0.0 with: 0.0; glVertex3f: x+dx with: y+dy with: z+dz.
dx _ dx negated.
ogl glNormal3f: -1.0 with: 0.0 with: 0.0;
glTexCoord2f:1.0 with: 0.0; glVertex3f: x+dx with: y+dy with: z+dz;
glTexCoord2f:0.0 with:0.0; glVertex3f: x+dx with: y+dy with: z+(dz negated);
glTexCoord2f:0.0 with:1.0; glVertex3f: x+dx with: y+(dy negated) with: z+(dz negated);
glTexCoord2f:1.0 with:1.0; glVertex3f: x+dx with: y+(dy negated) with: z+dz.
dx _ dx negated.
ogl glNormal3f: 0.0 with: 1.0 with: 0.0;
glTexCoord2f:1.0 with: 0.0; glVertex3f: x+dx with: y+dy with: z+dz;
glTexCoord2f:0.0 with:0.0; glVertex3f: x+dx with: y+dy with: z+(dz negated);
glTexCoord2f:0.0 with:1.0; glVertex3f: x+(dx negated) with: y+dy with: z+(dz negated);
glTexCoord2f:1.0 with:1.0; glVertex3f: x+(dx negated) with: y+dy with: z+dz.
dy _ dy negated.
ogl glNormal3f: 0.0 with: -1.0 with: 0.0;
glTexCoord2f:0.0 with:1.0; glVertex3f: x+(dx negated) with: y+dy with: z+dz;
glTexCoord2f:1.0 with:1.0; glVertex3f: x+(dx negated) with: y+dy with: z+(dz negated);
glTexCoord2f:1.0 with:0.0; glVertex3f: x+dx with: y+dy with: z+(dz negated);
glTexCoord2f:0.0 with: 0.0; glVertex3f: x+dx with: y+dy with: z+dz.
ogl glEnd.
|
| render: ogl cube: box scale: scale
|
self renderCube: ogl location: 0.0@0.0@0.0 scale: scale.
|
| render: ogl sphere: bndSphr segments: segments
|
| position radius ringSin ringCos pi2 seg2 vert rts rbs rtc rbc ax u du v dv |
position _ bndSphr localPosition.
radius _ bndSphr radius.
seg2 _ 1+ (segments * 2) .
ringSin _ FloatArray ofSize: seg2.
ringCos _ FloatArray ofSize: seg2.
vert _ B3DVector3 new.
pi2 _ Float pi *2.0.
1 to: seg2-1 do:[ :index |
ax _ ((index) * pi2)/ (seg2-1).
ringSin at:index put: ax sin.
ringCos at:index put: ax cos.].
ringSin at: seg2 put: (ringSin at: 1).
ringCos at: seg2 put: (ringCos at: 1).
rts _ 0.0.
rtc _ 1.0.
rbs _ringSin at: 1.
rbc _ ringCos at: 1.
du _ 1.0/(seg2-1).
v _ 0.0.
dv _ 1.0/segments.
1 to: segments do:[ :iv |
ogl glBegin: GLTriangleStrip.
u _ 0.0.
1 to: seg2 do: [ :ih |
vert x: rts*(ringSin at: ih) y: rtc z: rts*(ringCos at: ih).
ogl glNormal3fv: vert;
glTexCoord2f: u with: v;
glVertex3fv: (vert * radius)+ position.
vert x: rbs*(ringSin at: ih) y: rbc z: rbs*(ringCos at: ih).
ogl glNormal3fv: vert;
glTexCoord2f: u with: v+dv;
glVertex3fv: (vert * radius)+ position.
u_ u+du.].
v _ v+dv.
rts _ rbs.
rtc _ rbc.
rbs _ ringSin at: iv+1.
rbc _ ringCos at: iv+1.
ogl glEnd.].
|
| renderAlpha: ogl
|
"This is used to render transparent ( alpha blended ) objects."
|
| renderCube: ogl location: loc scale: scale
|
| dx dy dz x y z |
" This message is used only to make sure a frame is actually drawing something. In this case, I draw a cube. "
dx _ scale/2.0.
dy _ scale/2.0.
dz _ scale/2.0.
x _ loc x.
y _ loc y.
z _ loc z.
ogl glBegin: GLQuads;
glNormal3f: 0.0 with: 0.0 with: 1.0;
glTexCoord2f:0.0 with:1.0; glVertex3f: x+(dx negated) with: y+(dy negated) with: z+dz;
glTexCoord2f:1.0 with:1.0; glVertex3f: x+dx with: y+(dy negated) with: z+dz;
glTexCoord2f:1.0 with:0.0; glVertex3f: x+dx with: y+dy with: z+dz;
glTexCoord2f:0.0 with: 0.0; glVertex3f: x+(dx negated) with: y+dy with: z+dz.
dz _ dz negated.
ogl glNormal3f: 0.0 with: 0.0 with: -1.0;
glTexCoord2f:1.0 with: 0.0; glVertex3f: x+(dx negated) with: y+dy with: z+dz;
glTexCoord2f:0.0 with:0.0; glVertex3f: x+dx with: y+dy with: z+dz;
glTexCoord2f:0.0 with:1.0; glVertex3f: x+dx with: y+(dy negated) with: z+dz;
glTexCoord2f:1.0 with:1.0; glVertex3f: x+(dx negated) with: y+(dy negated) with: z+dz.
dz _ dz negated.
ogl glNormal3f: 1.0 with: 0.0 with: 0.0;
glTexCoord2f:0.0 with:1.0; glVertex3f: x+dx with: y+(dy negated) with: z+dz;
glTexCoord2f:1.0 with:1.0; glVertex3f: x+dx with: y+(dy negated) with: z+(dz negated);
glTexCoord2f:1.0 with: 0.0; glVertex3f: x+dx with: y+dy with: z+(dz negated);
glTexCoord2f:0.0 with: 0.0; glVertex3f: x+dx with: y+dy with: z+dz.
dx _ dx negated.
ogl glNormal3f: -1.0 with: 0.0 with: 0.0;
glTexCoord2f:1.0 with: 0.0; glVertex3f: x+dx with: y+dy with: z+dz;
glTexCoord2f:0.0 with:0.0; glVertex3f: x+dx with: y+dy with: z+(dz negated);
glTexCoord2f:0.0 with:1.0; glVertex3f: x+dx with: y+(dy negated) with: z+(dz negated);
glTexCoord2f:1.0 with:1.0; glVertex3f: x+dx with: y+(dy negated) with: z+dz.
dx _ dx negated.
ogl glNormal3f: 0.0 with: 1.0 with: 0.0;
glTexCoord2f:1.0 with: 0.0; glVertex3f: x+dx with: y+dy with: z+dz;
glTexCoord2f:0.0 with:0.0; glVertex3f: x+dx with: y+dy with: z+(dz negated);
glTexCoord2f:0.0 with:1.0; glVertex3f: x+(dx negated) with: y+dy with: z+(dz negated);
glTexCoord2f:1.0 with:1.0; glVertex3f: x+(dx negated) with: y+dy with: z+dz.
dy _ dy negated.
ogl glNormal3f: 0.0 with: -1.0 with: 0.0;
glTexCoord2f:0.0 with:1.0; glVertex3f: x+(dx negated) with: y+dy with: z+dz;
glTexCoord2f:1.0 with:1.0; glVertex3f: x+(dx negated) with: y+dy with: z+(dz negated);
glTexCoord2f:1.0 with:0.0; glVertex3f: x+dx with: y+dy with: z+(dz negated);
glTexCoord2f:0.0 with: 0.0; glVertex3f: x+dx with: y+dy with: z+dz.
ogl glEnd.
|
| renderCube: ogl scale: scale
|
self renderCube: ogl location: 0.0@0.0@0.0 scale: scale.
|
| renderFrame: ogl parent: parent root: root
|
| count childCount globalTrans ac |
" I am running a parallel set of transforms here. Why? Because I am told the OGL is inefficient at reading the current transform. Easy to change."
" Any given frame can have multiple parents. This means that the frame can't keep a static reference to the parent frame. This must be dynamic, essentially filled out at render time. This allows for pure -instancing- of frame objects. That is, the same frame and all of its contents can easily be in multiple locations in the render tree without significant additional bookkeeping. It also means that when an object DOES need to refer to its parent or the space frame (read -root- for traditional approaches), this can ONLY be done at render-time via this mechanism. It also means that a child really must not modify the parent directly, as the parent has other responsibilities."
" #renderFrame: must return the number of objects that were rendered - failure to do so will just crash."
count _ 0.
(visible or:[frameChildren notNil])ifFalse:[^ 0 ].
self parent ~= parent ifTrue:[ self isSpace ifFalse:[self frameChanged. ]].
self currentParent: parent.
" apply the local transform to this matrix "
frameChanged ifTrue:[
self globalTransform: (parent globalTransform composeWith: localTransform).].
ogl glPushMatrix.
ogl glMultMatrixf: localTransform transposed.
self boundSphere ifNotNil:[
self boundSphere transform: globalTransform.
solid ifTrue:[ root testRayFrames: self boundSphere.].
].
"------ is this inside the viewing pyramid?"
ac _ ogl camera.
(visible and:[ac testBounds: self boundSphere]) ifTrue:[
ac pointer ifNotNil:[
ac inPortal ifTrue:[
(ac pointer pointerPick: self boundSphere).
]
ifFalse:[
self isPortal ifFalse:[
(ac pointer pointerPick: self boundSphere).
(ac downPointer pick: self boundSphere).
].
].
].
timeStamp _ ogl timeStamp.
count _ 1.
self render: ogl.
self hasAlpha ifTrue: [
globalTrans _ B3DMatrix4x4 new.
ogl glGetFloatv: GLModelviewMatrix with: globalTrans.
root addAlphaObject: self
transform: globalTrans
distance: ((ac globalPosition - globalPosition ) squaredLength * Processor activeProcess croquetWorld frameScaleSquared)
parent: parent.].].
frameChildren ifNotNil:[
" render all of the child frames "
childCount _ 0.
frameChildren do:[:rFrame | childCount _ childCount+(rFrame renderFrame: ogl parent: self root: root).].
childCount > 0 ifTrue:[count _ count+childCount. timeStamp _ ogl timeStamp.]
].
ogl glPopMatrix.
^ count.
|
| renderFrame: ogl space: space
|
| saveParent saveTransform count childCount globalTrans ac |
" I am running a parallel set of transforms here. Why? Because I am told the OGL is inefficient at reading the current transform. Easy to change."
Transcript show:'TFrame>>#renderFrame:space: is deprecated.';cr.
" Any given frame can have multiple parents. This means that the frame can't keep a static reference to the parent frame. This must be dynamic, essentially filled out at render time. This allows for pure -instancing- of frame objects. That is, the same frame and all of its contents can easily be in multiple locations in the render tree without significant additional bookkeeping. It also means that when an object DOES need to refer to its parent or the space frame (read -root- for traditional approaches), this can ONLY be done at render-time via this mechanism. It also means that a child really must not modify the parent directly, as the parent has other responsibilities."
" #renderFrame: must return the number of objects that were rendered - failure to do so will just crash."
count _ 0.
(visible or:[frameChildren notNil])ifFalse:[^ 0 ].
saveParent _ space currentParent.
self parent ~= saveParent ifTrue:[ self isSpace ifFalse:[self frameChanged. ]].
self currentParent: saveParent.
space currentParent: self.
" apply the local transform to this matrix "
saveTransform _ space currentTransform.
saveTransform ifNotNil: [
space currentTransform: (saveTransform composeWith: localTransform).]
ifNil:[space currentTransform: localTransform. ].
ogl glPushMatrix.
ogl glMultMatrixf: localTransform transposed.
self boundSphere ifNotNil:[
self boundSphere transform: space currentTransform.
solid ifTrue:[ space testRayFrames: self boundSphere.].
].
"------ is this inside the viewing pyramid?"
ac _ ogl camera.
(visible and:[ac testBounds: self boundSphere]) ifTrue:[
ac pointer ifNotNil:[
ac inPortal ifTrue:[
(ac pointer pointerPick: self boundSphere)
]
ifFalse:[
self isPortal ifFalse:[
(ac pointer pointerPick: self boundSphere)
].
].
].
timeStamp _ ogl timeStamp.
count _ 1.
self render: ogl.
self hasAlpha ifTrue: [
globalTrans _ B3DMatrix4x4 new.
ogl glGetFloatv: GLModelviewMatrix with: globalTrans.
space addAlphaObject: self
transform: globalTrans "space currentTransform clone"
distance: ((ac globalPosition - space currentTranslation ) squaredLength * Processor activeProcess croquetWorld frameScaleSquared)
parent: space currentParent.].].
frameChildren ifNotNil:[
" render all of the child frames "
childCount _ 0.
frameChildren do:[:rFrame | childCount _ childCount+(rFrame renderFrame: ogl space: space).].
childCount > 0 ifTrue:[count _ count+childCount. timeStamp _ ogl timeStamp.]
].
ogl glPopMatrix.
space currentTransform: saveTransform.
space currentParent: saveParent.
^ count.
|
| transform |
| addRotationAroundX: anAngle
|
| trans rtrans |
self frameChanged.
rtrans _ B3DMatrix4x4 identity.
rtrans rotationAroundX: anAngle.
trans _ self translation.
localTransform _ rtrans composeWith:localTransform.
self translation: trans.
^ localTransform.
|
| addRotationAroundY: anAngle
|
| trans rtrans |
self frameChanged.
rtrans _ B3DMatrix4x4 identity.
rtrans rotationAroundY: anAngle.
trans _ self translation.
localTransform _ rtrans composeWith:localTransform.
self translation: trans.
^ localTransform.
|
| addRotationAroundZ: anAngle
|
| trans rtrans |
self frameChanged.
rtrans _ B3DMatrix4x4 identity.
rtrans rotationAroundZ: anAngle.
trans _ self translation.
localTransform _ rtrans composeWith:localTransform.
self translation: trans.
^ localTransform.
|
| addYaw: y
|
self yaw: self yaw + y.
|
| globalMatrixOut
|
" This simply reverses the direction of the matrix. An example of use is for TPortals, where the global matrix used for rendering the outside of the portal is the reverse of the exiting render, hence we need to flip the matrix around to get what we want."
| gt |
gt _ self globalTransform copy.
gt a11: 0.0 - gt a11.
gt a21: 0.0 - gt a21.
gt a31: 0.0 - gt a31.
gt a13: 0.0 - gt a13.
gt a23: 0.0 - gt a23.
gt a33: 0.0 - gt a33.
^ gt
|
| globalOrientation
|
"This is used to return just the orientation part of the matrix.The translation part is 0.0."
| mat |
mat _ self globalTransform clone.
mat translationX: 0.0 y: 0.0 z: 0.0.
^ mat.
|
| globalPitch
|
^self globalPitchYawRoll x
|
| globalPitchYawRoll
|
globalTransform ifNil:[^ 0.0@0.0@0.0].
^globalTransform pitchYawRoll
|
| globalPosition
|
frameChanged ifTrue:[ self globalTransform. ].
^ globalPosition.
"
^ self globalTransform translation.
"
|
| globalPosition: gp
|
self globalTransform.
frameChanged _ false.
globalPosition _ gp.
globalTransform translation: gp.
|
| globalRoll
|
^self globalPitchYawRoll z
|
| globalTransform
|
" This is the global transform of the frame - its location and orientation in global world coordinates. We only
calculate this when we have to, which is only when a local coordinate frame has been changed AND when someone asks for it. "
frameChanged ifTrue:[
frameParent ifNotNil: [ self globalTransform:
((frameParent globalTransform) composeWith: self localTransform)] ifNil:[
self globalTransform: self localTransform.].
globalPosition _ globalTransform translation.
].
^ globalTransform.
" NOT ^ self globalTransform - this causes bad recursion error!"
|
| globalTransform: gTrans
|
frameChanged _ false.
globalTransform _ gTrans.
globalPosition _ globalTransform translation.
self globalTransformUpdate.
^ globalTransform.
|
| globalTransformUpdate
|
" This is called when a new global transfom is calculated. It is designed to be extended by other frame sub-classes, such as TRigidBody, that would have variables that should be updated once when the frame gets changed."
|
| globalYaw
|
^self globalPitchYawRoll y
|
| gotoCamera
|
self translation: (Croquet world activeCamera translation)
|
| inverseGlobalOrientation
|
^ self globalOrientation orthoNormInverse.
|
| inverseGlobalTransform
|
^ self globalTransform orthoNormInverse.
|
| localTransform
|
^localTransform.
|
| localTransform: m4x4
|
self frameChanged.
localTransform _ m4x4.
|
| lookAt: v up: u
|
| at side m trans up |
up _ u.
trans _ self translation.
at _ trans - v.
at normalize.
up ifNil:[
at y abs = 1.0 ifFalse:[ up _ B3DVector3 x: 0 y: 1 z: 0.] ifTrue:[
up _ B3DVector3 x:0 y:0 z:-1].].
side _ (at cross: up) normalized negated.
up _ (side cross: at) normalized negated.
m _ B3DMatrix4x4 identity.
m a11: side x.
m a21: side y.
m a31: side z.
m a12: up x.
m a22: up y.
m a32: up z.
m a13: at x.
m a23: at y.
m a33: at z.
self localTransform: m.
self translation: trans.
|
| orientation
|
"This is used to return just the orientation part of the matrix.The translation part is 0.0."
| mat |
mat _ localTransform clone.
mat translationX: 0.0 y: 0.0 z: 0.0.
^ mat.
|
| orientation: mat
|
"This is used to set just the orientation part of the matrix. It keeps the translation parts intact."
| trans |
self frameChanged.
trans _ self translation.
localTransform _ mat clone.
self translation: trans.
^ localTransform.
|
| pitch
|
^self pitchYawRoll x
|
| pitch: p
|
| angles |
angles := self pitchYawRoll.
angles x: p.
self pitchYawRoll: angles.
|
| pitchYawRoll
|
^localTransform pitchYawRoll
|
| pitchYawRoll: aVector
|
| tfm |
tfm := localTransform copy pitchYawRoll: aVector.
self localTransform: tfm.
|
| pitchYawRollBy: delta
|
self pitchYawRoll: self pitchYawRoll + delta
|
| quaternion
|
^ localTransform asQuaternion.
|
| relativeTransform: frame
|
^ self globalTransform orthoNormInverse composeWith: frame globalTransform.
|
| releaseToRoot
|
"Transfer the frame from the current parent to the root frame while keeping the pose in exactly the same orientation"
| trans root |
trans _ self globalTransform.
root _ self root.
self transferTo: root.
self localTransform: trans.
|
| roll
|
^self pitchYawRoll z
|
| roll: r
|
| angles |
angles := self pitchYawRoll.
angles z: r.
self pitchYawRoll: angles.
|
| rotFromBallPoints: from to: to
|
| f t |
" This matrix needs to be transposed to convert from left handed to right (which is OpenGL's world)."
f _ from normalized.
t _ to normalized.
f _ (f+t) normalized.
f _ (f+t) normalized.
^ (B3DRotation a: (f x * t x) + (f y * t y) + (f z * t z )
b: (f y * t z) - (f z * t y)
c: (f z * t x) - (f x * t z)
d: (f x * t y) - (f y * t x)
).
|
| rotation: anAngle around: aVector3
|
| trans |
self frameChanged.
trans _ self translation.
localTransform rotation: anAngle around: aVector3.
self translation: trans.
^ localTransform.
|
| rotation: anAngle aroundX: xValue y: yValue z: zValue
|
| trans |
self frameChanged.
trans _ self translation.
localTransform rotation: anAngle aroundX: xValue y: yValue z: zValue.
self translation: trans.
^ localTransform.
|
| rotationAroundX: anAngle
|
| trans |
self frameChanged.
trans _ self translation.
localTransform rotationAroundX: anAngle.
self translation: trans.
^ localTransform.
|
| rotationAroundY: anAngle
|
| trans |
self frameChanged.
trans _ self translation.
localTransform rotationAroundY: anAngle.
self translation: trans.
^ localTransform.
|
| rotationAroundZ: anAngle
|
| trans |
self frameChanged.
trans _ self translation.
localTransform rotationAroundZ: anAngle.
self translation: trans.
^ localTransform.
|
| scale
|
^ 1.0.
|
| scale: scale
|
self translation: scale * self translation.
frameChildren ifNotNil:[
frameChildren do:[ :fc | fc scale: scale.]].
|
| transformBy: m4x4
|
self frameChanged.
localTransform _ localTransform composedWithLocal: m4x4.
|
| translation
|
^localTransform translation.
|
| translation: aVector
|
self frameChanged.
^localTransform translation: aVector.
|
| translationX: xValue y: yValue z: zValue
|
self frameChanged.
^ localTransform translationX: xValue y: yValue z: zValue.
|
| yaw
|
^self pitchYawRoll y
|
| yaw: y
|
| angles |
angles := self pitchYawRoll.
angles y: y.
self pitchYawRoll: angles.
|
| yawTransform
|
| v |
v _ localTransform row3.
v x > 0 ifTrue:[self yaw: v z arcCos radiansToDegrees negated] ifFalse:
[self yaw: v z arcCos radiansToDegrees.].
|
| yellow-scripts |
| dropFart: aRadius rate: aSamplingRate
|
| radius rate fartLoc newLoc fart stepT nextT script |
radius _ aRadius ifNil:[0.3].
rate _ aSamplingRate ifNil:[4].
stepT _ 1000.0 / rate.
nextT _ Processor activeProcess new + stepT.
fartLoc _ self translation.
script := Processor activeProcess.
[true] whileTrue:[
nextT waitUntil.
nextT _ nextT + stepT.
newLoc _ self translation.
fartLoc = newLoc ifFalse:[
fartLoc _ newLoc.
fart _ TSphere new.
fart material: ((TMaterial new) color: Color white).
fart radius: radius.
fart translation: fartLoc.
fart segments: 2.
self root addChild: fart.
fart startScript: #fadeOut:style:rate: withArguments:{3. nil. nil}.
].
"see if a stop was requested"
script isStopRequested ifTrue:[^self].
].
|
| fadeOut: aDuration style: aStyle rate: aSamplingRate
|
| duration style rate endState styleFunc lastState startState deltaTime msecsDuration proportion newState progressT startT script |
duration _ aDuration ifNil:[self defaultDuration].
style _ aStyle ifNil:[self defaultInterpolationStyle].
rate _ aSamplingRate ifNil:[self defaultSamplingRate].
"Get the ultimate state we're interested in"
endState := 0.0.
duration <= 0 ifTrue:[^self setAlpha: endState].
"Compute msecs since that's what we'll be working on here"
msecsDuration := duration * 1000.
"Get the interpolation function (evaluating from 0-1 and returning values from 0-1)"
styleFunc := style asScriptStyle.
"Reset the interpolation state"
lastState := startState := self getAlpha.
"And go moving until we're out of time"
rate _ msecsDuration * rate // 1000.
deltaTime _ msecsDuration // rate.
startT _ Croquet teaTime.
script := Processor activeProcess.
1 to: rate do:[:i|
progressT _ (i * deltaTime) asFloat.
(startT + progressT) waitUntil. "<-- here is where tea scheduling kicks in"
"Compute the proportion of time that's over"
proportion := progressT / msecsDuration asFloat.
"Map it through the interpolation style"
proportion := styleFunc value: proportion.
"Compute the state (e.g., offset) at our new proportion"
newState := startState interpolateTo: endState at: proportion.
"Transform incrementally - this is so that we can superimpose animations."
self setAlpha: (self getAlpha + newState - lastState).
"Remember last state for the next round"
lastState := newState.
"see if a stop was requested"
script isStopRequested ifTrue:[^self].
].
(startT + msecsDuration) waitUntil. "<-- here is where tea scheduling kicks in"
"Apply the remaining part of the transform (if any)"
self setAlpha: (self getAlpha + endState - lastState).
frameParent removeChild: self.
|
| forwardBy: aDistance duration: aDuration style: aStyle rate: aSamplingRate
|
^self move: #forward distance: aDistance duration: aDuration style: aStyle rate: aSamplingRate
|
| move: aDirection distance: aDistance duration: aDuration style: aStyle rate: aSamplingRate
|
| direction distance duration style rate endState styleFunc lastState startState deltaTime msecsDuration proportion newState startT progressT script |
direction _ aDirection ifNil:[self defaultDirection].
distance _ aDistance ifNil:[self defaultDistance].
duration _ aDuration ifNil:[self defaultDuration].
style _ aStyle ifNil:[self defaultInterpolationStyle].
rate _ aSamplingRate ifNil:[self defaultSamplingRate].
"Get the ultimate state we're interested in"
endState := direction asMoveDirection * distance.
duration <= 0 ifTrue:[^self transformBy: (B3DMatrix4x4 withOffset: endState)].
"Compute msecs since that's what we'll be working on here"
msecsDuration := duration * 1000.
"Get the interpolation function (evaluating from 0-1 and returning values from 0-1)"
styleFunc := style asScriptStyle.
"Reset the interpolation state"
lastState := startState := 0@0@0.
"And go moving until we're out of time"
rate _ msecsDuration * rate // 1000.
deltaTime _ msecsDuration // rate.
startT _ Croquet teaTime.
script := Processor activeProcess.
1 to: rate do:[:i|
progressT _ (i*deltaTime) asFloat.
(startT + progressT) waitUntil. "<-- here is where tea scheduling kicks in"
"Compute the proportion of time that's over"
proportion := progressT / msecsDuration asFloat.
"Map it through the interpolation style"
proportion := styleFunc value: proportion.
"Compute the state (e.g., offset) at our new proportion"
newState := startState interpolateTo: endState at: proportion.
"Transform incrementally - this is so that we can superimpose animations."
self transformBy: (B3DMatrix4x4 withOffset: newState - lastState).
"Remember last state for the next round"
lastState := newState.
"see if a stop was requested"
script isStopRequested ifTrue:[^self].
].
(startT + msecsDuration) waitUntil. "<-- here is where tea scheduling kicks in"
"Apply the remaining part of the transform (if any)"
self transformBy: (B3DMatrix4x4 withOffset: endState - lastState).
|
| moveBy: aDirection duration: aDuration style: aStyle rate: aSamplingRate
|
| direction duration style rate endState styleFunc lastState startState deltaTime msecsDuration proportion newState startT progressT script |
direction _ aDirection ifNil:[self defaultDirection asMoveDirection * self defaultDistance].
duration _ aDuration ifNil:[self defaultDuration].
style _ aStyle ifNil:[self defaultInterpolationStyle].
rate _ aSamplingRate ifNil:[self defaultSamplingRate].
"Get the ultimate state we're interested in"
endState := direction.
duration <= 0 ifTrue:[^self transformBy: (B3DMatrix4x4 withOffset: endState)].
"Compute msecs since that's what we'll be working on here"
msecsDuration := duration * 1000.
"Get the interpolation function (evaluating from 0-1 and r
|