1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* 3DMacroscopic implementation */ 18 19 #include "sles_allinclusive.h" 20 21 22 static SLresult I3DMacroscopic_SetSize(SL3DMacroscopicItf self, 23 SLmillimeter width, SLmillimeter height, SLmillimeter depth) 24 { 25 SL_ENTER_INTERFACE 26 27 if (!((0 <= width) && (width <= SL_MILLIMETER_MAX) && 28 (0 <= height) && (height <= SL_MILLIMETER_MAX) && 29 (0 <= depth) && (depth <= SL_MILLIMETER_MAX))) { 30 result = SL_RESULT_PARAMETER_INVALID; 31 } else { 32 I3DMacroscopic *thiz = (I3DMacroscopic *) self; 33 interface_lock_exclusive(thiz); 34 thiz->mSize.mWidth = width; 35 thiz->mSize.mHeight = height; 36 thiz->mSize.mDepth = depth; 37 interface_unlock_exclusive(thiz); 38 result = SL_RESULT_SUCCESS; 39 } 40 41 SL_LEAVE_INTERFACE 42 } 43 44 45 static SLresult I3DMacroscopic_GetSize(SL3DMacroscopicItf self, 46 SLmillimeter *pWidth, SLmillimeter *pHeight, SLmillimeter *pDepth) 47 { 48 SL_ENTER_INTERFACE 49 50 if (NULL == pWidth || NULL == pHeight || NULL == pDepth) { 51 result = SL_RESULT_PARAMETER_INVALID; 52 } else { 53 I3DMacroscopic *thiz = (I3DMacroscopic *) self; 54 interface_lock_shared(thiz); 55 SLmillimeter width = thiz->mSize.mWidth; 56 SLmillimeter height = thiz->mSize.mHeight; 57 SLmillimeter depth = thiz->mSize.mDepth; 58 interface_unlock_shared(thiz); 59 *pWidth = width; 60 *pHeight = height; 61 *pDepth = depth; 62 result = SL_RESULT_SUCCESS; 63 } 64 65 SL_LEAVE_INTERFACE 66 } 67 68 69 static SLresult I3DMacroscopic_SetOrientationAngles(SL3DMacroscopicItf self, 70 SLmillidegree heading, SLmillidegree pitch, SLmillidegree roll) 71 { 72 SL_ENTER_INTERFACE 73 74 if (!((-360000 <= heading) && (heading <= 360000) && 75 (-90000 <= pitch) && (pitch <= 90000) && 76 (-360000 <= roll) && (roll <= 360000))) { 77 result = SL_RESULT_PARAMETER_INVALID; 78 } else { 79 I3DMacroscopic *thiz = (I3DMacroscopic *) self; 80 interface_lock_exclusive(thiz); 81 thiz->mOrientationAngles.mHeading = heading; 82 thiz->mOrientationAngles.mPitch = pitch; 83 thiz->mOrientationAngles.mRoll = roll; 84 thiz->mOrientationActive = ANGLES_SET_VECTORS_UNKNOWN; 85 thiz->mRotatePending = SL_BOOLEAN_FALSE; 86 // ++thiz->mGeneration; 87 interface_unlock_exclusive(thiz); 88 result = SL_RESULT_SUCCESS; 89 } 90 91 SL_LEAVE_INTERFACE 92 } 93 94 95 static SLresult I3DMacroscopic_SetOrientationVectors(SL3DMacroscopicItf self, 96 const SLVec3D *pFront, const SLVec3D *pAbove) 97 { 98 SL_ENTER_INTERFACE 99 100 if (NULL == pFront || NULL == pAbove) { 101 result = SL_RESULT_PARAMETER_INVALID; 102 } else { 103 I3DMacroscopic *thiz = (I3DMacroscopic *) self; 104 SLVec3D front = *pFront; 105 SLVec3D above = *pAbove; 106 // NTH Check for vectors close to zero or close to parallel 107 interface_lock_exclusive(thiz); 108 thiz->mOrientationVectors.mFront = front; 109 thiz->mOrientationVectors.mAbove = above; 110 thiz->mOrientationVectors.mUp = above; // wrong 111 thiz->mOrientationActive = ANGLES_UNKNOWN_VECTORS_SET; 112 thiz->mRotatePending = SL_BOOLEAN_FALSE; 113 interface_unlock_exclusive(thiz); 114 result = SL_RESULT_SUCCESS; 115 } 116 117 SL_LEAVE_INTERFACE 118 } 119 120 121 static SLresult I3DMacroscopic_Rotate(SL3DMacroscopicItf self, 122 SLmillidegree theta, const SLVec3D *pAxis) 123 { 124 SL_ENTER_INTERFACE 125 126 if (!((-360000 <= theta) && (theta <= 360000)) || NULL == pAxis) { 127 result = SL_RESULT_PARAMETER_INVALID; 128 } else { 129 SLVec3D axis = *pAxis; 130 // NTH Check that axis is not (close to) zero vector, length does not matter 131 I3DMacroscopic *thiz = (I3DMacroscopic *) self; 132 interface_lock_exclusive(thiz); 133 while (thiz->mRotatePending) 134 interface_cond_wait(thiz); 135 thiz->mTheta = theta; 136 thiz->mAxis = axis; 137 thiz->mRotatePending = SL_BOOLEAN_TRUE; 138 interface_unlock_exclusive(thiz); 139 result = SL_RESULT_SUCCESS; 140 } 141 142 SL_LEAVE_INTERFACE 143 } 144 145 146 static SLresult I3DMacroscopic_GetOrientationVectors(SL3DMacroscopicItf self, 147 SLVec3D *pFront, SLVec3D *pUp) 148 { 149 SL_ENTER_INTERFACE 150 151 if (NULL == pFront || NULL == pUp) { 152 result = SL_RESULT_PARAMETER_INVALID; 153 } else { 154 I3DMacroscopic *thiz = (I3DMacroscopic *) self; 155 interface_lock_exclusive(thiz); 156 for (;;) { 157 enum AnglesVectorsActive orientationActive = thiz->mOrientationActive; 158 switch (orientationActive) { 159 case ANGLES_COMPUTED_VECTORS_SET: // not in 1.0.1 160 case ANGLES_REQUESTED_VECTORS_SET: // not in 1.0.1 161 case ANGLES_UNKNOWN_VECTORS_SET: 162 case ANGLES_SET_VECTORS_COMPUTED: 163 { 164 SLVec3D front = thiz->mOrientationVectors.mFront; 165 SLVec3D up = thiz->mOrientationVectors.mUp; 166 interface_unlock_exclusive(thiz); 167 *pFront = front; 168 *pUp = up; 169 } 170 break; 171 case ANGLES_SET_VECTORS_UNKNOWN: 172 thiz->mOrientationActive = ANGLES_SET_VECTORS_REQUESTED; 173 // fall through 174 case ANGLES_SET_VECTORS_REQUESTED: 175 // matched by cond_broadcast in case multiple requesters 176 #if 0 177 interface_cond_wait(thiz); 178 #else 179 thiz->mOrientationActive = ANGLES_SET_VECTORS_COMPUTED; 180 #endif 181 continue; 182 default: 183 interface_unlock_exclusive(thiz); 184 assert(SL_BOOLEAN_FALSE); 185 pFront->x = 0; 186 pFront->y = 0; 187 pFront->z = 0; 188 pUp->x = 0; 189 pUp->y = 0; 190 pUp->z = 0; 191 break; 192 } 193 break; 194 } 195 result = SL_RESULT_SUCCESS; 196 } 197 198 SL_LEAVE_INTERFACE 199 } 200 201 202 static const struct SL3DMacroscopicItf_ I3DMacroscopic_Itf = { 203 I3DMacroscopic_SetSize, 204 I3DMacroscopic_GetSize, 205 I3DMacroscopic_SetOrientationAngles, 206 I3DMacroscopic_SetOrientationVectors, 207 I3DMacroscopic_Rotate, 208 I3DMacroscopic_GetOrientationVectors 209 }; 210 211 void I3DMacroscopic_init(void *self) 212 { 213 I3DMacroscopic *thiz = (I3DMacroscopic *) self; 214 thiz->mItf = &I3DMacroscopic_Itf; 215 thiz->mSize.mWidth = 0; 216 thiz->mSize.mHeight = 0; 217 thiz->mSize.mDepth = 0; 218 thiz->mOrientationAngles.mHeading = 0; 219 thiz->mOrientationAngles.mPitch = 0; 220 thiz->mOrientationAngles.mRoll = 0; 221 memset(&thiz->mOrientationVectors, 0x55, sizeof(thiz->mOrientationVectors)); 222 thiz->mOrientationVectors.mFront.x = 0; 223 thiz->mOrientationVectors.mFront.y = 0; 224 thiz->mOrientationVectors.mFront.z = -1000; 225 thiz->mOrientationVectors.mUp.x = 0; 226 thiz->mOrientationVectors.mUp.y = 1000; 227 thiz->mOrientationVectors.mUp.z = 0; 228 thiz->mOrientationVectors.mAbove.x = 0; 229 thiz->mOrientationVectors.mAbove.y = 0; 230 thiz->mOrientationVectors.mAbove.z = 0; 231 thiz->mOrientationActive = ANGLES_SET_VECTORS_COMPUTED; 232 thiz->mTheta = 0x55555555; 233 thiz->mAxis.x = 0x55555555; 234 thiz->mAxis.y = 0x55555555; 235 thiz->mAxis.z = 0x55555555; 236 thiz->mRotatePending = SL_BOOLEAN_FALSE; 237 } 238