Page Menu
Home
Code
Search
Configure Global Search
Log In
Files
F391686
object.js
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
33 KB
Subscribers
None
object.js
View Options
if
(
!
dojo
.
_hasResource
[
"dojox.gfx3d.object"
]){
//_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo
.
_hasResource
[
"dojox.gfx3d.object"
]
=
true
;
dojo
.
provide
(
"dojox.gfx3d.object"
);
dojo
.
require
(
"dojox.gfx"
);
dojo
.
require
(
"dojox.gfx3d.lighting"
);
dojo
.
require
(
"dojox.gfx3d.scheduler"
);
dojo
.
require
(
"dojox.gfx3d.vector"
);
dojo
.
require
(
"dojox.gfx3d.gradient"
);
// FIXME: why the global "out" var here?
var
out
=
function
(
o
,
x
){
if
(
arguments
.
length
>
1
){
// console.debug("debug:", o);
o
=
x
;
}
var
e
=
{};
for
(
var
i
in
o
){
if
(
i
in
e
){
continue
;
}
// console.debug("debug:", i, typeof o[i], o[i]);
}
};
dojo
.
declare
(
"dojox.gfx3d.Object"
,
null
,
{
constructor
:
function
(){
// summary: a Object object, which knows how to map
// 3D objects to 2D shapes.
// object: Object: an abstract Object object
// (see dojox.gfx3d.defaultEdges,
// dojox.gfx3d.defaultTriangles,
// dojox.gfx3d.defaultQuads
// dojox.gfx3d.defaultOrbit
// dojox.gfx3d.defaultCube
// or dojox.gfx3d.defaultCylinder)
this
.
object
=
null
;
// matrix: dojox.gfx3d.matrix: world transform
this
.
matrix
=
null
;
// cache: buffer for intermediate result, used late for draw()
this
.
cache
=
null
;
// renderer: a reference for the Viewport
this
.
renderer
=
null
;
// parent: a reference for parent, Scene or Viewport object
this
.
parent
=
null
;
// strokeStyle: Object: a stroke object
this
.
strokeStyle
=
null
;
// fillStyle: Object: a fill object or texture object
this
.
fillStyle
=
null
;
// shape: dojox.gfx.Shape: an underlying 2D shape
this
.
shape
=
null
;
},
setObject
:
function
(
newObject
){
// summary: sets a Object object
// object: Object: an abstract Object object
// (see dojox.gfx3d.defaultEdges,
// dojox.gfx3d.defaultTriangles,
// dojox.gfx3d.defaultQuads
// dojox.gfx3d.defaultOrbit
// dojox.gfx3d.defaultCube
// or dojox.gfx3d.defaultCylinder)
this
.
object
=
dojox
.
gfx
.
makeParameters
(
this
.
object
,
newObject
);
return
this
;
},
setTransform
:
function
(
matrix
){
// summary: sets a transformation matrix
// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
// (see an argument of dojox.gfx3d.matrix.Matrix
// constructor for a list of acceptable arguments)
this
.
matrix
=
dojox
.
gfx3d
.
matrix
.
clone
(
matrix
?
dojox
.
gfx3d
.
matrix
.
normalize
(
matrix
)
:
dojox
.
gfx3d
.
identity
,
true
);
return
this
;
// self
},
// apply left & right transformation
applyRightTransform
:
function
(
matrix
){
// summary: multiplies the existing matrix with an argument on right side
// (this.matrix * matrix)
// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
// (see an argument of dojox.gfx.matrix.Matrix
// constructor for a list of acceptable arguments)
return
matrix
?
this
.
setTransform
([
this
.
matrix
,
matrix
])
:
this
;
// self
},
applyLeftTransform
:
function
(
matrix
){
// summary: multiplies the existing matrix with an argument on left side
// (matrix * this.matrix)
// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
// (see an argument of dojox.gfx.matrix.Matrix
// constructor for a list of acceptable arguments)
return
matrix
?
this
.
setTransform
([
matrix
,
this
.
matrix
])
:
this
;
// self
},
applyTransform
:
function
(
matrix
){
// summary: a shortcut for dojox.gfx.Shape.applyRightTransform
// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
// (see an argument of dojox.gfx.matrix.Matrix
// constructor for a list of acceptable arguments)
return
matrix
?
this
.
setTransform
([
this
.
matrix
,
matrix
])
:
this
;
// self
},
setFill
:
function
(
fill
){
// summary: sets a fill object
// (the default implementation is to delegate to
// the underlying 2D shape).
// fill: Object: a fill object
// (see dojox.gfx.defaultLinearGradient,
// dojox.gfx.defaultRadialGradient,
// dojox.gfx.defaultPattern,
// dojo.Color
// or dojox.gfx.MODEL)
this
.
fillStyle
=
fill
;
return
this
;
},
setStroke
:
function
(
stroke
){
// summary: sets a stroke object
// (the default implementation simply ignores it)
// stroke: Object: a stroke object
// (see dojox.gfx.defaultStroke)
this
.
strokeStyle
=
stroke
;
return
this
;
},
toStdFill
:
function
(
lighting
,
normal
){
return
(
this
.
fillStyle
&&
typeof
this
.
fillStyle
[
'type'
]
!=
"undefined"
)
?
lighting
[
this
.
fillStyle
.
type
](
normal
,
this
.
fillStyle
.
finish
,
this
.
fillStyle
.
color
)
:
this
.
fillStyle
;
},
invalidate
:
function
(){
this
.
renderer
.
addTodo
(
this
);
},
destroy
:
function
(){
if
(
this
.
shape
){
var
p
=
this
.
shape
.
getParent
();
if
(
p
){
p
.
remove
(
this
.
shape
);
}
this
.
shape
=
null
;
}
},
// All the 3D objects need to override the following virtual functions:
// render, getZOrder, getOutline, draw, redraw if necessary.
render
:
function
(
camera
){
throw
"Pure virtual function, not implemented"
;
},
draw
:
function
(
lighting
){
throw
"Pure virtual function, not implemented"
;
},
getZOrder
:
function
(){
return
0
;
},
getOutline
:
function
(){
return
null
;
}
});
dojo
.
declare
(
"dojox.gfx3d.Scene"
,
dojox
.
gfx3d
.
Object
,
{
// summary: the Scene is just a containter.
// note: we have the following assumption:
// all objects in the Scene are not overlapped with other objects
// outside of the scene.
constructor
:
function
(){
// summary: a containter of other 3D objects
this
.
objects
=
[];
this
.
todos
=
[];
this
.
schedule
=
dojox
.
gfx3d
.
scheduler
.
zOrder
;
this
.
_draw
=
dojox
.
gfx3d
.
drawer
.
conservative
;
},
setFill
:
function
(
fill
){
this
.
fillStyle
=
fill
;
dojo
.
forEach
(
this
.
objects
,
function
(
item
){
item
.
setFill
(
fill
);
});
return
this
;
},
setStroke
:
function
(
stroke
){
this
.
strokeStyle
=
stroke
;
dojo
.
forEach
(
this
.
objects
,
function
(
item
){
item
.
setStroke
(
stroke
);
});
return
this
;
},
render
:
function
(
camera
,
deep
){
var
m
=
dojox
.
gfx3d
.
matrix
.
multiply
(
camera
,
this
.
matrix
);
if
(
deep
){
this
.
todos
=
this
.
objects
;
}
dojo
.
forEach
(
this
.
todos
,
function
(
item
){
item
.
render
(
m
,
deep
);
});
},
draw
:
function
(
lighting
){
this
.
objects
=
this
.
schedule
(
this
.
objects
);
this
.
_draw
(
this
.
todos
,
this
.
objects
,
this
.
renderer
);
},
addTodo
:
function
(
newObject
){
// FIXME: use indexOf?
if
(
dojo
.
every
(
this
.
todos
,
function
(
item
){
return
item
!=
newObject
;
})){
this
.
todos
.
push
(
newObject
);
this
.
invalidate
();
}
},
invalidate
:
function
(){
this
.
parent
.
addTodo
(
this
);
},
getZOrder
:
function
(){
var
zOrder
=
0
;
dojo
.
forEach
(
this
.
objects
,
function
(
item
){
zOrder
+=
item
.
getZOrder
();
});
return
(
this
.
objects
.
length
>
1
)
?
zOrder
/
this
.
objects
.
length
:
0
;
}
});
dojo
.
declare
(
"dojox.gfx3d.Edges"
,
dojox
.
gfx3d
.
Object
,
{
constructor
:
function
(){
// summary: a generic edge in 3D viewport
this
.
object
=
dojo
.
clone
(
dojox
.
gfx3d
.
defaultEdges
);
},
setObject
:
function
(
newObject
,
/* String, optional */
style
){
// summary: setup the object
// newObject: Array of points || Object
// style: String, optional
this
.
object
=
dojox
.
gfx
.
makeParameters
(
this
.
object
,
(
newObject
instanceof
Array
)
?
{
points
:
newObject
,
style
:
style
}
:
newObject
);
return
this
;
},
getZOrder
:
function
(){
var
zOrder
=
0
;
dojo
.
forEach
(
this
.
cache
,
function
(
item
){
zOrder
+=
item
.
z
;}
);
return
(
this
.
cache
.
length
>
1
)
?
zOrder
/
this
.
cache
.
length
:
0
;
},
render
:
function
(
camera
){
var
m
=
dojox
.
gfx3d
.
matrix
.
multiply
(
camera
,
this
.
matrix
);
this
.
cache
=
dojo
.
map
(
this
.
object
.
points
,
function
(
item
){
return
dojox
.
gfx3d
.
matrix
.
multiplyPoint
(
m
,
item
);
});
},
draw
:
function
(){
var
c
=
this
.
cache
;
if
(
this
.
shape
){
this
.
shape
.
setShape
(
""
)
}
else
{
this
.
shape
=
this
.
renderer
.
createPath
();
}
var
p
=
this
.
shape
.
setAbsoluteMode
(
"absolute"
);
if
(
this
.
object
.
style
==
"strip"
||
this
.
object
.
style
==
"loop"
){
p
.
moveTo
(
c
[
0
].
x
,
c
[
0
].
y
);
dojo
.
forEach
(
c
.
slice
(
1
),
function
(
item
){
p
.
lineTo
(
item
.
x
,
item
.
y
);
});
if
(
this
.
object
.
style
==
"loop"
){
p
.
closePath
();
}
}
else
{
for
(
var
i
=
0
;
i
<
this
.
cache
.
length
;
){
p
.
moveTo
(
c
[
i
].
x
,
c
[
i
].
y
);
i
++
;
p
.
lineTo
(
c
[
i
].
x
,
c
[
i
].
y
);
i
++
;
}
}
// FIXME: doe setFill make sense here?
p
.
setStroke
(
this
.
strokeStyle
);
}
});
dojo
.
declare
(
"dojox.gfx3d.Orbit"
,
dojox
.
gfx3d
.
Object
,
{
constructor
:
function
(){
// summary: a generic edge in 3D viewport
this
.
object
=
dojo
.
clone
(
dojox
.
gfx3d
.
defaultOrbit
);
},
render
:
function
(
camera
){
var
m
=
dojox
.
gfx3d
.
matrix
.
multiply
(
camera
,
this
.
matrix
);
var
angles
=
[
0
,
Math
.
PI
/
4
,
Math
.
PI
/
3
];
var
center
=
dojox
.
gfx3d
.
matrix
.
multiplyPoint
(
m
,
this
.
object
.
center
);
var
marks
=
dojo
.
map
(
angles
,
function
(
item
){
return
{
x
:
this
.
center
.
x
+
this
.
radius
*
Math
.
cos
(
item
),
y
:
this
.
center
.
y
+
this
.
radius
*
Math
.
sin
(
item
),
z
:
this
.
center
.
z
};
},
this
.
object
);
marks
=
dojo
.
map
(
marks
,
function
(
item
){
return
dojox
.
gfx3d
.
matrix
.
multiplyPoint
(
m
,
item
);
});
var
normal
=
dojox
.
gfx3d
.
vector
.
normalize
(
marks
);
marks
=
dojo
.
map
(
marks
,
function
(
item
){
return
dojox
.
gfx3d
.
vector
.
substract
(
item
,
center
);
});
// Use the algorithm here:
// http://www.3dsoftware.com/Math/PlaneCurves/EllipseAlgebra/
// After we normalize the marks, the equation is:
// a x^2 + 2b xy + cy^2 + f = 0: let a = 1
// so the final equation is:
// [ xy, y^2, 1] * [2b, c, f]' = [ -x^2 ]'
var
A
=
{
xx
:
marks
[
0
].
x
*
marks
[
0
].
y
,
xy
:
marks
[
0
].
y
*
marks
[
0
].
y
,
xz
:
1
,
yx
:
marks
[
1
].
x
*
marks
[
1
].
y
,
yy
:
marks
[
1
].
y
*
marks
[
1
].
y
,
yz
:
1
,
zx
:
marks
[
2
].
x
*
marks
[
2
].
y
,
zy
:
marks
[
2
].
y
*
marks
[
2
].
y
,
zz
:
1
,
dx
:
0
,
dy
:
0
,
dz
:
0
};
var
b
=
dojo
.
map
(
marks
,
function
(
item
){
return
-
Math
.
pow
(
item
.
x
,
2
);
});
// X is 2b, c, f
var
X
=
dojox
.
gfx3d
.
matrix
.
multiplyPoint
(
dojox
.
gfx3d
.
matrix
.
invert
(
A
),
b
[
0
],
b
[
1
],
b
[
2
]);
var
theta
=
Math
.
atan2
(
X
.
x
,
1
-
X
.
y
)
/
2
;
// rotate the marks back to the canonical form
var
probes
=
dojo
.
map
(
marks
,
function
(
item
){
return
dojox
.
gfx
.
matrix
.
multiplyPoint
(
dojox
.
gfx
.
matrix
.
rotate
(
-
theta
),
item
.
x
,
item
.
y
);
});
// we are solving the equation: Ax = b
// A = [x^2, y^2] X = [1/a^2, 1/b^2]', b = [1, 1]'
// so rx = Math.sqrt(1/ ( inv(A)[1:] * b ) );
// so ry = Math.sqrt(1/ ( inv(A)[2:] * b ) );
var
a
=
Math
.
pow
(
probes
[
0
].
x
,
2
);
var
b
=
Math
.
pow
(
probes
[
0
].
y
,
2
);
var
c
=
Math
.
pow
(
probes
[
1
].
x
,
2
);
var
d
=
Math
.
pow
(
probes
[
1
].
y
,
2
);
// the invert matrix is
// 1/(ad -bc) [ d, -b; -c, a];
var
rx
=
Math
.
sqrt
(
(
a
*
d
-
b
*
c
)
/
(
d
-
b
)
);
var
ry
=
Math
.
sqrt
(
(
a
*
d
-
b
*
c
)
/
(
a
-
c
)
);
this
.
cache
=
{
cx
:
center
.
x
,
cy
:
center
.
y
,
rx
:
rx
,
ry
:
ry
,
theta
:
theta
,
normal
:
normal
};
},
draw
:
function
(
lighting
){
if
(
this
.
shape
){
this
.
shape
.
setShape
(
this
.
cache
);
}
else
{
this
.
shape
=
this
.
renderer
.
createEllipse
(
this
.
cache
);
}
this
.
shape
.
applyTransform
(
dojox
.
gfx
.
matrix
.
rotateAt
(
this
.
cache
.
theta
,
this
.
cache
.
cx
,
this
.
cache
.
cy
))
.
setStroke
(
this
.
strokeStyle
)
.
setFill
(
this
.
toStdFill
(
lighting
,
this
.
cache
.
normal
));
}
});
dojo
.
declare
(
"dojox.gfx3d.Path3d"
,
dojox
.
gfx3d
.
Object
,
{
// This object is still very immature !
constructor
:
function
(){
// summary: a generic line
// (this is a helper object, which is defined for convenience)
this
.
object
=
dojo
.
clone
(
dojox
.
gfx3d
.
defaultPath3d
);
this
.
segments
=
[];
this
.
absolute
=
true
;
this
.
last
=
{};
this
.
path
=
""
;
},
_collectArgs
:
function
(
array
,
args
){
// summary: converts an array of arguments to plain numeric values
// array: Array: an output argument (array of numbers)
// args: Array: an input argument (can be values of Boolean, Number, dojox.gfx.Point, or an embedded array of them)
for
(
var
i
=
0
;
i
<
args
.
length
;
++
i
){
var
t
=
args
[
i
];
if
(
typeof
(
t
)
==
"boolean"
){
array
.
push
(
t
?
1
:
0
);
}
else
if
(
typeof
(
t
)
==
"number"
){
array
.
push
(
t
);
}
else
if
(
t
instanceof
Array
){
this
.
_collectArgs
(
array
,
t
);
}
else
if
(
"x"
in
t
&&
"y"
in
t
){
array
.
push
(
t
.
x
);
array
.
push
(
t
.
y
);
}
}
},
// a dictionary, which maps segment type codes to a number of their argemnts
_validSegments
:
{
m
:
3
,
l
:
3
,
z
:
0
},
_pushSegment
:
function
(
action
,
args
){
// summary: adds a segment
// action: String: valid SVG code for a segment's type
// args: Array: a list of parameters for this segment
var
group
=
this
.
_validSegments
[
action
.
toLowerCase
()];
if
(
typeof
(
group
)
==
"number"
){
if
(
group
){
if
(
args
.
length
>=
group
){
var
segment
=
{
action
:
action
,
args
:
args
.
slice
(
0
,
args
.
length
-
args
.
length
%
group
)};
this
.
segments
.
push
(
segment
);
}
}
else
{
var
segment
=
{
action
:
action
,
args
:
[]};
this
.
segments
.
push
(
segment
);
}
}
},
moveTo
:
function
(){
// summary: formes a move segment
var
args
=
[];
this
.
_collectArgs
(
args
,
arguments
);
this
.
_pushSegment
(
this
.
absolute
?
"M"
:
"m"
,
args
);
return
this
;
// self
},
lineTo
:
function
(){
// summary: formes a line segment
var
args
=
[];
this
.
_collectArgs
(
args
,
arguments
);
this
.
_pushSegment
(
this
.
absolute
?
"L"
:
"l"
,
args
);
return
this
;
// self
},
closePath
:
function
(){
// summary: closes a path
this
.
_pushSegment
(
"Z"
,
[]);
return
this
;
// self
},
render
:
function
(
camera
){
// TODO: we need to get the ancestors' matrix
var
m
=
dojox
.
gfx3d
.
matrix
.
multiply
(
camera
,
this
.
matrix
);
// iterate all the segments and convert them to 2D canvas
// TODO consider the relative mode
var
path
=
""
var
_validSegments
=
this
.
_validSegments
;
dojo
.
forEach
(
this
.
segments
,
function
(
item
){
path
+=
item
.
action
;
for
(
var
i
=
0
;
i
<
item
.
args
.
length
;
i
+=
_validSegments
[
item
.
action
.
toLowerCase
()]
){
var
pt
=
dojox
.
gfx3d
.
matrix
.
multiplyPoint
(
m
,
item
.
args
[
i
],
item
.
args
[
i
+
1
],
item
.
args
[
i
+
2
])
path
+=
" "
+
pt
.
x
+
" "
+
pt
.
y
;
}
});
this
.
cache
=
path
;
},
_draw
:
function
(){
return
this
.
parent
.
createPath
(
this
.
cache
);
}
});
dojo
.
declare
(
"dojox.gfx3d.Triangles"
,
dojox
.
gfx3d
.
Object
,
{
constructor
:
function
(){
// summary: a generic triangle
// (this is a helper object, which is defined for convenience)
this
.
object
=
dojo
.
clone
(
dojox
.
gfx3d
.
defaultTriangles
);
},
setObject
:
function
(
newObject
,
/* String, optional */
style
){
// summary: setup the object
// newObject: Array of points || Object
// style: String, optional
if
(
newObject
instanceof
Array
){
this
.
object
=
dojox
.
gfx
.
makeParameters
(
this
.
object
,
{
points
:
newObject
,
style
:
style
}
);
}
else
{
this
.
object
=
dojox
.
gfx
.
makeParameters
(
this
.
object
,
newObject
);
}
return
this
;
},
render
:
function
(
camera
){
var
m
=
dojox
.
gfx3d
.
matrix
.
multiply
(
camera
,
this
.
matrix
);
var
c
=
dojo
.
map
(
this
.
object
.
points
,
function
(
item
){
return
dojox
.
gfx3d
.
matrix
.
multiplyPoint
(
m
,
item
);
});
this
.
cache
=
[];
var
pool
=
c
.
slice
(
0
,
2
);
var
center
=
c
[
0
];
if
(
this
.
object
.
style
==
"strip"
){
dojo
.
forEach
(
c
.
slice
(
2
),
function
(
item
){
pool
.
push
(
item
);
pool
.
push
(
pool
[
0
]);
this
.
cache
.
push
(
pool
);
pool
=
pool
.
slice
(
1
,
3
);
},
this
);
}
else
if
(
this
.
object
.
style
==
"fan"
){
dojo
.
forEach
(
c
.
slice
(
2
),
function
(
item
){
pool
.
push
(
item
);
pool
.
push
(
center
);
this
.
cache
.
push
(
pool
);
pool
=
[
center
,
item
];
},
this
);
}
else
{
for
(
var
i
=
0
;
i
<
c
.
length
;
){
this
.
cache
.
push
(
[
c
[
i
],
c
[
i
+
1
],
c
[
i
+
2
],
c
[
i
]
]);
i
+=
3
;
}
}
},
draw
:
function
(
lighting
){
// use the BSP to schedule
this
.
cache
=
dojox
.
gfx3d
.
scheduler
.
bsp
(
this
.
cache
,
function
(
it
){
return
it
;
});
if
(
this
.
shape
){
this
.
shape
.
clear
();
}
else
{
this
.
shape
=
this
.
renderer
.
createGroup
();
}
dojo
.
forEach
(
this
.
cache
,
function
(
item
){
this
.
shape
.
createPolyline
(
item
)
.
setStroke
(
this
.
strokeStyle
)
.
setFill
(
this
.
toStdFill
(
lighting
,
dojox
.
gfx3d
.
vector
.
normalize
(
item
)));
},
this
);
},
getZOrder
:
function
(){
var
zOrder
=
0
;
dojo
.
forEach
(
this
.
cache
,
function
(
item
){
zOrder
+=
(
item
[
0
].
z
+
item
[
1
].
z
+
item
[
2
].
z
)
/
3
;
});
return
(
this
.
cache
.
length
>
1
)
?
zOrder
/
this
.
cache
.
length
:
0
;
}
});
dojo
.
declare
(
"dojox.gfx3d.Quads"
,
dojox
.
gfx3d
.
Object
,
{
constructor
:
function
(){
// summary: a generic triangle
// (this is a helper object, which is defined for convenience)
this
.
object
=
dojo
.
clone
(
dojox
.
gfx3d
.
defaultQuads
);
},
setObject
:
function
(
newObject
,
/* String, optional */
style
){
// summary: setup the object
// newObject: Array of points || Object
// style: String, optional
this
.
object
=
dojox
.
gfx
.
makeParameters
(
this
.
object
,
(
newObject
instanceof
Array
)
?
{
points
:
newObject
,
style
:
style
}
:
newObject
);
return
this
;
},
render
:
function
(
camera
){
var
m
=
dojox
.
gfx3d
.
matrix
.
multiply
(
camera
,
this
.
matrix
);
var
c
=
dojo
.
map
(
this
.
object
.
points
,
function
(
item
){
return
dojox
.
gfx3d
.
matrix
.
multiplyPoint
(
m
,
item
);
});
this
.
cache
=
[];
if
(
this
.
object
.
style
==
"strip"
){
var
pool
=
c
.
slice
(
0
,
2
);
for
(
var
i
=
2
;
i
<
c
.
length
;
){
pool
=
pool
.
concat
(
[
c
[
i
],
c
[
i
+
1
],
pool
[
0
]
]
);
this
.
cache
.
push
(
pool
);
pool
=
pool
.
slice
(
2
,
4
);
i
+=
2
;
}
}
else
{
for
(
var
i
=
0
;
i
<
c
.
length
;
){
this
.
cache
.
push
(
[
c
[
i
],
c
[
i
+
1
],
c
[
i
+
2
],
c
[
i
+
3
],
c
[
i
]
]
);
i
+=
4
;
}
}
},
draw
:
function
(
lighting
){
// use the BSP to schedule
this
.
cache
=
dojox
.
gfx3d
.
scheduler
.
bsp
(
this
.
cache
,
function
(
it
){
return
it
;
});
if
(
this
.
shape
){
this
.
shape
.
clear
();
}
else
{
this
.
shape
=
this
.
renderer
.
createGroup
();
}
// using naive iteration to speed things up a bit by avoiding function call overhead
for
(
var
x
=
0
;
x
<
this
.
cache
.
length
;
x
++
){
this
.
shape
.
createPolyline
(
this
.
cache
[
x
])
.
setStroke
(
this
.
strokeStyle
)
.
setFill
(
this
.
toStdFill
(
lighting
,
dojox
.
gfx3d
.
vector
.
normalize
(
this
.
cache
[
x
])));
}
/*
dojo.forEach(this.cache, function(item){
this.shape.createPolyline(item)
.setStroke(this.strokeStyle)
.setFill(this.toStdFill(lighting, dojox.gfx3d.vector.normalize(item)));
}, this);
*/
},
getZOrder
:
function
(){
var
zOrder
=
0
;
// using naive iteration to speed things up a bit by avoiding function call overhead
for
(
var
x
=
0
;
x
<
this
.
cache
.
length
;
x
++
){
var
i
=
this
.
cache
[
x
];
zOrder
+=
(
i
[
0
].
z
+
i
[
1
].
z
+
i
[
2
].
z
+
i
[
3
].
z
)
/
4
;
}
/*
dojo.forEach(this.cache, function(item){
zOrder += (item[0].z + item[1].z + item[2].z + item[3].z) / 4; });
*/
return
(
this
.
cache
.
length
>
1
)
?
zOrder
/
this
.
cache
.
length
:
0
;
}
});
dojo
.
declare
(
"dojox.gfx3d.Polygon"
,
dojox
.
gfx3d
.
Object
,
{
constructor
:
function
(){
// summary: a generic triangle
// (this is a helper object, which is defined for convenience)
this
.
object
=
dojo
.
clone
(
dojox
.
gfx3d
.
defaultPolygon
);
},
setObject
:
function
(
newObject
){
// summary: setup the object
// newObject: Array of points || Object
this
.
object
=
dojox
.
gfx
.
makeParameters
(
this
.
object
,
(
newObject
instanceof
Array
)
?
{
path
:
newObject
}
:
newObject
)
return
this
;
},
render
:
function
(
camera
){
var
m
=
dojox
.
gfx3d
.
matrix
.
multiply
(
camera
,
this
.
matrix
);
this
.
cache
=
dojo
.
map
(
this
.
object
.
path
,
function
(
item
){
return
dojox
.
gfx3d
.
matrix
.
multiplyPoint
(
m
,
item
);
});
// add the first point to close the polyline
this
.
cache
.
push
(
this
.
cache
[
0
]);
},
draw
:
function
(
lighting
){
if
(
this
.
shape
){
this
.
shape
.
setShape
({
points
:
this
.
cache
});
}
else
{
this
.
shape
=
this
.
renderer
.
createPolyline
({
points
:
this
.
cache
});
}
this
.
shape
.
setStroke
(
this
.
strokeStyle
)
.
setFill
(
this
.
toStdFill
(
lighting
,
dojox
.
gfx3d
.
matrix
.
normalize
(
this
.
cache
)));
},
getZOrder
:
function
(){
var
zOrder
=
0
;
// using naive iteration to speed things up a bit by avoiding function call overhead
for
(
var
x
=
0
;
x
<
this
.
cache
.
length
;
x
++
){
zOrder
+=
this
.
cache
[
x
].
z
;
}
return
(
this
.
cache
.
length
>
1
)
?
zOrder
/
this
.
cache
.
length
:
0
;
},
getOutline
:
function
(){
return
this
.
cache
.
slice
(
0
,
3
);
}
});
dojo
.
declare
(
"dojox.gfx3d.Cube"
,
dojox
.
gfx3d
.
Object
,
{
constructor
:
function
(){
// summary: a generic triangle
// (this is a helper object, which is defined for convenience)
this
.
object
=
dojo
.
clone
(
dojox
.
gfx3d
.
defaultCube
);
this
.
polygons
=
[];
},
setObject
:
function
(
newObject
){
// summary: setup the object
// newObject: Array of points || Object
this
.
object
=
dojox
.
gfx
.
makeParameters
(
this
.
object
,
newObject
);
},
render
:
function
(
camera
){
// parse the top, bottom to get 6 polygons:
var
a
=
this
.
object
.
top
;
var
g
=
this
.
object
.
bottom
;
var
b
=
{
x
:
g
.
x
,
y
:
a
.
y
,
z
:
a
.
z
};
var
c
=
{
x
:
g
.
x
,
y
:
g
.
y
,
z
:
a
.
z
};
var
d
=
{
x
:
a
.
x
,
y
:
g
.
y
,
z
:
a
.
z
};
var
e
=
{
x
:
a
.
x
,
y
:
a
.
y
,
z
:
g
.
z
};
var
f
=
{
x
:
g
.
x
,
y
:
a
.
y
,
z
:
g
.
z
};
var
h
=
{
x
:
a
.
x
,
y
:
g
.
y
,
z
:
g
.
z
};
var
polygons
=
[
a
,
b
,
c
,
d
,
e
,
f
,
g
,
h
];
var
m
=
dojox
.
gfx3d
.
matrix
.
multiply
(
camera
,
this
.
matrix
);
var
p
=
dojo
.
map
(
polygons
,
function
(
item
){
return
dojox
.
gfx3d
.
matrix
.
multiplyPoint
(
m
,
item
);
});
a
=
p
[
0
];
b
=
p
[
1
];
c
=
p
[
2
];
d
=
p
[
3
];
e
=
p
[
4
];
f
=
p
[
5
];
g
=
p
[
6
];
h
=
p
[
7
];
this
.
cache
=
[[
a
,
b
,
c
,
d
,
a
],
[
e
,
f
,
g
,
h
,
e
],
[
a
,
d
,
h
,
e
,
a
],
[
d
,
c
,
g
,
h
,
d
],
[
c
,
b
,
f
,
g
,
c
],
[
b
,
a
,
e
,
f
,
b
]];
},
draw
:
function
(
lighting
){
// use bsp to sort.
this
.
cache
=
dojox
.
gfx3d
.
scheduler
.
bsp
(
this
.
cache
,
function
(
it
){
return
it
;
});
// only the last 3 polys are visible.
var
cache
=
this
.
cache
.
slice
(
3
);
if
(
this
.
shape
){
this
.
shape
.
clear
();
}
else
{
this
.
shape
=
this
.
renderer
.
createGroup
();
}
for
(
var
x
=
0
;
x
<
cache
.
length
;
x
++
){
this
.
shape
.
createPolyline
(
cache
[
x
])
.
setStroke
(
this
.
strokeStyle
)
.
setFill
(
this
.
toStdFill
(
lighting
,
dojox
.
gfx3d
.
vector
.
normalize
(
cache
[
x
])));
}
/*
dojo.forEach(cache, function(item){
this.shape.createPolyline(item)
.setStroke(this.strokeStyle)
.setFill(this.toStdFill(lighting, dojox.gfx3d.vector.normalize(item)));
}, this);
*/
},
getZOrder
:
function
(){
var
top
=
this
.
cache
[
0
][
0
];
var
bottom
=
this
.
cache
[
1
][
2
];
return
(
top
.
z
+
bottom
.
z
)
/
2
;
}
});
dojo
.
declare
(
"dojox.gfx3d.Cylinder"
,
dojox
.
gfx3d
.
Object
,
{
constructor
:
function
(){
this
.
object
=
dojo
.
clone
(
dojox
.
gfx3d
.
defaultCylinder
);
},
render
:
function
(
camera
){
// get the bottom surface first
var
m
=
dojox
.
gfx3d
.
matrix
.
multiply
(
camera
,
this
.
matrix
);
var
angles
=
[
0
,
Math
.
PI
/
4
,
Math
.
PI
/
3
];
var
center
=
dojox
.
gfx3d
.
matrix
.
multiplyPoint
(
m
,
this
.
object
.
center
);
var
marks
=
dojo
.
map
(
angles
,
function
(
item
){
return
{
x
:
this
.
center
.
x
+
this
.
radius
*
Math
.
cos
(
item
),
y
:
this
.
center
.
y
+
this
.
radius
*
Math
.
sin
(
item
),
z
:
this
.
center
.
z
};
},
this
.
object
);
marks
=
dojo
.
map
(
marks
,
function
(
item
){
return
dojox
.
gfx3d
.
vector
.
substract
(
dojox
.
gfx3d
.
matrix
.
multiplyPoint
(
m
,
item
),
center
);
});
// Use the algorithm here:
// http://www.3dsoftware.com/Math/PlaneCurves/EllipseAlgebra/
// After we normalize the marks, the equation is:
// a x^2 + 2b xy + cy^2 + f = 0: let a = 1
// so the final equation is:
// [ xy, y^2, 1] * [2b, c, f]' = [ -x^2 ]'
var
A
=
{
xx
:
marks
[
0
].
x
*
marks
[
0
].
y
,
xy
:
marks
[
0
].
y
*
marks
[
0
].
y
,
xz
:
1
,
yx
:
marks
[
1
].
x
*
marks
[
1
].
y
,
yy
:
marks
[
1
].
y
*
marks
[
1
].
y
,
yz
:
1
,
zx
:
marks
[
2
].
x
*
marks
[
2
].
y
,
zy
:
marks
[
2
].
y
*
marks
[
2
].
y
,
zz
:
1
,
dx
:
0
,
dy
:
0
,
dz
:
0
};
var
b
=
dojo
.
map
(
marks
,
function
(
item
){
return
-
Math
.
pow
(
item
.
x
,
2
);
});
// X is 2b, c, f
var
X
=
dojox
.
gfx3d
.
matrix
.
multiplyPoint
(
dojox
.
gfx3d
.
matrix
.
invert
(
A
),
b
[
0
],
b
[
1
],
b
[
2
]);
var
theta
=
Math
.
atan2
(
X
.
x
,
1
-
X
.
y
)
/
2
;
// rotate the marks back to the canonical form
var
probes
=
dojo
.
map
(
marks
,
function
(
item
){
return
dojox
.
gfx
.
matrix
.
multiplyPoint
(
dojox
.
gfx
.
matrix
.
rotate
(
-
theta
),
item
.
x
,
item
.
y
);
});
// we are solving the equation: Ax = b
// A = [x^2, y^2] X = [1/a^2, 1/b^2]', b = [1, 1]'
// so rx = Math.sqrt(1/ ( inv(A)[1:] * b ) );
// so ry = Math.sqrt(1/ ( inv(A)[2:] * b ) );
var
a
=
Math
.
pow
(
probes
[
0
].
x
,
2
);
var
b
=
Math
.
pow
(
probes
[
0
].
y
,
2
);
var
c
=
Math
.
pow
(
probes
[
1
].
x
,
2
);
var
d
=
Math
.
pow
(
probes
[
1
].
y
,
2
);
// the invert matrix is
// 1/(ad - bc) [ d, -b; -c, a];
var
rx
=
Math
.
sqrt
((
a
*
d
-
b
*
c
)
/
(
d
-
b
));
var
ry
=
Math
.
sqrt
((
a
*
d
-
b
*
c
)
/
(
a
-
c
));
if
(
rx
<
ry
){
var
t
=
rx
;
rx
=
ry
;
ry
=
t
;
theta
-=
Math
.
PI
/
2
;
}
var
top
=
dojox
.
gfx3d
.
matrix
.
multiplyPoint
(
m
,
dojox
.
gfx3d
.
vector
.
sum
(
this
.
object
.
center
,
{
x
:
0
,
y
:
0
,
z
:
this
.
object
.
height
}));
var
gradient
=
this
.
fillStyle
.
type
==
"constant"
?
this
.
fillStyle
.
color
:
dojox
.
gfx3d
.
gradient
(
this
.
renderer
.
lighting
,
this
.
fillStyle
,
this
.
object
.
center
,
this
.
object
.
radius
,
Math
.
PI
,
2
*
Math
.
PI
,
m
);
if
(
isNaN
(
rx
)
||
isNaN
(
ry
)
||
isNaN
(
theta
)){
// in case the cap is invisible (parallel to the incident vector)
rx
=
this
.
object
.
radius
,
ry
=
0
,
theta
=
0
;
}
this
.
cache
=
{
center
:
center
,
top
:
top
,
rx
:
rx
,
ry
:
ry
,
theta
:
theta
,
gradient
:
gradient
};
},
draw
:
function
(){
var
c
=
this
.
cache
,
v
=
dojox
.
gfx3d
.
vector
,
m
=
dojox
.
gfx
.
matrix
,
centers
=
[
c
.
center
,
c
.
top
],
normal
=
v
.
substract
(
c
.
top
,
c
.
center
);
if
(
v
.
dotProduct
(
normal
,
this
.
renderer
.
lighting
.
incident
)
>
0
){
centers
=
[
c
.
top
,
c
.
center
];
normal
=
v
.
substract
(
c
.
center
,
c
.
top
);
}
var
color
=
this
.
renderer
.
lighting
[
this
.
fillStyle
.
type
](
normal
,
this
.
fillStyle
.
finish
,
this
.
fillStyle
.
color
),
d
=
Math
.
sqrt
(
Math
.
pow
(
c
.
center
.
x
-
c
.
top
.
x
,
2
)
+
Math
.
pow
(
c
.
center
.
y
-
c
.
top
.
y
,
2
)
);
if
(
this
.
shape
){
this
.
shape
.
clear
();
}
else
{
this
.
shape
=
this
.
renderer
.
createGroup
();
}
this
.
shape
.
createPath
(
""
)
.
moveTo
(
0
,
-
c
.
rx
)
.
lineTo
(
d
,
-
c
.
rx
)
.
lineTo
(
d
,
c
.
rx
)
.
lineTo
(
0
,
c
.
rx
)
.
arcTo
(
c
.
ry
,
c
.
rx
,
0
,
true
,
true
,
0
,
-
c
.
rx
)
.
setFill
(
c
.
gradient
).
setStroke
(
this
.
strokeStyle
)
.
setTransform
([
m
.
translate
(
centers
[
0
]),
m
.
rotate
(
Math
.
atan2
(
centers
[
1
].
y
-
centers
[
0
].
y
,
centers
[
1
].
x
-
centers
[
0
].
x
))]);
if
(
c
.
rx
>
0
&&
c
.
ry
>
0
){
this
.
shape
.
createEllipse
({
cx
:
centers
[
1
].
x
,
cy
:
centers
[
1
].
y
,
rx
:
c
.
rx
,
ry
:
c
.
ry
})
.
setFill
(
color
).
setStroke
(
this
.
strokeStyle
)
.
applyTransform
(
m
.
rotateAt
(
c
.
theta
,
centers
[
1
]));
}
}
});
// the ultimate container of 3D world
dojo
.
declare
(
"dojox.gfx3d.Viewport"
,
dojox
.
gfx
.
Group
,
{
constructor
:
function
(){
// summary: a viewport/container for 3D objects, which knows
// the camera and lightings
// matrix: dojox.gfx3d.matrix: world transform
// dimension: Object: the dimension of the canvas
this
.
dimension
=
null
;
// objects: Array: all 3d Objects
this
.
objects
=
[];
// todos: Array: all 3d Objects that needs to redraw
this
.
todos
=
[];
// FIXME: memory leak?
this
.
renderer
=
this
;
// Using zOrder as the default scheduler
this
.
schedule
=
dojox
.
gfx3d
.
scheduler
.
zOrder
;
this
.
draw
=
dojox
.
gfx3d
.
drawer
.
conservative
;
// deep: boolean, true means the whole viewport needs to re-render, redraw
this
.
deep
=
false
;
// lights: Array: an array of light objects
this
.
lights
=
[];
this
.
lighting
=
null
;
},
setCameraTransform
:
function
(
matrix
){
// summary: sets a transformation matrix
// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
// (see an argument of dojox.gfx.matrix.Matrix
// constructor for a list of acceptable arguments)
this
.
camera
=
dojox
.
gfx3d
.
matrix
.
clone
(
matrix
?
dojox
.
gfx3d
.
matrix
.
normalize
(
matrix
)
:
dojox
.
gfx3d
.
identity
,
true
);
this
.
invalidate
();
return
this
;
// self
},
applyCameraRightTransform
:
function
(
matrix
){
// summary: multiplies the existing matrix with an argument on right side
// (this.matrix * matrix)
// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
// (see an argument of dojox.gfx3d.matrix.Matrix
// constructor for a list of acceptable arguments)
return
matrix
?
this
.
setCameraTransform
([
this
.
camera
,
matrix
])
:
this
;
// self
},
applyCameraLeftTransform
:
function
(
matrix
){
// summary: multiplies the existing matrix with an argument on left side
// (matrix * this.matrix)
// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
// (see an argument of dojox.gfx3d.matrix.Matrix
// constructor for a list of acceptable arguments)
return
matrix
?
this
.
setCameraTransform
([
matrix
,
this
.
camera
])
:
this
;
// self
},
applyCameraTransform
:
function
(
matrix
){
// summary: a shortcut for dojox.gfx3d.Object.applyRightTransform
// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
// (see an argument of dojox.gfx3d.matrix.Matrix
// constructor for a list of acceptable arguments)
return
this
.
applyCameraRightTransform
(
matrix
);
// self
},
setLights
:
function
(
/* Array || Object */
lights
,
/* Color, optional */
ambient
,
/* Color, optional */
specular
){
// summary: set the lights
// lights: Array: an array of light object
// or lights object
// ambient: Color: an ambient object
// specular: Color: an specular object
this
.
lights
=
(
lights
instanceof
Array
)
?
{
sources
:
lights
,
ambient
:
ambient
,
specular
:
specular
}
:
lights
;
var
view
=
{
x
:
0
,
y
:
0
,
z
:
1
};
this
.
lighting
=
new
dojox
.
gfx3d
.
lighting
.
Model
(
view
,
this
.
lights
.
sources
,
this
.
lights
.
ambient
,
this
.
lights
.
specular
);
this
.
invalidate
();
return
this
;
},
addLights
:
function
(
lights
){
// summary: add new light/lights to the viewport.
// lights: Array || light object: light object(s)
return
this
.
setLights
(
this
.
lights
.
sources
.
concat
(
lights
));
},
addTodo
:
function
(
newObject
){
// NOTE: Viewport implements almost the same addTodo,
// except calling invalidate, since invalidate is used as
// any modification needs to redraw the object itself, call invalidate.
// then call render.
if
(
dojo
.
every
(
this
.
todos
,
function
(
item
){
return
item
!=
newObject
;
})){
this
.
todos
.
push
(
newObject
);
}
},
invalidate
:
function
(){
this
.
deep
=
true
;
this
.
todos
=
this
.
objects
;
},
setDimensions
:
function
(
dim
){
if
(
dim
){
this
.
dimension
=
{
width
:
typeof
dim
.
width
==
"string"
?
parseInt
(
dim
.
width
)
:
dim
.
width
,
height
:
typeof
dim
.
height
==
"string"
?
parseInt
(
dim
.
height
)
:
dim
.
height
};
}
else
{
this
.
dimension
=
null
;
}
},
render
:
function
(){
// summary: iterate all children and call their render callback function.
if
(
this
.
todos
.
length
==
0
){
return
;
}
var
m
=
dojox
.
gfx3d
.
matrix
;
// Iterate the todos and call render to prepare the rendering:
for
(
var
x
=
0
;
x
<
this
.
todos
.
length
;
x
++
){
this
.
todos
[
x
].
render
(
dojox
.
gfx3d
.
matrix
.
normalize
([
m
.
cameraRotateXg
(
180
),
m
.
cameraTranslate
(
0
,
this
.
dimension
.
height
,
0
),
this
.
camera
,
]),
this
.
deep
);
}
this
.
objects
=
this
.
schedule
(
this
.
objects
);
this
.
draw
(
this
.
todos
,
this
.
objects
,
this
);
this
.
todos
=
[];
this
.
deep
=
false
;
}
});
//FIXME: Viewport cannot masquerade as a Group
dojox
.
gfx3d
.
Viewport
.
nodeType
=
dojox
.
gfx
.
Group
.
nodeType
;
dojox
.
gfx3d
.
_creators
=
{
// summary: object creators
createEdges
:
function
(
edges
,
style
){
// summary: creates an edge object
// line: Object: a edge object (see dojox.gfx3d.defaultPath)
return
this
.
create3DObject
(
dojox
.
gfx3d
.
Edges
,
edges
,
style
);
// dojox.gfx3d.Edge
},
createTriangles
:
function
(
tris
,
style
){
// summary: creates an edge object
// line: Object: a edge object (see dojox.gfx3d.defaultPath)
return
this
.
create3DObject
(
dojox
.
gfx3d
.
Triangles
,
tris
,
style
);
// dojox.gfx3d.Edge
},
createQuads
:
function
(
quads
,
style
){
// summary: creates an edge object
// line: Object: a edge object (see dojox.gfx3d.defaultPath)
return
this
.
create3DObject
(
dojox
.
gfx3d
.
Quads
,
quads
,
style
);
// dojox.gfx3d.Edge
},
createPolygon
:
function
(
points
){
// summary: creates an triangle object
// points: Array of points || Object
return
this
.
create3DObject
(
dojox
.
gfx3d
.
Polygon
,
points
);
// dojox.gfx3d.Polygon
},
createOrbit
:
function
(
orbit
){
// summary: creates an triangle object
// points: Array of points || Object
return
this
.
create3DObject
(
dojox
.
gfx3d
.
Orbit
,
orbit
);
// dojox.gfx3d.Cube
},
createCube
:
function
(
cube
){
// summary: creates an triangle object
// points: Array of points || Object
return
this
.
create3DObject
(
dojox
.
gfx3d
.
Cube
,
cube
);
// dojox.gfx3d.Cube
},
createCylinder
:
function
(
cylinder
){
// summary: creates an triangle object
// points: Array of points || Object
return
this
.
create3DObject
(
dojox
.
gfx3d
.
Cylinder
,
cylinder
);
// dojox.gfx3d.Cube
},
createPath3d
:
function
(
path
){
// summary: creates an edge object
// line: Object: a edge object (see dojox.gfx3d.defaultPath)
return
this
.
create3DObject
(
dojox
.
gfx3d
.
Path3d
,
path
);
// dojox.gfx3d.Edge
},
createScene
:
function
(){
// summary: creates an triangle object
// line: Object: a triangle object (see dojox.gfx3d.defaultPath)
return
this
.
create3DObject
(
dojox
.
gfx3d
.
Scene
);
// dojox.gfx3d.Scene
},
create3DObject
:
function
(
objectType
,
rawObject
,
style
){
// summary: creates an instance of the passed shapeType class
// shapeType: Function: a class constructor to create an instance of
// rawShape: Object: properties to be passed in to the classes "setShape" method
var
obj
=
new
objectType
();
this
.
adopt
(
obj
);
if
(
rawObject
){
obj
.
setObject
(
rawObject
,
style
);
}
return
obj
;
// dojox.gfx3d.Object
},
// todo : override the add/remove if necessary
adopt
:
function
(
obj
){
// summary: adds a shape to the list
// shape: dojox.gfx.Shape: a shape
obj
.
renderer
=
this
.
renderer
;
// obj._setParent(this, null); more TODOs HERER?
obj
.
parent
=
this
;
this
.
objects
.
push
(
obj
);
this
.
addTodo
(
obj
);
return
this
;
},
abandon
:
function
(
obj
,
silently
){
// summary: removes a shape from the list
// silently: Boolean?: if true, do not redraw a picture yet
for
(
var
i
=
0
;
i
<
this
.
objects
.
length
;
++
i
){
if
(
this
.
objects
[
i
]
==
obj
){
this
.
objects
.
splice
(
i
,
1
);
}
}
// if(this.rawNode == shape.rawNode.parentNode){
// this.rawNode.removeChild(shape.rawNode);
// }
// obj._setParent(null, null);
obj
.
parent
=
null
;
return
this
;
// self
},
setScheduler
:
function
(
scheduler
){
this
.
schedule
=
scheduler
;
},
setDrawer
:
function
(
drawer
){
this
.
draw
=
drawer
;
}
};
dojo
.
extend
(
dojox
.
gfx3d
.
Viewport
,
dojox
.
gfx3d
.
_creators
);
dojo
.
extend
(
dojox
.
gfx3d
.
Scene
,
dojox
.
gfx3d
.
_creators
);
delete
dojox
.
gfx3d
.
_creators
;
//FIXME: extending dojox.gfx.Surface and masquerading Viewport as Group is hacky!
// Add createViewport to dojox.gfx.Surface
dojo
.
extend
(
dojox
.
gfx
.
Surface
,
{
createViewport
:
function
(){
//FIXME: createObject is non-public method!
var
viewport
=
this
.
createObject
(
dojox
.
gfx3d
.
Viewport
,
null
,
true
);
//FIXME: this may not work with dojox.gfx.Group !!
viewport
.
setDimensions
(
this
.
getDimensions
());
return
viewport
;
}
});
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Feb 22, 20:24 (1 d, 8 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24590
Default Alt Text
object.js (33 KB)
Attached To
rZEDHG ZedLegacy
Event Timeline
Log In to Comment